ActivityManagerService.java revision f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8
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            if (!app.isolated) {
1984                try {
1985                    gids = mContext.getPackageManager().getPackageGids(
1986                            app.info.packageName);
1987                } catch (PackageManager.NameNotFoundException e) {
1988                    Slog.w(TAG, "Unable to retrieve gids", e);
1989                }
1990            }
1991            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1992                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1993                        && mTopComponent != null
1994                        && app.processName.equals(mTopComponent.getPackageName())) {
1995                    uid = 0;
1996                }
1997                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1998                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1999                    uid = 0;
2000                }
2001            }
2002            int debugFlags = 0;
2003            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2004                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2005                // Also turn on CheckJNI for debuggable apps. It's quite
2006                // awkward to turn on otherwise.
2007                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2008            }
2009            // Run the app in safe mode if its manifest requests so or the
2010            // system is booted in safe mode.
2011            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2012                Zygote.systemInSafeMode == true) {
2013                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2014            }
2015            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2016                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2017            }
2018            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2019                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2020            }
2021            if ("1".equals(SystemProperties.get("debug.assert"))) {
2022                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2023            }
2024
2025            // Start the process.  It will either succeed and return a result containing
2026            // the PID of the new process, or else throw a RuntimeException.
2027            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2028                    app.processName, uid, uid, gids, debugFlags,
2029                    app.info.targetSdkVersion, null, null);
2030
2031            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2032            synchronized (bs) {
2033                if (bs.isOnBattery()) {
2034                    app.batteryStats.incStartsLocked();
2035                }
2036            }
2037
2038            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2039                    app.processName, hostingType,
2040                    hostingNameStr != null ? hostingNameStr : "");
2041
2042            if (app.persistent) {
2043                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2044            }
2045
2046            StringBuilder buf = mStringBuilder;
2047            buf.setLength(0);
2048            buf.append("Start proc ");
2049            buf.append(app.processName);
2050            buf.append(" for ");
2051            buf.append(hostingType);
2052            if (hostingNameStr != null) {
2053                buf.append(" ");
2054                buf.append(hostingNameStr);
2055            }
2056            buf.append(": pid=");
2057            buf.append(startResult.pid);
2058            buf.append(" uid=");
2059            buf.append(uid);
2060            buf.append(" gids={");
2061            if (gids != null) {
2062                for (int gi=0; gi<gids.length; gi++) {
2063                    if (gi != 0) buf.append(", ");
2064                    buf.append(gids[gi]);
2065
2066                }
2067            }
2068            buf.append("}");
2069            Slog.i(TAG, buf.toString());
2070            app.setPid(startResult.pid);
2071            app.usingWrapper = startResult.usingWrapper;
2072            app.removed = false;
2073            synchronized (mPidsSelfLocked) {
2074                this.mPidsSelfLocked.put(startResult.pid, app);
2075                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2076                msg.obj = app;
2077                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2078                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2079            }
2080        } catch (RuntimeException e) {
2081            // XXX do better error recovery.
2082            app.setPid(0);
2083            Slog.e(TAG, "Failure starting process " + app.processName, e);
2084        }
2085    }
2086
2087    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2088        if (resumed) {
2089            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2090        } else {
2091            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2092        }
2093    }
2094
2095    boolean startHomeActivityLocked(int userId) {
2096        if (mHeadless) {
2097            // Added because none of the other calls to ensureBootCompleted seem to fire
2098            // when running headless.
2099            ensureBootCompleted();
2100            return false;
2101        }
2102
2103        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2104                && mTopAction == null) {
2105            // We are running in factory test mode, but unable to find
2106            // the factory test app, so just sit around displaying the
2107            // error message and don't try to start anything.
2108            return false;
2109        }
2110        Intent intent = new Intent(
2111            mTopAction,
2112            mTopData != null ? Uri.parse(mTopData) : null);
2113        intent.setComponent(mTopComponent);
2114        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2115            intent.addCategory(Intent.CATEGORY_HOME);
2116        }
2117        ActivityInfo aInfo =
2118            intent.resolveActivityInfo(mContext.getPackageManager(),
2119                    STOCK_PM_FLAGS);
2120        if (aInfo != null) {
2121            intent.setComponent(new ComponentName(
2122                    aInfo.applicationInfo.packageName, aInfo.name));
2123            // Don't do this if the home app is currently being
2124            // instrumented.
2125            aInfo = new ActivityInfo(aInfo);
2126            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2127            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2128                    aInfo.applicationInfo.uid);
2129            if (app == null || app.instrumentationClass == null) {
2130                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2131                mMainStack.startActivityLocked(null, intent, null, aInfo,
2132                        null, null, 0, 0, 0, 0, null, false, null);
2133            }
2134        }
2135
2136        return true;
2137    }
2138
2139    /**
2140     * Starts the "new version setup screen" if appropriate.
2141     */
2142    void startSetupActivityLocked() {
2143        // Only do this once per boot.
2144        if (mCheckedForSetup) {
2145            return;
2146        }
2147
2148        // We will show this screen if the current one is a different
2149        // version than the last one shown, and we are not running in
2150        // low-level factory test mode.
2151        final ContentResolver resolver = mContext.getContentResolver();
2152        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2153                Settings.Secure.getInt(resolver,
2154                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2155            mCheckedForSetup = true;
2156
2157            // See if we should be showing the platform update setup UI.
2158            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2159            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2160                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2161
2162            // We don't allow third party apps to replace this.
2163            ResolveInfo ri = null;
2164            for (int i=0; ris != null && i<ris.size(); i++) {
2165                if ((ris.get(i).activityInfo.applicationInfo.flags
2166                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2167                    ri = ris.get(i);
2168                    break;
2169                }
2170            }
2171
2172            if (ri != null) {
2173                String vers = ri.activityInfo.metaData != null
2174                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2175                        : null;
2176                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2177                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2178                            Intent.METADATA_SETUP_VERSION);
2179                }
2180                String lastVers = Settings.Secure.getString(
2181                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2182                if (vers != null && !vers.equals(lastVers)) {
2183                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2184                    intent.setComponent(new ComponentName(
2185                            ri.activityInfo.packageName, ri.activityInfo.name));
2186                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2187                            null, null, 0, 0, 0, 0, null, false, null);
2188                }
2189            }
2190        }
2191    }
2192
2193    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2194        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2195    }
2196
2197    void enforceNotIsolatedCaller(String caller) {
2198        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2199            throw new SecurityException("Isolated process not allowed to call " + caller);
2200        }
2201    }
2202
2203    public int getFrontActivityScreenCompatMode() {
2204        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2205        synchronized (this) {
2206            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2207        }
2208    }
2209
2210    public void setFrontActivityScreenCompatMode(int mode) {
2211        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2212                "setFrontActivityScreenCompatMode");
2213        synchronized (this) {
2214            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2215        }
2216    }
2217
2218    public int getPackageScreenCompatMode(String packageName) {
2219        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2220        synchronized (this) {
2221            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2222        }
2223    }
2224
2225    public void setPackageScreenCompatMode(String packageName, int mode) {
2226        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2227                "setPackageScreenCompatMode");
2228        synchronized (this) {
2229            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2230        }
2231    }
2232
2233    public boolean getPackageAskScreenCompat(String packageName) {
2234        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2235        synchronized (this) {
2236            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2237        }
2238    }
2239
2240    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2241        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2242                "setPackageAskScreenCompat");
2243        synchronized (this) {
2244            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2245        }
2246    }
2247
2248    void reportResumedActivityLocked(ActivityRecord r) {
2249        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2250        updateUsageStats(r, true);
2251    }
2252
2253    private void dispatchProcessesChanged() {
2254        int N;
2255        synchronized (this) {
2256            N = mPendingProcessChanges.size();
2257            if (mActiveProcessChanges.length < N) {
2258                mActiveProcessChanges = new ProcessChangeItem[N];
2259            }
2260            mPendingProcessChanges.toArray(mActiveProcessChanges);
2261            mAvailProcessChanges.addAll(mPendingProcessChanges);
2262            mPendingProcessChanges.clear();
2263            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2264        }
2265        int i = mProcessObservers.beginBroadcast();
2266        while (i > 0) {
2267            i--;
2268            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2269            if (observer != null) {
2270                try {
2271                    for (int j=0; j<N; j++) {
2272                        ProcessChangeItem item = mActiveProcessChanges[j];
2273                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2274                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2275                                    + item.pid + " uid=" + item.uid + ": "
2276                                    + item.foregroundActivities);
2277                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2278                                    item.foregroundActivities);
2279                        }
2280                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2281                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2282                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2283                            observer.onImportanceChanged(item.pid, item.uid,
2284                                    item.importance);
2285                        }
2286                    }
2287                } catch (RemoteException e) {
2288                }
2289            }
2290        }
2291        mProcessObservers.finishBroadcast();
2292    }
2293
2294    private void dispatchProcessDied(int pid, int uid) {
2295        int i = mProcessObservers.beginBroadcast();
2296        while (i > 0) {
2297            i--;
2298            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2299            if (observer != null) {
2300                try {
2301                    observer.onProcessDied(pid, uid);
2302                } catch (RemoteException e) {
2303                }
2304            }
2305        }
2306        mProcessObservers.finishBroadcast();
2307    }
2308
2309    final void doPendingActivityLaunchesLocked(boolean doResume) {
2310        final int N = mPendingActivityLaunches.size();
2311        if (N <= 0) {
2312            return;
2313        }
2314        for (int i=0; i<N; i++) {
2315            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2316            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2317                    pal.startFlags, doResume && i == (N-1), null);
2318        }
2319        mPendingActivityLaunches.clear();
2320    }
2321
2322    public final int startActivity(IApplicationThread caller,
2323            Intent intent, String resolvedType, IBinder resultTo,
2324            String resultWho, int requestCode, int startFlags,
2325            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2326        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2327                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2328    }
2329
2330    public final int startActivityAsUser(IApplicationThread caller,
2331            Intent intent, String resolvedType, IBinder resultTo,
2332            String resultWho, int requestCode, int startFlags,
2333            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2334        enforceNotIsolatedCaller("startActivity");
2335        if (userId != UserHandle.getCallingUserId()) {
2336            // Requesting a different user, make sure that they have the permission
2337            if (checkComponentPermission(
2338                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2339                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2340                    == PackageManager.PERMISSION_GRANTED) {
2341                // Translate to the current user id, if caller wasn't aware
2342                if (userId == UserHandle.USER_CURRENT) {
2343                    userId = mCurrentUserId;
2344                }
2345            } else {
2346                String msg = "Permission Denial: "
2347                        + "Request to startActivity as user " + userId
2348                        + " but is calling from user " + UserHandle.getCallingUserId()
2349                        + "; this requires "
2350                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2351                Slog.w(TAG, msg);
2352                throw new SecurityException(msg);
2353            }
2354        } else {
2355            if (intent.getCategories() != null
2356                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2357                // Requesting home, set the identity to the current user
2358                // HACK!
2359                userId = mCurrentUserId;
2360            } else {
2361                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2362                // the current user's userId
2363                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2364                    userId = 0;
2365                } else {
2366                    userId = Binder.getOrigCallingUser();
2367                }
2368            }
2369        }
2370        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2371                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2372                null, null, options, userId);
2373    }
2374
2375    public final WaitResult startActivityAndWait(IApplicationThread caller,
2376            Intent intent, String resolvedType, IBinder resultTo,
2377            String resultWho, int requestCode, int startFlags, String profileFile,
2378            ParcelFileDescriptor profileFd, Bundle options) {
2379        enforceNotIsolatedCaller("startActivityAndWait");
2380        WaitResult res = new WaitResult();
2381        int userId = Binder.getOrigCallingUser();
2382        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2383                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2384                res, null, options, userId);
2385        return res;
2386    }
2387
2388    public final int startActivityWithConfig(IApplicationThread caller,
2389            Intent intent, String resolvedType, IBinder resultTo,
2390            String resultWho, int requestCode, int startFlags, Configuration config,
2391            Bundle options) {
2392        enforceNotIsolatedCaller("startActivityWithConfig");
2393        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2394                resultTo, resultWho, requestCode, startFlags,
2395                null, null, null, config, options, Binder.getOrigCallingUser());
2396        return ret;
2397    }
2398
2399    public int startActivityIntentSender(IApplicationThread caller,
2400            IntentSender intent, Intent fillInIntent, String resolvedType,
2401            IBinder resultTo, String resultWho, int requestCode,
2402            int flagsMask, int flagsValues, Bundle options) {
2403        enforceNotIsolatedCaller("startActivityIntentSender");
2404        // Refuse possible leaked file descriptors
2405        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2406            throw new IllegalArgumentException("File descriptors passed in Intent");
2407        }
2408
2409        IIntentSender sender = intent.getTarget();
2410        if (!(sender instanceof PendingIntentRecord)) {
2411            throw new IllegalArgumentException("Bad PendingIntent object");
2412        }
2413
2414        PendingIntentRecord pir = (PendingIntentRecord)sender;
2415
2416        synchronized (this) {
2417            // If this is coming from the currently resumed activity, it is
2418            // effectively saying that app switches are allowed at this point.
2419            if (mMainStack.mResumedActivity != null
2420                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2421                            Binder.getCallingUid()) {
2422                mAppSwitchesAllowedTime = 0;
2423            }
2424        }
2425        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2426                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2427        return ret;
2428    }
2429
2430    public boolean startNextMatchingActivity(IBinder callingActivity,
2431            Intent intent, Bundle options) {
2432        // Refuse possible leaked file descriptors
2433        if (intent != null && intent.hasFileDescriptors() == true) {
2434            throw new IllegalArgumentException("File descriptors passed in Intent");
2435        }
2436
2437        synchronized (this) {
2438            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2439            if (r == null) {
2440                ActivityOptions.abort(options);
2441                return false;
2442            }
2443            if (r.app == null || r.app.thread == null) {
2444                // The caller is not running...  d'oh!
2445                ActivityOptions.abort(options);
2446                return false;
2447            }
2448            intent = new Intent(intent);
2449            // The caller is not allowed to change the data.
2450            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2451            // And we are resetting to find the next component...
2452            intent.setComponent(null);
2453
2454            ActivityInfo aInfo = null;
2455            try {
2456                List<ResolveInfo> resolves =
2457                    AppGlobals.getPackageManager().queryIntentActivities(
2458                            intent, r.resolvedType,
2459                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2460                            UserHandle.getCallingUserId());
2461
2462                // Look for the original activity in the list...
2463                final int N = resolves != null ? resolves.size() : 0;
2464                for (int i=0; i<N; i++) {
2465                    ResolveInfo rInfo = resolves.get(i);
2466                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2467                            && rInfo.activityInfo.name.equals(r.info.name)) {
2468                        // We found the current one...  the next matching is
2469                        // after it.
2470                        i++;
2471                        if (i<N) {
2472                            aInfo = resolves.get(i).activityInfo;
2473                        }
2474                        break;
2475                    }
2476                }
2477            } catch (RemoteException e) {
2478            }
2479
2480            if (aInfo == null) {
2481                // Nobody who is next!
2482                ActivityOptions.abort(options);
2483                return false;
2484            }
2485
2486            intent.setComponent(new ComponentName(
2487                    aInfo.applicationInfo.packageName, aInfo.name));
2488            intent.setFlags(intent.getFlags()&~(
2489                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2490                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2491                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2492                    Intent.FLAG_ACTIVITY_NEW_TASK));
2493
2494            // Okay now we need to start the new activity, replacing the
2495            // currently running activity.  This is a little tricky because
2496            // we want to start the new one as if the current one is finished,
2497            // but not finish the current one first so that there is no flicker.
2498            // And thus...
2499            final boolean wasFinishing = r.finishing;
2500            r.finishing = true;
2501
2502            // Propagate reply information over to the new activity.
2503            final ActivityRecord resultTo = r.resultTo;
2504            final String resultWho = r.resultWho;
2505            final int requestCode = r.requestCode;
2506            r.resultTo = null;
2507            if (resultTo != null) {
2508                resultTo.removeResultsLocked(r, resultWho, requestCode);
2509            }
2510
2511            final long origId = Binder.clearCallingIdentity();
2512            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2513                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2514                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2515                    options, false, null);
2516            Binder.restoreCallingIdentity(origId);
2517
2518            r.finishing = wasFinishing;
2519            if (res != ActivityManager.START_SUCCESS) {
2520                return false;
2521            }
2522            return true;
2523        }
2524    }
2525
2526    public final int startActivityInPackage(int uid,
2527            Intent intent, String resolvedType, IBinder resultTo,
2528            String resultWho, int requestCode, int startFlags, Bundle options) {
2529
2530        // This is so super not safe, that only the system (or okay root)
2531        // can do it.
2532        int userId = Binder.getOrigCallingUser();
2533        final int callingUid = Binder.getCallingUid();
2534        if (callingUid != 0 && callingUid != Process.myUid()) {
2535            throw new SecurityException(
2536                    "startActivityInPackage only available to the system");
2537        }
2538
2539        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2540                resultTo, resultWho, requestCode, startFlags,
2541                null, null, null, null, options, userId);
2542        return ret;
2543    }
2544
2545    public final int startActivities(IApplicationThread caller,
2546            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2547        enforceNotIsolatedCaller("startActivities");
2548        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2549                options, Binder.getOrigCallingUser());
2550        return ret;
2551    }
2552
2553    public final int startActivitiesInPackage(int uid,
2554            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2555            Bundle options) {
2556
2557        // This is so super not safe, that only the system (or okay root)
2558        // can do it.
2559        final int callingUid = Binder.getCallingUid();
2560        if (callingUid != 0 && callingUid != Process.myUid()) {
2561            throw new SecurityException(
2562                    "startActivityInPackage only available to the system");
2563        }
2564        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2565                options, UserHandle.getUserId(uid));
2566        return ret;
2567    }
2568
2569    final void addRecentTaskLocked(TaskRecord task) {
2570        int N = mRecentTasks.size();
2571        // Quick case: check if the top-most recent task is the same.
2572        if (N > 0 && mRecentTasks.get(0) == task) {
2573            return;
2574        }
2575        // Remove any existing entries that are the same kind of task.
2576        for (int i=0; i<N; i++) {
2577            TaskRecord tr = mRecentTasks.get(i);
2578            if (task.userId == tr.userId
2579                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2580                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2581                mRecentTasks.remove(i);
2582                i--;
2583                N--;
2584                if (task.intent == null) {
2585                    // If the new recent task we are adding is not fully
2586                    // specified, then replace it with the existing recent task.
2587                    task = tr;
2588                }
2589            }
2590        }
2591        if (N >= MAX_RECENT_TASKS) {
2592            mRecentTasks.remove(N-1);
2593        }
2594        mRecentTasks.add(0, task);
2595    }
2596
2597    public void setRequestedOrientation(IBinder token,
2598            int requestedOrientation) {
2599        synchronized (this) {
2600            ActivityRecord r = mMainStack.isInStackLocked(token);
2601            if (r == null) {
2602                return;
2603            }
2604            final long origId = Binder.clearCallingIdentity();
2605            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2606            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2607                    mConfiguration,
2608                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2609            if (config != null) {
2610                r.frozenBeforeDestroy = true;
2611                if (!updateConfigurationLocked(config, r, false, false)) {
2612                    mMainStack.resumeTopActivityLocked(null);
2613                }
2614            }
2615            Binder.restoreCallingIdentity(origId);
2616        }
2617    }
2618
2619    public int getRequestedOrientation(IBinder token) {
2620        synchronized (this) {
2621            ActivityRecord r = mMainStack.isInStackLocked(token);
2622            if (r == null) {
2623                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2624            }
2625            return mWindowManager.getAppOrientation(r.appToken);
2626        }
2627    }
2628
2629    /**
2630     * This is the internal entry point for handling Activity.finish().
2631     *
2632     * @param token The Binder token referencing the Activity we want to finish.
2633     * @param resultCode Result code, if any, from this Activity.
2634     * @param resultData Result data (Intent), if any, from this Activity.
2635     *
2636     * @return Returns true if the activity successfully finished, or false if it is still running.
2637     */
2638    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2639        // Refuse possible leaked file descriptors
2640        if (resultData != null && resultData.hasFileDescriptors() == true) {
2641            throw new IllegalArgumentException("File descriptors passed in Intent");
2642        }
2643
2644        synchronized(this) {
2645            if (mController != null) {
2646                // Find the first activity that is not finishing.
2647                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2648                if (next != null) {
2649                    // ask watcher if this is allowed
2650                    boolean resumeOK = true;
2651                    try {
2652                        resumeOK = mController.activityResuming(next.packageName);
2653                    } catch (RemoteException e) {
2654                        mController = null;
2655                    }
2656
2657                    if (!resumeOK) {
2658                        return false;
2659                    }
2660                }
2661            }
2662            final long origId = Binder.clearCallingIdentity();
2663            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2664                    resultData, "app-request");
2665            Binder.restoreCallingIdentity(origId);
2666            return res;
2667        }
2668    }
2669
2670    public final void finishHeavyWeightApp() {
2671        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2672                != PackageManager.PERMISSION_GRANTED) {
2673            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2674                    + Binder.getCallingPid()
2675                    + ", uid=" + Binder.getCallingUid()
2676                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2677            Slog.w(TAG, msg);
2678            throw new SecurityException(msg);
2679        }
2680
2681        synchronized(this) {
2682            if (mHeavyWeightProcess == null) {
2683                return;
2684            }
2685
2686            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2687                    mHeavyWeightProcess.activities);
2688            for (int i=0; i<activities.size(); i++) {
2689                ActivityRecord r = activities.get(i);
2690                if (!r.finishing) {
2691                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2692                    if (index >= 0) {
2693                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2694                                null, "finish-heavy");
2695                    }
2696                }
2697            }
2698
2699            mHeavyWeightProcess = null;
2700            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2701        }
2702    }
2703
2704    public void crashApplication(int uid, int initialPid, String packageName,
2705            String message) {
2706        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2707                != PackageManager.PERMISSION_GRANTED) {
2708            String msg = "Permission Denial: crashApplication() from pid="
2709                    + Binder.getCallingPid()
2710                    + ", uid=" + Binder.getCallingUid()
2711                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2712            Slog.w(TAG, msg);
2713            throw new SecurityException(msg);
2714        }
2715
2716        synchronized(this) {
2717            ProcessRecord proc = null;
2718
2719            // Figure out which process to kill.  We don't trust that initialPid
2720            // still has any relation to current pids, so must scan through the
2721            // list.
2722            synchronized (mPidsSelfLocked) {
2723                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2724                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2725                    if (p.uid != uid) {
2726                        continue;
2727                    }
2728                    if (p.pid == initialPid) {
2729                        proc = p;
2730                        break;
2731                    }
2732                    for (String str : p.pkgList) {
2733                        if (str.equals(packageName)) {
2734                            proc = p;
2735                        }
2736                    }
2737                }
2738            }
2739
2740            if (proc == null) {
2741                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2742                        + " initialPid=" + initialPid
2743                        + " packageName=" + packageName);
2744                return;
2745            }
2746
2747            if (proc.thread != null) {
2748                if (proc.pid == Process.myPid()) {
2749                    Log.w(TAG, "crashApplication: trying to crash self!");
2750                    return;
2751                }
2752                long ident = Binder.clearCallingIdentity();
2753                try {
2754                    proc.thread.scheduleCrash(message);
2755                } catch (RemoteException e) {
2756                }
2757                Binder.restoreCallingIdentity(ident);
2758            }
2759        }
2760    }
2761
2762    public final void finishSubActivity(IBinder token, String resultWho,
2763            int requestCode) {
2764        synchronized(this) {
2765            final long origId = Binder.clearCallingIdentity();
2766            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2767            Binder.restoreCallingIdentity(origId);
2768        }
2769    }
2770
2771    public boolean finishActivityAffinity(IBinder token) {
2772        synchronized(this) {
2773            final long origId = Binder.clearCallingIdentity();
2774            boolean res = mMainStack.finishActivityAffinityLocked(token);
2775            Binder.restoreCallingIdentity(origId);
2776            return res;
2777        }
2778    }
2779
2780    public boolean willActivityBeVisible(IBinder token) {
2781        synchronized(this) {
2782            int i;
2783            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2784                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2785                if (r.appToken == token) {
2786                    return true;
2787                }
2788                if (r.fullscreen && !r.finishing) {
2789                    return false;
2790                }
2791            }
2792            return true;
2793        }
2794    }
2795
2796    public void overridePendingTransition(IBinder token, String packageName,
2797            int enterAnim, int exitAnim) {
2798        synchronized(this) {
2799            ActivityRecord self = mMainStack.isInStackLocked(token);
2800            if (self == null) {
2801                return;
2802            }
2803
2804            final long origId = Binder.clearCallingIdentity();
2805
2806            if (self.state == ActivityState.RESUMED
2807                    || self.state == ActivityState.PAUSING) {
2808                mWindowManager.overridePendingAppTransition(packageName,
2809                        enterAnim, exitAnim, null);
2810            }
2811
2812            Binder.restoreCallingIdentity(origId);
2813        }
2814    }
2815
2816    /**
2817     * Main function for removing an existing process from the activity manager
2818     * as a result of that process going away.  Clears out all connections
2819     * to the process.
2820     */
2821    private final void handleAppDiedLocked(ProcessRecord app,
2822            boolean restarting, boolean allowRestart) {
2823        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2824        if (!restarting) {
2825            mLruProcesses.remove(app);
2826        }
2827
2828        if (mProfileProc == app) {
2829            clearProfilerLocked();
2830        }
2831
2832        // Just in case...
2833        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2834            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2835            mMainStack.mPausingActivity = null;
2836        }
2837        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2838            mMainStack.mLastPausedActivity = null;
2839        }
2840
2841        // Remove this application's activities from active lists.
2842        mMainStack.removeHistoryRecordsForAppLocked(app);
2843
2844        boolean atTop = true;
2845        boolean hasVisibleActivities = false;
2846
2847        // Clean out the history list.
2848        int i = mMainStack.mHistory.size();
2849        if (localLOGV) Slog.v(
2850            TAG, "Removing app " + app + " from history with " + i + " entries");
2851        while (i > 0) {
2852            i--;
2853            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2854            if (localLOGV) Slog.v(
2855                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2856            if (r.app == app) {
2857                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2858                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2859                        RuntimeException here = new RuntimeException("here");
2860                        here.fillInStackTrace();
2861                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2862                                + ": haveState=" + r.haveState
2863                                + " stateNotNeeded=" + r.stateNotNeeded
2864                                + " finishing=" + r.finishing
2865                                + " state=" + r.state, here);
2866                    }
2867                    if (!r.finishing) {
2868                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2869                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2870                                System.identityHashCode(r),
2871                                r.task.taskId, r.shortComponentName,
2872                                "proc died without state saved");
2873                    }
2874                    mMainStack.removeActivityFromHistoryLocked(r);
2875
2876                } else {
2877                    // We have the current state for this activity, so
2878                    // it can be restarted later when needed.
2879                    if (localLOGV) Slog.v(
2880                        TAG, "Keeping entry, setting app to null");
2881                    if (r.visible) {
2882                        hasVisibleActivities = true;
2883                    }
2884                    r.app = null;
2885                    r.nowVisible = false;
2886                    if (!r.haveState) {
2887                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2888                                "App died, clearing saved state of " + r);
2889                        r.icicle = null;
2890                    }
2891                }
2892
2893                r.stack.cleanUpActivityLocked(r, true, true);
2894            }
2895            atTop = false;
2896        }
2897
2898        app.activities.clear();
2899
2900        if (app.instrumentationClass != null) {
2901            Slog.w(TAG, "Crash of app " + app.processName
2902                  + " running instrumentation " + app.instrumentationClass);
2903            Bundle info = new Bundle();
2904            info.putString("shortMsg", "Process crashed.");
2905            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2906        }
2907
2908        if (!restarting) {
2909            if (!mMainStack.resumeTopActivityLocked(null)) {
2910                // If there was nothing to resume, and we are not already
2911                // restarting this process, but there is a visible activity that
2912                // is hosted by the process...  then make sure all visible
2913                // activities are running, taking care of restarting this
2914                // process.
2915                if (hasVisibleActivities) {
2916                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2917                }
2918            }
2919        }
2920    }
2921
2922    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2923        IBinder threadBinder = thread.asBinder();
2924        // Find the application record.
2925        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2926            ProcessRecord rec = mLruProcesses.get(i);
2927            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2928                return i;
2929            }
2930        }
2931        return -1;
2932    }
2933
2934    final ProcessRecord getRecordForAppLocked(
2935            IApplicationThread thread) {
2936        if (thread == null) {
2937            return null;
2938        }
2939
2940        int appIndex = getLRURecordIndexForAppLocked(thread);
2941        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2942    }
2943
2944    final void appDiedLocked(ProcessRecord app, int pid,
2945            IApplicationThread thread) {
2946
2947        mProcDeaths[0]++;
2948
2949        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2950        synchronized (stats) {
2951            stats.noteProcessDiedLocked(app.info.uid, pid);
2952        }
2953
2954        // Clean up already done if the process has been re-started.
2955        if (app.pid == pid && app.thread != null &&
2956                app.thread.asBinder() == thread.asBinder()) {
2957            if (!app.killedBackground) {
2958                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2959                        + ") has died.");
2960            }
2961            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2962            if (localLOGV) Slog.v(
2963                TAG, "Dying app: " + app + ", pid: " + pid
2964                + ", thread: " + thread.asBinder());
2965            boolean doLowMem = app.instrumentationClass == null;
2966            handleAppDiedLocked(app, false, true);
2967
2968            if (doLowMem) {
2969                // If there are no longer any background processes running,
2970                // and the app that died was not running instrumentation,
2971                // then tell everyone we are now low on memory.
2972                boolean haveBg = false;
2973                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2974                    ProcessRecord rec = mLruProcesses.get(i);
2975                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2976                        haveBg = true;
2977                        break;
2978                    }
2979                }
2980
2981                if (!haveBg) {
2982                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2983                    long now = SystemClock.uptimeMillis();
2984                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2985                        ProcessRecord rec = mLruProcesses.get(i);
2986                        if (rec != app && rec.thread != null &&
2987                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2988                            // The low memory report is overriding any current
2989                            // state for a GC request.  Make sure to do
2990                            // heavy/important/visible/foreground processes first.
2991                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2992                                rec.lastRequestedGc = 0;
2993                            } else {
2994                                rec.lastRequestedGc = rec.lastLowMemory;
2995                            }
2996                            rec.reportLowMemory = true;
2997                            rec.lastLowMemory = now;
2998                            mProcessesToGc.remove(rec);
2999                            addProcessToGcListLocked(rec);
3000                        }
3001                    }
3002                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3003                    scheduleAppGcsLocked();
3004                }
3005            }
3006        } else if (app.pid != pid) {
3007            // A new process has already been started.
3008            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3009                    + ") has died and restarted (pid " + app.pid + ").");
3010            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3011        } else if (DEBUG_PROCESSES) {
3012            Slog.d(TAG, "Received spurious death notification for thread "
3013                    + thread.asBinder());
3014        }
3015    }
3016
3017    /**
3018     * If a stack trace dump file is configured, dump process stack traces.
3019     * @param clearTraces causes the dump file to be erased prior to the new
3020     *    traces being written, if true; when false, the new traces will be
3021     *    appended to any existing file content.
3022     * @param firstPids of dalvik VM processes to dump stack traces for first
3023     * @param lastPids of dalvik VM processes to dump stack traces for last
3024     * @param nativeProcs optional list of native process names to dump stack crawls
3025     * @return file containing stack traces, or null if no dump file is configured
3026     */
3027    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3028            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3029        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3030        if (tracesPath == null || tracesPath.length() == 0) {
3031            return null;
3032        }
3033
3034        File tracesFile = new File(tracesPath);
3035        try {
3036            File tracesDir = tracesFile.getParentFile();
3037            if (!tracesDir.exists()) tracesFile.mkdirs();
3038            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3039
3040            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3041            tracesFile.createNewFile();
3042            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3043        } catch (IOException e) {
3044            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3045            return null;
3046        }
3047
3048        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3049        return tracesFile;
3050    }
3051
3052    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3053            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3054        // Use a FileObserver to detect when traces finish writing.
3055        // The order of traces is considered important to maintain for legibility.
3056        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3057            public synchronized void onEvent(int event, String path) { notify(); }
3058        };
3059
3060        try {
3061            observer.startWatching();
3062
3063            // First collect all of the stacks of the most important pids.
3064            if (firstPids != null) {
3065                try {
3066                    int num = firstPids.size();
3067                    for (int i = 0; i < num; i++) {
3068                        synchronized (observer) {
3069                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3070                            observer.wait(200);  // Wait for write-close, give up after 200msec
3071                        }
3072                    }
3073                } catch (InterruptedException e) {
3074                    Log.wtf(TAG, e);
3075                }
3076            }
3077
3078            // Next measure CPU usage.
3079            if (processStats != null) {
3080                processStats.init();
3081                System.gc();
3082                processStats.update();
3083                try {
3084                    synchronized (processStats) {
3085                        processStats.wait(500); // measure over 1/2 second.
3086                    }
3087                } catch (InterruptedException e) {
3088                }
3089                processStats.update();
3090
3091                // We'll take the stack crawls of just the top apps using CPU.
3092                final int N = processStats.countWorkingStats();
3093                int numProcs = 0;
3094                for (int i=0; i<N && numProcs<5; i++) {
3095                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3096                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3097                        numProcs++;
3098                        try {
3099                            synchronized (observer) {
3100                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3101                                observer.wait(200);  // Wait for write-close, give up after 200msec
3102                            }
3103                        } catch (InterruptedException e) {
3104                            Log.wtf(TAG, e);
3105                        }
3106
3107                    }
3108                }
3109            }
3110
3111        } finally {
3112            observer.stopWatching();
3113        }
3114
3115        if (nativeProcs != null) {
3116            int[] pids = Process.getPidsForCommands(nativeProcs);
3117            if (pids != null) {
3118                for (int pid : pids) {
3119                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3120                }
3121            }
3122        }
3123    }
3124
3125    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3126        if (true || IS_USER_BUILD) {
3127            return;
3128        }
3129        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3130        if (tracesPath == null || tracesPath.length() == 0) {
3131            return;
3132        }
3133
3134        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3135        StrictMode.allowThreadDiskWrites();
3136        try {
3137            final File tracesFile = new File(tracesPath);
3138            final File tracesDir = tracesFile.getParentFile();
3139            final File tracesTmp = new File(tracesDir, "__tmp__");
3140            try {
3141                if (!tracesDir.exists()) tracesFile.mkdirs();
3142                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3143
3144                if (tracesFile.exists()) {
3145                    tracesTmp.delete();
3146                    tracesFile.renameTo(tracesTmp);
3147                }
3148                StringBuilder sb = new StringBuilder();
3149                Time tobj = new Time();
3150                tobj.set(System.currentTimeMillis());
3151                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3152                sb.append(": ");
3153                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3154                sb.append(" since ");
3155                sb.append(msg);
3156                FileOutputStream fos = new FileOutputStream(tracesFile);
3157                fos.write(sb.toString().getBytes());
3158                if (app == null) {
3159                    fos.write("\n*** No application process!".getBytes());
3160                }
3161                fos.close();
3162                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3163            } catch (IOException e) {
3164                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3165                return;
3166            }
3167
3168            if (app != null) {
3169                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3170                firstPids.add(app.pid);
3171                dumpStackTraces(tracesPath, firstPids, null, null, null);
3172            }
3173
3174            File lastTracesFile = null;
3175            File curTracesFile = null;
3176            for (int i=9; i>=0; i--) {
3177                String name = String.format("slow%02d.txt", i);
3178                curTracesFile = new File(tracesDir, name);
3179                if (curTracesFile.exists()) {
3180                    if (lastTracesFile != null) {
3181                        curTracesFile.renameTo(lastTracesFile);
3182                    } else {
3183                        curTracesFile.delete();
3184                    }
3185                }
3186                lastTracesFile = curTracesFile;
3187            }
3188            tracesFile.renameTo(curTracesFile);
3189            if (tracesTmp.exists()) {
3190                tracesTmp.renameTo(tracesFile);
3191            }
3192        } finally {
3193            StrictMode.setThreadPolicy(oldPolicy);
3194        }
3195    }
3196
3197    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3198            ActivityRecord parent, final String annotation) {
3199        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3200        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3201
3202        if (mController != null) {
3203            try {
3204                // 0 == continue, -1 = kill process immediately
3205                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3206                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3207            } catch (RemoteException e) {
3208                mController = null;
3209            }
3210        }
3211
3212        long anrTime = SystemClock.uptimeMillis();
3213        if (MONITOR_CPU_USAGE) {
3214            updateCpuStatsNow();
3215        }
3216
3217        synchronized (this) {
3218            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3219            if (mShuttingDown) {
3220                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3221                return;
3222            } else if (app.notResponding) {
3223                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3224                return;
3225            } else if (app.crashing) {
3226                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3227                return;
3228            }
3229
3230            // In case we come through here for the same app before completing
3231            // this one, mark as anring now so we will bail out.
3232            app.notResponding = true;
3233
3234            // Log the ANR to the event log.
3235            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3236                    annotation);
3237
3238            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3239            firstPids.add(app.pid);
3240
3241            int parentPid = app.pid;
3242            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3243            if (parentPid != app.pid) firstPids.add(parentPid);
3244
3245            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3246
3247            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3248                ProcessRecord r = mLruProcesses.get(i);
3249                if (r != null && r.thread != null) {
3250                    int pid = r.pid;
3251                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3252                        if (r.persistent) {
3253                            firstPids.add(pid);
3254                        } else {
3255                            lastPids.put(pid, Boolean.TRUE);
3256                        }
3257                    }
3258                }
3259            }
3260        }
3261
3262        // Log the ANR to the main log.
3263        StringBuilder info = new StringBuilder();
3264        info.setLength(0);
3265        info.append("ANR in ").append(app.processName);
3266        if (activity != null && activity.shortComponentName != null) {
3267            info.append(" (").append(activity.shortComponentName).append(")");
3268        }
3269        info.append("\n");
3270        if (annotation != null) {
3271            info.append("Reason: ").append(annotation).append("\n");
3272        }
3273        if (parent != null && parent != activity) {
3274            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3275        }
3276
3277        final ProcessStats processStats = new ProcessStats(true);
3278
3279        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3280
3281        String cpuInfo = null;
3282        if (MONITOR_CPU_USAGE) {
3283            updateCpuStatsNow();
3284            synchronized (mProcessStatsThread) {
3285                cpuInfo = mProcessStats.printCurrentState(anrTime);
3286            }
3287            info.append(processStats.printCurrentLoad());
3288            info.append(cpuInfo);
3289        }
3290
3291        info.append(processStats.printCurrentState(anrTime));
3292
3293        Slog.e(TAG, info.toString());
3294        if (tracesFile == null) {
3295            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3296            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3297        }
3298
3299        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3300                cpuInfo, tracesFile, null);
3301
3302        if (mController != null) {
3303            try {
3304                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3305                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3306                if (res != 0) {
3307                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3308                    return;
3309                }
3310            } catch (RemoteException e) {
3311                mController = null;
3312            }
3313        }
3314
3315        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3316        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3317                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3318
3319        synchronized (this) {
3320            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3321                Slog.w(TAG, "Killing " + app + ": background ANR");
3322                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3323                        app.processName, app.setAdj, "background ANR");
3324                Process.killProcessQuiet(app.pid);
3325                return;
3326            }
3327
3328            // Set the app's notResponding state, and look up the errorReportReceiver
3329            makeAppNotRespondingLocked(app,
3330                    activity != null ? activity.shortComponentName : null,
3331                    annotation != null ? "ANR " + annotation : "ANR",
3332                    info.toString());
3333
3334            // Bring up the infamous App Not Responding dialog
3335            Message msg = Message.obtain();
3336            HashMap map = new HashMap();
3337            msg.what = SHOW_NOT_RESPONDING_MSG;
3338            msg.obj = map;
3339            map.put("app", app);
3340            if (activity != null) {
3341                map.put("activity", activity);
3342            }
3343
3344            mHandler.sendMessage(msg);
3345        }
3346    }
3347
3348    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3349        if (!mLaunchWarningShown) {
3350            mLaunchWarningShown = true;
3351            mHandler.post(new Runnable() {
3352                @Override
3353                public void run() {
3354                    synchronized (ActivityManagerService.this) {
3355                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3356                        d.show();
3357                        mHandler.postDelayed(new Runnable() {
3358                            @Override
3359                            public void run() {
3360                                synchronized (ActivityManagerService.this) {
3361                                    d.dismiss();
3362                                    mLaunchWarningShown = false;
3363                                }
3364                            }
3365                        }, 4000);
3366                    }
3367                }
3368            });
3369        }
3370    }
3371
3372    public boolean clearApplicationUserData(final String packageName,
3373            final IPackageDataObserver observer, final int userId) {
3374        enforceNotIsolatedCaller("clearApplicationUserData");
3375        int uid = Binder.getCallingUid();
3376        int pid = Binder.getCallingPid();
3377        long callingId = Binder.clearCallingIdentity();
3378        try {
3379            IPackageManager pm = AppGlobals.getPackageManager();
3380            int pkgUid = -1;
3381            synchronized(this) {
3382                try {
3383                    pkgUid = pm.getPackageUid(packageName, userId);
3384                } catch (RemoteException e) {
3385                }
3386                if (pkgUid == -1) {
3387                    Slog.w(TAG, "Invalid packageName:" + packageName);
3388                    return false;
3389                }
3390                if (uid == pkgUid || checkComponentPermission(
3391                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3392                        pid, uid, -1, true)
3393                        == PackageManager.PERMISSION_GRANTED) {
3394                    forceStopPackageLocked(packageName, pkgUid);
3395                } else {
3396                    throw new SecurityException(pid+" does not have permission:"+
3397                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3398                                    "for process:"+packageName);
3399                }
3400            }
3401
3402            try {
3403                //clear application user data
3404                pm.clearApplicationUserData(packageName, observer, userId);
3405                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3406                        Uri.fromParts("package", packageName, null));
3407                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3408                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3409                        null, null, 0, null, null, null, false, false, userId);
3410            } catch (RemoteException e) {
3411            }
3412        } finally {
3413            Binder.restoreCallingIdentity(callingId);
3414        }
3415        return true;
3416    }
3417
3418    public void killBackgroundProcesses(final String packageName) {
3419        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3420                != PackageManager.PERMISSION_GRANTED &&
3421                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3422                        != PackageManager.PERMISSION_GRANTED) {
3423            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3424                    + Binder.getCallingPid()
3425                    + ", uid=" + Binder.getCallingUid()
3426                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3427            Slog.w(TAG, msg);
3428            throw new SecurityException(msg);
3429        }
3430
3431        int userId = UserHandle.getCallingUserId();
3432        long callingId = Binder.clearCallingIdentity();
3433        try {
3434            IPackageManager pm = AppGlobals.getPackageManager();
3435            int pkgUid = -1;
3436            synchronized(this) {
3437                try {
3438                    pkgUid = pm.getPackageUid(packageName, userId);
3439                } catch (RemoteException e) {
3440                }
3441                if (pkgUid == -1) {
3442                    Slog.w(TAG, "Invalid packageName: " + packageName);
3443                    return;
3444                }
3445                killPackageProcessesLocked(packageName, pkgUid,
3446                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3447            }
3448        } finally {
3449            Binder.restoreCallingIdentity(callingId);
3450        }
3451    }
3452
3453    public void killAllBackgroundProcesses() {
3454        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3455                != PackageManager.PERMISSION_GRANTED) {
3456            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3457                    + Binder.getCallingPid()
3458                    + ", uid=" + Binder.getCallingUid()
3459                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3460            Slog.w(TAG, msg);
3461            throw new SecurityException(msg);
3462        }
3463
3464        long callingId = Binder.clearCallingIdentity();
3465        try {
3466            synchronized(this) {
3467                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3468                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3469                    final int NA = apps.size();
3470                    for (int ia=0; ia<NA; ia++) {
3471                        ProcessRecord app = apps.valueAt(ia);
3472                        if (app.persistent) {
3473                            // we don't kill persistent processes
3474                            continue;
3475                        }
3476                        if (app.removed) {
3477                            procs.add(app);
3478                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3479                            app.removed = true;
3480                            procs.add(app);
3481                        }
3482                    }
3483                }
3484
3485                int N = procs.size();
3486                for (int i=0; i<N; i++) {
3487                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3488                }
3489            }
3490        } finally {
3491            Binder.restoreCallingIdentity(callingId);
3492        }
3493    }
3494
3495    public void forceStopPackage(final String packageName) {
3496        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3497                != PackageManager.PERMISSION_GRANTED) {
3498            String msg = "Permission Denial: forceStopPackage() from pid="
3499                    + Binder.getCallingPid()
3500                    + ", uid=" + Binder.getCallingUid()
3501                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3502            Slog.w(TAG, msg);
3503            throw new SecurityException(msg);
3504        }
3505        final int userId = UserHandle.getCallingUserId();
3506        long callingId = Binder.clearCallingIdentity();
3507        try {
3508            IPackageManager pm = AppGlobals.getPackageManager();
3509            int pkgUid = -1;
3510            synchronized(this) {
3511                try {
3512                    pkgUid = pm.getPackageUid(packageName, userId);
3513                } catch (RemoteException e) {
3514                }
3515                if (pkgUid == -1) {
3516                    Slog.w(TAG, "Invalid packageName: " + packageName);
3517                    return;
3518                }
3519                forceStopPackageLocked(packageName, pkgUid);
3520                try {
3521                    pm.setPackageStoppedState(packageName, true, userId);
3522                } catch (RemoteException e) {
3523                } catch (IllegalArgumentException e) {
3524                    Slog.w(TAG, "Failed trying to unstop package "
3525                            + packageName + ": " + e);
3526                }
3527            }
3528        } finally {
3529            Binder.restoreCallingIdentity(callingId);
3530        }
3531    }
3532
3533    /*
3534     * The pkg name and uid have to be specified.
3535     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3536     */
3537    public void killApplicationWithUid(String pkg, int uid) {
3538        if (pkg == null) {
3539            return;
3540        }
3541        // Make sure the uid is valid.
3542        if (uid < 0) {
3543            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3544            return;
3545        }
3546        int callerUid = Binder.getCallingUid();
3547        // Only the system server can kill an application
3548        if (callerUid == Process.SYSTEM_UID) {
3549            // Post an aysnc message to kill the application
3550            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3551            msg.arg1 = uid;
3552            msg.arg2 = 0;
3553            msg.obj = pkg;
3554            mHandler.sendMessage(msg);
3555        } else {
3556            throw new SecurityException(callerUid + " cannot kill pkg: " +
3557                    pkg);
3558        }
3559    }
3560
3561    public void closeSystemDialogs(String reason) {
3562        enforceNotIsolatedCaller("closeSystemDialogs");
3563
3564        final int uid = Binder.getCallingUid();
3565        final long origId = Binder.clearCallingIdentity();
3566        synchronized (this) {
3567            closeSystemDialogsLocked(uid, reason);
3568        }
3569        Binder.restoreCallingIdentity(origId);
3570    }
3571
3572    void closeSystemDialogsLocked(int callingUid, String reason) {
3573        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3574        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3575        if (reason != null) {
3576            intent.putExtra("reason", reason);
3577        }
3578        mWindowManager.closeSystemDialogs(reason);
3579
3580        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3581            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3582            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3583                r.stack.finishActivityLocked(r, i,
3584                        Activity.RESULT_CANCELED, null, "close-sys");
3585            }
3586        }
3587
3588        broadcastIntentLocked(null, null, intent, null,
3589                null, 0, null, null, null, false, false, -1,
3590                callingUid, 0 /* TODO: Verify */);
3591    }
3592
3593    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3594            throws RemoteException {
3595        enforceNotIsolatedCaller("getProcessMemoryInfo");
3596        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3597        for (int i=pids.length-1; i>=0; i--) {
3598            infos[i] = new Debug.MemoryInfo();
3599            Debug.getMemoryInfo(pids[i], infos[i]);
3600        }
3601        return infos;
3602    }
3603
3604    public long[] getProcessPss(int[] pids) throws RemoteException {
3605        enforceNotIsolatedCaller("getProcessPss");
3606        long[] pss = new long[pids.length];
3607        for (int i=pids.length-1; i>=0; i--) {
3608            pss[i] = Debug.getPss(pids[i]);
3609        }
3610        return pss;
3611    }
3612
3613    public void killApplicationProcess(String processName, int uid) {
3614        if (processName == null) {
3615            return;
3616        }
3617
3618        int callerUid = Binder.getCallingUid();
3619        // Only the system server can kill an application
3620        if (callerUid == Process.SYSTEM_UID) {
3621            synchronized (this) {
3622                ProcessRecord app = getProcessRecordLocked(processName, uid);
3623                if (app != null && app.thread != null) {
3624                    try {
3625                        app.thread.scheduleSuicide();
3626                    } catch (RemoteException e) {
3627                        // If the other end already died, then our work here is done.
3628                    }
3629                } else {
3630                    Slog.w(TAG, "Process/uid not found attempting kill of "
3631                            + processName + " / " + uid);
3632                }
3633            }
3634        } else {
3635            throw new SecurityException(callerUid + " cannot kill app process: " +
3636                    processName);
3637        }
3638    }
3639
3640    private void forceStopPackageLocked(final String packageName, int uid) {
3641        forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
3642        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3643                Uri.fromParts("package", packageName, null));
3644        if (!mProcessesReady) {
3645            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3646        }
3647        intent.putExtra(Intent.EXTRA_UID, uid);
3648        broadcastIntentLocked(null, null, intent,
3649                null, null, 0, null, null, null,
3650                false, false,
3651                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3652    }
3653
3654    private final boolean killPackageProcessesLocked(String packageName, int uid,
3655            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3656            boolean evenPersistent, String reason) {
3657        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3658
3659        // Remove all processes this package may have touched: all with the
3660        // same UID (except for the system or root user), and all whose name
3661        // matches the package name.
3662        final String procNamePrefix = packageName + ":";
3663        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3664            final int NA = apps.size();
3665            for (int ia=0; ia<NA; ia++) {
3666                ProcessRecord app = apps.valueAt(ia);
3667                if (app.persistent && !evenPersistent) {
3668                    // we don't kill persistent processes
3669                    continue;
3670                }
3671                if (app.removed) {
3672                    if (doit) {
3673                        procs.add(app);
3674                    }
3675                // If uid is specified and the uid and process name match
3676                // Or, the uid is not specified and the process name matches
3677                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3678                            || ((app.processName.equals(packageName)
3679                                 || app.processName.startsWith(procNamePrefix))
3680                                && uid < 0))) {
3681                    if (app.setAdj >= minOomAdj) {
3682                        if (!doit) {
3683                            return true;
3684                        }
3685                        app.removed = true;
3686                        procs.add(app);
3687                    }
3688                }
3689            }
3690        }
3691
3692        int N = procs.size();
3693        for (int i=0; i<N; i++) {
3694            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3695        }
3696        return N > 0;
3697    }
3698
3699    private final boolean forceStopPackageLocked(String name, int uid,
3700            boolean callerWillRestart, boolean purgeCache, boolean doit,
3701            boolean evenPersistent, int userId) {
3702        int i;
3703        int N;
3704
3705        if (uid < 0) {
3706            try {
3707                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3708            } catch (RemoteException e) {
3709            }
3710        }
3711
3712        if (doit) {
3713            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3714
3715            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3716            while (badApps.hasNext()) {
3717                SparseArray<Long> ba = badApps.next();
3718                if (ba.get(uid) != null) {
3719                    badApps.remove();
3720                }
3721            }
3722        }
3723
3724        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3725                callerWillRestart, false, doit, evenPersistent, "force stop");
3726
3727        TaskRecord lastTask = null;
3728        for (i=0; i<mMainStack.mHistory.size(); i++) {
3729            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3730            final boolean samePackage = r.packageName.equals(name);
3731            if (r.userId == userId
3732                    && (samePackage || r.task == lastTask)
3733                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3734                if (!doit) {
3735                    if (r.finishing) {
3736                        // If this activity is just finishing, then it is not
3737                        // interesting as far as something to stop.
3738                        continue;
3739                    }
3740                    return true;
3741                }
3742                didSomething = true;
3743                Slog.i(TAG, "  Force finishing activity " + r);
3744                if (samePackage) {
3745                    if (r.app != null) {
3746                        r.app.removed = true;
3747                    }
3748                    r.app = null;
3749                }
3750                lastTask = r.task;
3751                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3752                        null, "force-stop", true)) {
3753                    i--;
3754                }
3755            }
3756        }
3757
3758        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3759            if (!doit) {
3760                return true;
3761            }
3762            didSomething = true;
3763        }
3764
3765        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3766        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3767            if (provider.info.packageName.equals(name)
3768                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3769                if (!doit) {
3770                    return true;
3771                }
3772                didSomething = true;
3773                providers.add(provider);
3774            }
3775        }
3776
3777        N = providers.size();
3778        for (i=0; i<N; i++) {
3779            removeDyingProviderLocked(null, providers.get(i), true);
3780        }
3781
3782        if (doit) {
3783            if (purgeCache) {
3784                AttributeCache ac = AttributeCache.instance();
3785                if (ac != null) {
3786                    ac.removePackage(name);
3787                }
3788            }
3789            if (mBooted) {
3790                mMainStack.resumeTopActivityLocked(null);
3791                mMainStack.scheduleIdleLocked();
3792            }
3793        }
3794
3795        return didSomething;
3796    }
3797
3798    private final boolean removeProcessLocked(ProcessRecord app,
3799            boolean callerWillRestart, boolean allowRestart, String reason) {
3800        final String name = app.processName;
3801        final int uid = app.uid;
3802        if (DEBUG_PROCESSES) Slog.d(
3803            TAG, "Force removing proc " + app.toShortString() + " (" + name
3804            + "/" + uid + ")");
3805
3806        mProcessNames.remove(name, uid);
3807        mIsolatedProcesses.remove(app.uid);
3808        if (mHeavyWeightProcess == app) {
3809            mHeavyWeightProcess = null;
3810            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3811        }
3812        boolean needRestart = false;
3813        if (app.pid > 0 && app.pid != MY_PID) {
3814            int pid = app.pid;
3815            synchronized (mPidsSelfLocked) {
3816                mPidsSelfLocked.remove(pid);
3817                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3818            }
3819            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3820            handleAppDiedLocked(app, true, allowRestart);
3821            mLruProcesses.remove(app);
3822            Process.killProcessQuiet(pid);
3823
3824            if (app.persistent && !app.isolated) {
3825                if (!callerWillRestart) {
3826                    addAppLocked(app.info, false);
3827                } else {
3828                    needRestart = true;
3829                }
3830            }
3831        } else {
3832            mRemovedProcesses.add(app);
3833        }
3834
3835        return needRestart;
3836    }
3837
3838    private final void processStartTimedOutLocked(ProcessRecord app) {
3839        final int pid = app.pid;
3840        boolean gone = false;
3841        synchronized (mPidsSelfLocked) {
3842            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3843            if (knownApp != null && knownApp.thread == null) {
3844                mPidsSelfLocked.remove(pid);
3845                gone = true;
3846            }
3847        }
3848
3849        if (gone) {
3850            Slog.w(TAG, "Process " + app + " failed to attach");
3851            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3852                    app.processName);
3853            mProcessNames.remove(app.processName, app.uid);
3854            mIsolatedProcesses.remove(app.uid);
3855            if (mHeavyWeightProcess == app) {
3856                mHeavyWeightProcess = null;
3857                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3858            }
3859            // Take care of any launching providers waiting for this process.
3860            checkAppInLaunchingProvidersLocked(app, true);
3861            // Take care of any services that are waiting for the process.
3862            mServices.processStartTimedOutLocked(app);
3863            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3864                    app.processName, app.setAdj, "start timeout");
3865            Process.killProcessQuiet(pid);
3866            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3867                Slog.w(TAG, "Unattached app died before backup, skipping");
3868                try {
3869                    IBackupManager bm = IBackupManager.Stub.asInterface(
3870                            ServiceManager.getService(Context.BACKUP_SERVICE));
3871                    bm.agentDisconnected(app.info.packageName);
3872                } catch (RemoteException e) {
3873                    // Can't happen; the backup manager is local
3874                }
3875            }
3876            if (isPendingBroadcastProcessLocked(pid)) {
3877                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3878                skipPendingBroadcastLocked(pid);
3879            }
3880        } else {
3881            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3882        }
3883    }
3884
3885    private final boolean attachApplicationLocked(IApplicationThread thread,
3886            int pid) {
3887
3888        // Find the application record that is being attached...  either via
3889        // the pid if we are running in multiple processes, or just pull the
3890        // next app record if we are emulating process with anonymous threads.
3891        ProcessRecord app;
3892        if (pid != MY_PID && pid >= 0) {
3893            synchronized (mPidsSelfLocked) {
3894                app = mPidsSelfLocked.get(pid);
3895            }
3896        } else {
3897            app = null;
3898        }
3899
3900        if (app == null) {
3901            Slog.w(TAG, "No pending application record for pid " + pid
3902                    + " (IApplicationThread " + thread + "); dropping process");
3903            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3904            if (pid > 0 && pid != MY_PID) {
3905                Process.killProcessQuiet(pid);
3906            } else {
3907                try {
3908                    thread.scheduleExit();
3909                } catch (Exception e) {
3910                    // Ignore exceptions.
3911                }
3912            }
3913            return false;
3914        }
3915
3916        // If this application record is still attached to a previous
3917        // process, clean it up now.
3918        if (app.thread != null) {
3919            handleAppDiedLocked(app, true, true);
3920        }
3921
3922        // Tell the process all about itself.
3923
3924        if (localLOGV) Slog.v(
3925                TAG, "Binding process pid " + pid + " to record " + app);
3926
3927        String processName = app.processName;
3928        try {
3929            AppDeathRecipient adr = new AppDeathRecipient(
3930                    app, pid, thread);
3931            thread.asBinder().linkToDeath(adr, 0);
3932            app.deathRecipient = adr;
3933        } catch (RemoteException e) {
3934            app.resetPackageList();
3935            startProcessLocked(app, "link fail", processName);
3936            return false;
3937        }
3938
3939        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3940
3941        app.thread = thread;
3942        app.curAdj = app.setAdj = -100;
3943        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3944        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3945        app.forcingToForeground = null;
3946        app.foregroundServices = false;
3947        app.hasShownUi = false;
3948        app.debugging = false;
3949
3950        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3951
3952        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3953        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3954
3955        if (!normalMode) {
3956            Slog.i(TAG, "Launching preboot mode app: " + app);
3957        }
3958
3959        if (localLOGV) Slog.v(
3960            TAG, "New app record " + app
3961            + " thread=" + thread.asBinder() + " pid=" + pid);
3962        try {
3963            int testMode = IApplicationThread.DEBUG_OFF;
3964            if (mDebugApp != null && mDebugApp.equals(processName)) {
3965                testMode = mWaitForDebugger
3966                    ? IApplicationThread.DEBUG_WAIT
3967                    : IApplicationThread.DEBUG_ON;
3968                app.debugging = true;
3969                if (mDebugTransient) {
3970                    mDebugApp = mOrigDebugApp;
3971                    mWaitForDebugger = mOrigWaitForDebugger;
3972                }
3973            }
3974            String profileFile = app.instrumentationProfileFile;
3975            ParcelFileDescriptor profileFd = null;
3976            boolean profileAutoStop = false;
3977            if (mProfileApp != null && mProfileApp.equals(processName)) {
3978                mProfileProc = app;
3979                profileFile = mProfileFile;
3980                profileFd = mProfileFd;
3981                profileAutoStop = mAutoStopProfiler;
3982            }
3983            boolean enableOpenGlTrace = false;
3984            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3985                enableOpenGlTrace = true;
3986                mOpenGlTraceApp = null;
3987            }
3988
3989            // If the app is being launched for restore or full backup, set it up specially
3990            boolean isRestrictedBackupMode = false;
3991            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3992                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3993                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3994                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3995            }
3996
3997            ensurePackageDexOpt(app.instrumentationInfo != null
3998                    ? app.instrumentationInfo.packageName
3999                    : app.info.packageName);
4000            if (app.instrumentationClass != null) {
4001                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4002            }
4003            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4004                    + processName + " with config " + mConfiguration);
4005            ApplicationInfo appInfo = app.instrumentationInfo != null
4006                    ? app.instrumentationInfo : app.info;
4007            app.compat = compatibilityInfoForPackageLocked(appInfo);
4008            if (profileFd != null) {
4009                profileFd = profileFd.dup();
4010            }
4011            thread.bindApplication(processName, appInfo, providers,
4012                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4013                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4014                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4015                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4016                    mCoreSettingsObserver.getCoreSettingsLocked());
4017            updateLruProcessLocked(app, false, true);
4018            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4019        } catch (Exception e) {
4020            // todo: Yikes!  What should we do?  For now we will try to
4021            // start another process, but that could easily get us in
4022            // an infinite loop of restarting processes...
4023            Slog.w(TAG, "Exception thrown during bind!", e);
4024
4025            app.resetPackageList();
4026            app.unlinkDeathRecipient();
4027            startProcessLocked(app, "bind fail", processName);
4028            return false;
4029        }
4030
4031        // Remove this record from the list of starting applications.
4032        mPersistentStartingProcesses.remove(app);
4033        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4034                "Attach application locked removing on hold: " + app);
4035        mProcessesOnHold.remove(app);
4036
4037        boolean badApp = false;
4038        boolean didSomething = false;
4039
4040        // See if the top visible activity is waiting to run in this process...
4041        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4042        if (hr != null && normalMode) {
4043            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4044                    && processName.equals(hr.processName)) {
4045                try {
4046                    if (mHeadless) {
4047                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4048                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4049                        didSomething = true;
4050                    }
4051                } catch (Exception e) {
4052                    Slog.w(TAG, "Exception in new application when starting activity "
4053                          + hr.intent.getComponent().flattenToShortString(), e);
4054                    badApp = true;
4055                }
4056            } else {
4057                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4058            }
4059        }
4060
4061        // Find any services that should be running in this process...
4062        if (!badApp) {
4063            try {
4064                didSomething |= mServices.attachApplicationLocked(app, processName);
4065            } catch (Exception e) {
4066                badApp = true;
4067            }
4068        }
4069
4070        // Check if a next-broadcast receiver is in this process...
4071        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4072            try {
4073                didSomething = sendPendingBroadcastsLocked(app);
4074            } catch (Exception e) {
4075                // If the app died trying to launch the receiver we declare it 'bad'
4076                badApp = true;
4077            }
4078        }
4079
4080        // Check whether the next backup agent is in this process...
4081        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4082            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4083            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4084            try {
4085                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4086                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4087                        mBackupTarget.backupMode);
4088            } catch (Exception e) {
4089                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4090                e.printStackTrace();
4091            }
4092        }
4093
4094        if (badApp) {
4095            // todo: Also need to kill application to deal with all
4096            // kinds of exceptions.
4097            handleAppDiedLocked(app, false, true);
4098            return false;
4099        }
4100
4101        if (!didSomething) {
4102            updateOomAdjLocked();
4103        }
4104
4105        return true;
4106    }
4107
4108    public final void attachApplication(IApplicationThread thread) {
4109        synchronized (this) {
4110            int callingPid = Binder.getCallingPid();
4111            final long origId = Binder.clearCallingIdentity();
4112            attachApplicationLocked(thread, callingPid);
4113            Binder.restoreCallingIdentity(origId);
4114        }
4115    }
4116
4117    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4118        final long origId = Binder.clearCallingIdentity();
4119        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4120        if (stopProfiling) {
4121            synchronized (this) {
4122                if (mProfileProc == r.app) {
4123                    if (mProfileFd != null) {
4124                        try {
4125                            mProfileFd.close();
4126                        } catch (IOException e) {
4127                        }
4128                        clearProfilerLocked();
4129                    }
4130                }
4131            }
4132        }
4133        Binder.restoreCallingIdentity(origId);
4134    }
4135
4136    void enableScreenAfterBoot() {
4137        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4138                SystemClock.uptimeMillis());
4139        mWindowManager.enableScreenAfterBoot();
4140
4141        synchronized (this) {
4142            updateEventDispatchingLocked();
4143        }
4144    }
4145
4146    public void showBootMessage(final CharSequence msg, final boolean always) {
4147        enforceNotIsolatedCaller("showBootMessage");
4148        mWindowManager.showBootMessage(msg, always);
4149    }
4150
4151    public void dismissKeyguardOnNextActivity() {
4152        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4153        final long token = Binder.clearCallingIdentity();
4154        try {
4155            synchronized (this) {
4156                if (mLockScreenShown) {
4157                    mLockScreenShown = false;
4158                    comeOutOfSleepIfNeededLocked();
4159                }
4160                mMainStack.dismissKeyguardOnNextActivityLocked();
4161            }
4162        } finally {
4163            Binder.restoreCallingIdentity(token);
4164        }
4165    }
4166
4167    final void finishBooting() {
4168        IntentFilter pkgFilter = new IntentFilter();
4169        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4170        pkgFilter.addDataScheme("package");
4171        mContext.registerReceiver(new BroadcastReceiver() {
4172            @Override
4173            public void onReceive(Context context, Intent intent) {
4174                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4175                if (pkgs != null) {
4176                    for (String pkg : pkgs) {
4177                        synchronized (ActivityManagerService.this) {
4178                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4179                                setResultCode(Activity.RESULT_OK);
4180                                return;
4181                            }
4182                        }
4183                    }
4184                }
4185            }
4186        }, pkgFilter);
4187
4188        IntentFilter userFilter = new IntentFilter();
4189        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4190        mContext.registerReceiver(new BroadcastReceiver() {
4191            @Override
4192            public void onReceive(Context context, Intent intent) {
4193                onUserRemoved(intent);
4194            }
4195        }, userFilter);
4196
4197        synchronized (this) {
4198            // Ensure that any processes we had put on hold are now started
4199            // up.
4200            final int NP = mProcessesOnHold.size();
4201            if (NP > 0) {
4202                ArrayList<ProcessRecord> procs =
4203                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4204                for (int ip=0; ip<NP; ip++) {
4205                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4206                            + procs.get(ip));
4207                    startProcessLocked(procs.get(ip), "on-hold", null);
4208                }
4209            }
4210
4211            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4212                // Start looking for apps that are abusing wake locks.
4213                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4214                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4215                // Tell anyone interested that we are done booting!
4216                SystemProperties.set("sys.boot_completed", "1");
4217                SystemProperties.set("dev.bootcomplete", "1");
4218                List<UserInfo> users = getUserManager().getUsers();
4219                for (UserInfo user : users) {
4220                    broadcastIntentLocked(null, null,
4221                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4222                            null, null, 0, null, null,
4223                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4224                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4225                }
4226            }
4227        }
4228    }
4229
4230    final void ensureBootCompleted() {
4231        boolean booting;
4232        boolean enableScreen;
4233        synchronized (this) {
4234            booting = mBooting;
4235            mBooting = false;
4236            enableScreen = !mBooted;
4237            mBooted = true;
4238        }
4239
4240        if (booting) {
4241            finishBooting();
4242        }
4243
4244        if (enableScreen) {
4245            enableScreenAfterBoot();
4246        }
4247    }
4248
4249    public final void activityPaused(IBinder token) {
4250        final long origId = Binder.clearCallingIdentity();
4251        mMainStack.activityPaused(token, false);
4252        Binder.restoreCallingIdentity(origId);
4253    }
4254
4255    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4256            CharSequence description) {
4257        if (localLOGV) Slog.v(
4258            TAG, "Activity stopped: token=" + token);
4259
4260        // Refuse possible leaked file descriptors
4261        if (icicle != null && icicle.hasFileDescriptors()) {
4262            throw new IllegalArgumentException("File descriptors passed in Bundle");
4263        }
4264
4265        ActivityRecord r = null;
4266
4267        final long origId = Binder.clearCallingIdentity();
4268
4269        synchronized (this) {
4270            r = mMainStack.isInStackLocked(token);
4271            if (r != null) {
4272                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4273            }
4274        }
4275
4276        if (r != null) {
4277            sendPendingThumbnail(r, null, null, null, false);
4278        }
4279
4280        trimApplications();
4281
4282        Binder.restoreCallingIdentity(origId);
4283    }
4284
4285    public final void activityDestroyed(IBinder token) {
4286        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4287        mMainStack.activityDestroyed(token);
4288    }
4289
4290    public String getCallingPackage(IBinder token) {
4291        synchronized (this) {
4292            ActivityRecord r = getCallingRecordLocked(token);
4293            return r != null && r.app != null ? r.info.packageName : null;
4294        }
4295    }
4296
4297    public ComponentName getCallingActivity(IBinder token) {
4298        synchronized (this) {
4299            ActivityRecord r = getCallingRecordLocked(token);
4300            return r != null ? r.intent.getComponent() : null;
4301        }
4302    }
4303
4304    private ActivityRecord getCallingRecordLocked(IBinder token) {
4305        ActivityRecord r = mMainStack.isInStackLocked(token);
4306        if (r == null) {
4307            return null;
4308        }
4309        return r.resultTo;
4310    }
4311
4312    public ComponentName getActivityClassForToken(IBinder token) {
4313        synchronized(this) {
4314            ActivityRecord r = mMainStack.isInStackLocked(token);
4315            if (r == null) {
4316                return null;
4317            }
4318            return r.intent.getComponent();
4319        }
4320    }
4321
4322    public String getPackageForToken(IBinder token) {
4323        synchronized(this) {
4324            ActivityRecord r = mMainStack.isInStackLocked(token);
4325            if (r == null) {
4326                return null;
4327            }
4328            return r.packageName;
4329        }
4330    }
4331
4332    public IIntentSender getIntentSender(int type,
4333            String packageName, IBinder token, String resultWho,
4334            int requestCode, Intent[] intents, String[] resolvedTypes,
4335            int flags, Bundle options) {
4336        enforceNotIsolatedCaller("getIntentSender");
4337        // Refuse possible leaked file descriptors
4338        if (intents != null) {
4339            if (intents.length < 1) {
4340                throw new IllegalArgumentException("Intents array length must be >= 1");
4341            }
4342            for (int i=0; i<intents.length; i++) {
4343                Intent intent = intents[i];
4344                if (intent != null) {
4345                    if (intent.hasFileDescriptors()) {
4346                        throw new IllegalArgumentException("File descriptors passed in Intent");
4347                    }
4348                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4349                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4350                        throw new IllegalArgumentException(
4351                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4352                    }
4353                    intents[i] = new Intent(intent);
4354                }
4355            }
4356            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4357                throw new IllegalArgumentException(
4358                        "Intent array length does not match resolvedTypes length");
4359            }
4360        }
4361        if (options != null) {
4362            if (options.hasFileDescriptors()) {
4363                throw new IllegalArgumentException("File descriptors passed in options");
4364            }
4365        }
4366
4367        synchronized(this) {
4368            int callingUid = Binder.getCallingUid();
4369            try {
4370                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4371                    int uid = AppGlobals.getPackageManager()
4372                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4373                    if (!UserHandle.isSameApp(callingUid, uid)) {
4374                        String msg = "Permission Denial: getIntentSender() from pid="
4375                            + Binder.getCallingPid()
4376                            + ", uid=" + Binder.getCallingUid()
4377                            + ", (need uid=" + uid + ")"
4378                            + " is not allowed to send as package " + packageName;
4379                        Slog.w(TAG, msg);
4380                        throw new SecurityException(msg);
4381                    }
4382                }
4383
4384                if (DEBUG_MU)
4385                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4386                            + Binder.getOrigCallingUid());
4387                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4388                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4389
4390            } catch (RemoteException e) {
4391                throw new SecurityException(e);
4392            }
4393        }
4394    }
4395
4396    IIntentSender getIntentSenderLocked(int type,
4397            String packageName, int callingUid, IBinder token, String resultWho,
4398            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4399            Bundle options) {
4400        if (DEBUG_MU)
4401            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4402        ActivityRecord activity = null;
4403        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4404            activity = mMainStack.isInStackLocked(token);
4405            if (activity == null) {
4406                return null;
4407            }
4408            if (activity.finishing) {
4409                return null;
4410            }
4411        }
4412
4413        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4414        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4415        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4416        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4417                |PendingIntent.FLAG_UPDATE_CURRENT);
4418
4419        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4420                type, packageName, activity, resultWho,
4421                requestCode, intents, resolvedTypes, flags, options);
4422        WeakReference<PendingIntentRecord> ref;
4423        ref = mIntentSenderRecords.get(key);
4424        PendingIntentRecord rec = ref != null ? ref.get() : null;
4425        if (rec != null) {
4426            if (!cancelCurrent) {
4427                if (updateCurrent) {
4428                    if (rec.key.requestIntent != null) {
4429                        rec.key.requestIntent.replaceExtras(intents != null ?
4430                                intents[intents.length - 1] : null);
4431                    }
4432                    if (intents != null) {
4433                        intents[intents.length-1] = rec.key.requestIntent;
4434                        rec.key.allIntents = intents;
4435                        rec.key.allResolvedTypes = resolvedTypes;
4436                    } else {
4437                        rec.key.allIntents = null;
4438                        rec.key.allResolvedTypes = null;
4439                    }
4440                }
4441                return rec;
4442            }
4443            rec.canceled = true;
4444            mIntentSenderRecords.remove(key);
4445        }
4446        if (noCreate) {
4447            return rec;
4448        }
4449        rec = new PendingIntentRecord(this, key, callingUid);
4450        mIntentSenderRecords.put(key, rec.ref);
4451        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4452            if (activity.pendingResults == null) {
4453                activity.pendingResults
4454                        = new HashSet<WeakReference<PendingIntentRecord>>();
4455            }
4456            activity.pendingResults.add(rec.ref);
4457        }
4458        return rec;
4459    }
4460
4461    public void cancelIntentSender(IIntentSender sender) {
4462        if (!(sender instanceof PendingIntentRecord)) {
4463            return;
4464        }
4465        synchronized(this) {
4466            PendingIntentRecord rec = (PendingIntentRecord)sender;
4467            try {
4468                int uid = AppGlobals.getPackageManager()
4469                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4470                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4471                    String msg = "Permission Denial: cancelIntentSender() from pid="
4472                        + Binder.getCallingPid()
4473                        + ", uid=" + Binder.getCallingUid()
4474                        + " is not allowed to cancel packges "
4475                        + rec.key.packageName;
4476                    Slog.w(TAG, msg);
4477                    throw new SecurityException(msg);
4478                }
4479            } catch (RemoteException e) {
4480                throw new SecurityException(e);
4481            }
4482            cancelIntentSenderLocked(rec, true);
4483        }
4484    }
4485
4486    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4487        rec.canceled = true;
4488        mIntentSenderRecords.remove(rec.key);
4489        if (cleanActivity && rec.key.activity != null) {
4490            rec.key.activity.pendingResults.remove(rec.ref);
4491        }
4492    }
4493
4494    public String getPackageForIntentSender(IIntentSender pendingResult) {
4495        if (!(pendingResult instanceof PendingIntentRecord)) {
4496            return null;
4497        }
4498        try {
4499            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4500            return res.key.packageName;
4501        } catch (ClassCastException e) {
4502        }
4503        return null;
4504    }
4505
4506    public int getUidForIntentSender(IIntentSender sender) {
4507        if (sender instanceof PendingIntentRecord) {
4508            try {
4509                PendingIntentRecord res = (PendingIntentRecord)sender;
4510                return res.uid;
4511            } catch (ClassCastException e) {
4512            }
4513        }
4514        return -1;
4515    }
4516
4517    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4518        if (!(pendingResult instanceof PendingIntentRecord)) {
4519            return false;
4520        }
4521        try {
4522            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4523            if (res.key.allIntents == null) {
4524                return false;
4525            }
4526            for (int i=0; i<res.key.allIntents.length; i++) {
4527                Intent intent = res.key.allIntents[i];
4528                if (intent.getPackage() != null && intent.getComponent() != null) {
4529                    return false;
4530                }
4531            }
4532            return true;
4533        } catch (ClassCastException e) {
4534        }
4535        return false;
4536    }
4537
4538    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4539        if (!(pendingResult instanceof PendingIntentRecord)) {
4540            return false;
4541        }
4542        try {
4543            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4544            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4545                return true;
4546            }
4547            return false;
4548        } catch (ClassCastException e) {
4549        }
4550        return false;
4551    }
4552
4553    public void setProcessLimit(int max) {
4554        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4555                "setProcessLimit()");
4556        synchronized (this) {
4557            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4558            mProcessLimitOverride = max;
4559        }
4560        trimApplications();
4561    }
4562
4563    public int getProcessLimit() {
4564        synchronized (this) {
4565            return mProcessLimitOverride;
4566        }
4567    }
4568
4569    void foregroundTokenDied(ForegroundToken token) {
4570        synchronized (ActivityManagerService.this) {
4571            synchronized (mPidsSelfLocked) {
4572                ForegroundToken cur
4573                    = mForegroundProcesses.get(token.pid);
4574                if (cur != token) {
4575                    return;
4576                }
4577                mForegroundProcesses.remove(token.pid);
4578                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4579                if (pr == null) {
4580                    return;
4581                }
4582                pr.forcingToForeground = null;
4583                pr.foregroundServices = false;
4584            }
4585            updateOomAdjLocked();
4586        }
4587    }
4588
4589    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4590        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4591                "setProcessForeground()");
4592        synchronized(this) {
4593            boolean changed = false;
4594
4595            synchronized (mPidsSelfLocked) {
4596                ProcessRecord pr = mPidsSelfLocked.get(pid);
4597                if (pr == null && isForeground) {
4598                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4599                    return;
4600                }
4601                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4602                if (oldToken != null) {
4603                    oldToken.token.unlinkToDeath(oldToken, 0);
4604                    mForegroundProcesses.remove(pid);
4605                    if (pr != null) {
4606                        pr.forcingToForeground = null;
4607                    }
4608                    changed = true;
4609                }
4610                if (isForeground && token != null) {
4611                    ForegroundToken newToken = new ForegroundToken() {
4612                        public void binderDied() {
4613                            foregroundTokenDied(this);
4614                        }
4615                    };
4616                    newToken.pid = pid;
4617                    newToken.token = token;
4618                    try {
4619                        token.linkToDeath(newToken, 0);
4620                        mForegroundProcesses.put(pid, newToken);
4621                        pr.forcingToForeground = token;
4622                        changed = true;
4623                    } catch (RemoteException e) {
4624                        // If the process died while doing this, we will later
4625                        // do the cleanup with the process death link.
4626                    }
4627                }
4628            }
4629
4630            if (changed) {
4631                updateOomAdjLocked();
4632            }
4633        }
4634    }
4635
4636    // =========================================================
4637    // PERMISSIONS
4638    // =========================================================
4639
4640    static class PermissionController extends IPermissionController.Stub {
4641        ActivityManagerService mActivityManagerService;
4642        PermissionController(ActivityManagerService activityManagerService) {
4643            mActivityManagerService = activityManagerService;
4644        }
4645
4646        public boolean checkPermission(String permission, int pid, int uid) {
4647            return mActivityManagerService.checkPermission(permission, pid,
4648                    uid) == PackageManager.PERMISSION_GRANTED;
4649        }
4650    }
4651
4652    /**
4653     * This can be called with or without the global lock held.
4654     */
4655    int checkComponentPermission(String permission, int pid, int uid,
4656            int owningUid, boolean exported) {
4657        // We might be performing an operation on behalf of an indirect binder
4658        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4659        // client identity accordingly before proceeding.
4660        Identity tlsIdentity = sCallerIdentity.get();
4661        if (tlsIdentity != null) {
4662            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4663                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4664            uid = tlsIdentity.uid;
4665            pid = tlsIdentity.pid;
4666        }
4667
4668        if (pid == MY_PID) {
4669            return PackageManager.PERMISSION_GRANTED;
4670        }
4671
4672        return ActivityManager.checkComponentPermission(permission, uid,
4673                owningUid, exported);
4674    }
4675
4676    /**
4677     * As the only public entry point for permissions checking, this method
4678     * can enforce the semantic that requesting a check on a null global
4679     * permission is automatically denied.  (Internally a null permission
4680     * string is used when calling {@link #checkComponentPermission} in cases
4681     * when only uid-based security is needed.)
4682     *
4683     * This can be called with or without the global lock held.
4684     */
4685    public int checkPermission(String permission, int pid, int uid) {
4686        if (permission == null) {
4687            return PackageManager.PERMISSION_DENIED;
4688        }
4689        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4690    }
4691
4692    /**
4693     * Binder IPC calls go through the public entry point.
4694     * This can be called with or without the global lock held.
4695     */
4696    int checkCallingPermission(String permission) {
4697        return checkPermission(permission,
4698                Binder.getCallingPid(),
4699                UserHandle.getAppId(Binder.getCallingUid()));
4700    }
4701
4702    /**
4703     * This can be called with or without the global lock held.
4704     */
4705    void enforceCallingPermission(String permission, String func) {
4706        if (checkCallingPermission(permission)
4707                == PackageManager.PERMISSION_GRANTED) {
4708            return;
4709        }
4710
4711        String msg = "Permission Denial: " + func + " from pid="
4712                + Binder.getCallingPid()
4713                + ", uid=" + Binder.getCallingUid()
4714                + " requires " + permission;
4715        Slog.w(TAG, msg);
4716        throw new SecurityException(msg);
4717    }
4718
4719    /**
4720     * Determine if UID is holding permissions required to access {@link Uri} in
4721     * the given {@link ProviderInfo}. Final permission checking is always done
4722     * in {@link ContentProvider}.
4723     */
4724    private final boolean checkHoldingPermissionsLocked(
4725            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4726        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4727                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4728
4729        if (pi.applicationInfo.uid == uid) {
4730            return true;
4731        } else if (!pi.exported) {
4732            return false;
4733        }
4734
4735        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4736        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4737        try {
4738            // check if target holds top-level <provider> permissions
4739            if (!readMet && pi.readPermission != null
4740                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4741                readMet = true;
4742            }
4743            if (!writeMet && pi.writePermission != null
4744                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4745                writeMet = true;
4746            }
4747
4748            // track if unprotected read/write is allowed; any denied
4749            // <path-permission> below removes this ability
4750            boolean allowDefaultRead = pi.readPermission == null;
4751            boolean allowDefaultWrite = pi.writePermission == null;
4752
4753            // check if target holds any <path-permission> that match uri
4754            final PathPermission[] pps = pi.pathPermissions;
4755            if (pps != null) {
4756                final String path = uri.getPath();
4757                int i = pps.length;
4758                while (i > 0 && (!readMet || !writeMet)) {
4759                    i--;
4760                    PathPermission pp = pps[i];
4761                    if (pp.match(path)) {
4762                        if (!readMet) {
4763                            final String pprperm = pp.getReadPermission();
4764                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4765                                    + pprperm + " for " + pp.getPath()
4766                                    + ": match=" + pp.match(path)
4767                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4768                            if (pprperm != null) {
4769                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4770                                    readMet = true;
4771                                } else {
4772                                    allowDefaultRead = false;
4773                                }
4774                            }
4775                        }
4776                        if (!writeMet) {
4777                            final String ppwperm = pp.getWritePermission();
4778                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4779                                    + ppwperm + " for " + pp.getPath()
4780                                    + ": match=" + pp.match(path)
4781                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4782                            if (ppwperm != null) {
4783                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4784                                    writeMet = true;
4785                                } else {
4786                                    allowDefaultWrite = false;
4787                                }
4788                            }
4789                        }
4790                    }
4791                }
4792            }
4793
4794            // grant unprotected <provider> read/write, if not blocked by
4795            // <path-permission> above
4796            if (allowDefaultRead) readMet = true;
4797            if (allowDefaultWrite) writeMet = true;
4798
4799        } catch (RemoteException e) {
4800            return false;
4801        }
4802
4803        return readMet && writeMet;
4804    }
4805
4806    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4807            int modeFlags) {
4808        // Root gets to do everything.
4809        if (uid == 0) {
4810            return true;
4811        }
4812        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4813        if (perms == null) return false;
4814        UriPermission perm = perms.get(uri);
4815        if (perm == null) return false;
4816        return (modeFlags&perm.modeFlags) == modeFlags;
4817    }
4818
4819    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4820        enforceNotIsolatedCaller("checkUriPermission");
4821
4822        // Another redirected-binder-call permissions check as in
4823        // {@link checkComponentPermission}.
4824        Identity tlsIdentity = sCallerIdentity.get();
4825        if (tlsIdentity != null) {
4826            uid = tlsIdentity.uid;
4827            pid = tlsIdentity.pid;
4828        }
4829
4830        uid = UserHandle.getAppId(uid);
4831        // Our own process gets to do everything.
4832        if (pid == MY_PID) {
4833            return PackageManager.PERMISSION_GRANTED;
4834        }
4835        synchronized(this) {
4836            return checkUriPermissionLocked(uri, uid, modeFlags)
4837                    ? PackageManager.PERMISSION_GRANTED
4838                    : PackageManager.PERMISSION_DENIED;
4839        }
4840    }
4841
4842    /**
4843     * Check if the targetPkg can be granted permission to access uri by
4844     * the callingUid using the given modeFlags.  Throws a security exception
4845     * if callingUid is not allowed to do this.  Returns the uid of the target
4846     * if the URI permission grant should be performed; returns -1 if it is not
4847     * needed (for example targetPkg already has permission to access the URI).
4848     * If you already know the uid of the target, you can supply it in
4849     * lastTargetUid else set that to -1.
4850     */
4851    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4852            Uri uri, int modeFlags, int lastTargetUid) {
4853        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4854                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4855        if (modeFlags == 0) {
4856            return -1;
4857        }
4858
4859        if (targetPkg != null) {
4860            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4861                    "Checking grant " + targetPkg + " permission to " + uri);
4862        }
4863
4864        final IPackageManager pm = AppGlobals.getPackageManager();
4865
4866        // If this is not a content: uri, we can't do anything with it.
4867        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4868            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4869                    "Can't grant URI permission for non-content URI: " + uri);
4870            return -1;
4871        }
4872
4873        String name = uri.getAuthority();
4874        ProviderInfo pi = null;
4875        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4876                UserHandle.getUserId(callingUid));
4877        if (cpr != null) {
4878            pi = cpr.info;
4879        } else {
4880            try {
4881                pi = pm.resolveContentProvider(name,
4882                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4883            } catch (RemoteException ex) {
4884            }
4885        }
4886        if (pi == null) {
4887            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4888            return -1;
4889        }
4890
4891        int targetUid = lastTargetUid;
4892        if (targetUid < 0 && targetPkg != null) {
4893            try {
4894                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4895                if (targetUid < 0) {
4896                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4897                            "Can't grant URI permission no uid for: " + targetPkg);
4898                    return -1;
4899                }
4900            } catch (RemoteException ex) {
4901                return -1;
4902            }
4903        }
4904
4905        if (targetUid >= 0) {
4906            // First...  does the target actually need this permission?
4907            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4908                // No need to grant the target this permission.
4909                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4910                        "Target " + targetPkg + " already has full permission to " + uri);
4911                return -1;
4912            }
4913        } else {
4914            // First...  there is no target package, so can anyone access it?
4915            boolean allowed = pi.exported;
4916            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4917                if (pi.readPermission != null) {
4918                    allowed = false;
4919                }
4920            }
4921            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4922                if (pi.writePermission != null) {
4923                    allowed = false;
4924                }
4925            }
4926            if (allowed) {
4927                return -1;
4928            }
4929        }
4930
4931        // Second...  is the provider allowing granting of URI permissions?
4932        if (!pi.grantUriPermissions) {
4933            throw new SecurityException("Provider " + pi.packageName
4934                    + "/" + pi.name
4935                    + " does not allow granting of Uri permissions (uri "
4936                    + uri + ")");
4937        }
4938        if (pi.uriPermissionPatterns != null) {
4939            final int N = pi.uriPermissionPatterns.length;
4940            boolean allowed = false;
4941            for (int i=0; i<N; i++) {
4942                if (pi.uriPermissionPatterns[i] != null
4943                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4944                    allowed = true;
4945                    break;
4946                }
4947            }
4948            if (!allowed) {
4949                throw new SecurityException("Provider " + pi.packageName
4950                        + "/" + pi.name
4951                        + " does not allow granting of permission to path of Uri "
4952                        + uri);
4953            }
4954        }
4955
4956        // Third...  does the caller itself have permission to access
4957        // this uri?
4958        if (callingUid != Process.myUid()) {
4959            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4960                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4961                    throw new SecurityException("Uid " + callingUid
4962                            + " does not have permission to uri " + uri);
4963                }
4964            }
4965        }
4966
4967        return targetUid;
4968    }
4969
4970    public int checkGrantUriPermission(int callingUid, String targetPkg,
4971            Uri uri, int modeFlags) {
4972        enforceNotIsolatedCaller("checkGrantUriPermission");
4973        synchronized(this) {
4974            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4975        }
4976    }
4977
4978    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4979            Uri uri, int modeFlags, UriPermissionOwner owner) {
4980        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4981                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4982        if (modeFlags == 0) {
4983            return;
4984        }
4985
4986        // So here we are: the caller has the assumed permission
4987        // to the uri, and the target doesn't.  Let's now give this to
4988        // the target.
4989
4990        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4991                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4992
4993        HashMap<Uri, UriPermission> targetUris
4994                = mGrantedUriPermissions.get(targetUid);
4995        if (targetUris == null) {
4996            targetUris = new HashMap<Uri, UriPermission>();
4997            mGrantedUriPermissions.put(targetUid, targetUris);
4998        }
4999
5000        UriPermission perm = targetUris.get(uri);
5001        if (perm == null) {
5002            perm = new UriPermission(targetUid, uri);
5003            targetUris.put(uri, perm);
5004        }
5005
5006        perm.modeFlags |= modeFlags;
5007        if (owner == null) {
5008            perm.globalModeFlags |= modeFlags;
5009        } else {
5010            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5011                 perm.readOwners.add(owner);
5012                 owner.addReadPermission(perm);
5013            }
5014            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5015                 perm.writeOwners.add(owner);
5016                 owner.addWritePermission(perm);
5017            }
5018        }
5019    }
5020
5021    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5022            int modeFlags, UriPermissionOwner owner) {
5023        if (targetPkg == null) {
5024            throw new NullPointerException("targetPkg");
5025        }
5026
5027        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5028        if (targetUid < 0) {
5029            return;
5030        }
5031
5032        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5033    }
5034
5035    static class NeededUriGrants extends ArrayList<Uri> {
5036        final String targetPkg;
5037        final int targetUid;
5038        final int flags;
5039
5040        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5041            targetPkg = _targetPkg;
5042            targetUid = _targetUid;
5043            flags = _flags;
5044        }
5045    }
5046
5047    /**
5048     * Like checkGrantUriPermissionLocked, but takes an Intent.
5049     */
5050    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5051            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5052        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5053                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5054                + " clip=" + (intent != null ? intent.getClipData() : null)
5055                + " from " + intent + "; flags=0x"
5056                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5057
5058        if (targetPkg == null) {
5059            throw new NullPointerException("targetPkg");
5060        }
5061
5062        if (intent == null) {
5063            return null;
5064        }
5065        Uri data = intent.getData();
5066        ClipData clip = intent.getClipData();
5067        if (data == null && clip == null) {
5068            return null;
5069        }
5070        if (data != null) {
5071            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5072                mode, needed != null ? needed.targetUid : -1);
5073            if (target > 0) {
5074                if (needed == null) {
5075                    needed = new NeededUriGrants(targetPkg, target, mode);
5076                }
5077                needed.add(data);
5078            }
5079        }
5080        if (clip != null) {
5081            for (int i=0; i<clip.getItemCount(); i++) {
5082                Uri uri = clip.getItemAt(i).getUri();
5083                if (uri != null) {
5084                    int target = -1;
5085                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5086                            mode, needed != null ? needed.targetUid : -1);
5087                    if (target > 0) {
5088                        if (needed == null) {
5089                            needed = new NeededUriGrants(targetPkg, target, mode);
5090                        }
5091                        needed.add(uri);
5092                    }
5093                } else {
5094                    Intent clipIntent = clip.getItemAt(i).getIntent();
5095                    if (clipIntent != null) {
5096                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5097                                callingUid, targetPkg, clipIntent, mode, needed);
5098                        if (newNeeded != null) {
5099                            needed = newNeeded;
5100                        }
5101                    }
5102                }
5103            }
5104        }
5105
5106        return needed;
5107    }
5108
5109    /**
5110     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5111     */
5112    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5113            UriPermissionOwner owner) {
5114        if (needed != null) {
5115            for (int i=0; i<needed.size(); i++) {
5116                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5117                        needed.get(i), needed.flags, owner);
5118            }
5119        }
5120    }
5121
5122    void grantUriPermissionFromIntentLocked(int callingUid,
5123            String targetPkg, Intent intent, UriPermissionOwner owner) {
5124        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5125                intent, intent != null ? intent.getFlags() : 0, null);
5126        if (needed == null) {
5127            return;
5128        }
5129
5130        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5131    }
5132
5133    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5134            Uri uri, int modeFlags) {
5135        enforceNotIsolatedCaller("grantUriPermission");
5136        synchronized(this) {
5137            final ProcessRecord r = getRecordForAppLocked(caller);
5138            if (r == null) {
5139                throw new SecurityException("Unable to find app for caller "
5140                        + caller
5141                        + " when granting permission to uri " + uri);
5142            }
5143            if (targetPkg == null) {
5144                throw new IllegalArgumentException("null target");
5145            }
5146            if (uri == null) {
5147                throw new IllegalArgumentException("null uri");
5148            }
5149
5150            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5151                    null);
5152        }
5153    }
5154
5155    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5156        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5157                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5158            HashMap<Uri, UriPermission> perms
5159                    = mGrantedUriPermissions.get(perm.uid);
5160            if (perms != null) {
5161                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5162                        "Removing " + perm.uid + " permission to " + perm.uri);
5163                perms.remove(perm.uri);
5164                if (perms.size() == 0) {
5165                    mGrantedUriPermissions.remove(perm.uid);
5166                }
5167            }
5168        }
5169    }
5170
5171    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5172            int modeFlags) {
5173        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5174                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5175        if (modeFlags == 0) {
5176            return;
5177        }
5178
5179        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5180                "Revoking all granted permissions to " + uri);
5181
5182        final IPackageManager pm = AppGlobals.getPackageManager();
5183
5184        final String authority = uri.getAuthority();
5185        ProviderInfo pi = null;
5186        int userId = UserHandle.getUserId(callingUid);
5187        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5188        if (cpr != null) {
5189            pi = cpr.info;
5190        } else {
5191            try {
5192                pi = pm.resolveContentProvider(authority,
5193                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5194            } catch (RemoteException ex) {
5195            }
5196        }
5197        if (pi == null) {
5198            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5199            return;
5200        }
5201
5202        // Does the caller have this permission on the URI?
5203        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5204            // Right now, if you are not the original owner of the permission,
5205            // you are not allowed to revoke it.
5206            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5207                throw new SecurityException("Uid " + callingUid
5208                        + " does not have permission to uri " + uri);
5209            //}
5210        }
5211
5212        // Go through all of the permissions and remove any that match.
5213        final List<String> SEGMENTS = uri.getPathSegments();
5214        if (SEGMENTS != null) {
5215            final int NS = SEGMENTS.size();
5216            int N = mGrantedUriPermissions.size();
5217            for (int i=0; i<N; i++) {
5218                HashMap<Uri, UriPermission> perms
5219                        = mGrantedUriPermissions.valueAt(i);
5220                Iterator<UriPermission> it = perms.values().iterator();
5221            toploop:
5222                while (it.hasNext()) {
5223                    UriPermission perm = it.next();
5224                    Uri targetUri = perm.uri;
5225                    if (!authority.equals(targetUri.getAuthority())) {
5226                        continue;
5227                    }
5228                    List<String> targetSegments = targetUri.getPathSegments();
5229                    if (targetSegments == null) {
5230                        continue;
5231                    }
5232                    if (targetSegments.size() < NS) {
5233                        continue;
5234                    }
5235                    for (int j=0; j<NS; j++) {
5236                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5237                            continue toploop;
5238                        }
5239                    }
5240                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5241                            "Revoking " + perm.uid + " permission to " + perm.uri);
5242                    perm.clearModes(modeFlags);
5243                    if (perm.modeFlags == 0) {
5244                        it.remove();
5245                    }
5246                }
5247                if (perms.size() == 0) {
5248                    mGrantedUriPermissions.remove(
5249                            mGrantedUriPermissions.keyAt(i));
5250                    N--;
5251                    i--;
5252                }
5253            }
5254        }
5255    }
5256
5257    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5258            int modeFlags) {
5259        enforceNotIsolatedCaller("revokeUriPermission");
5260        synchronized(this) {
5261            final ProcessRecord r = getRecordForAppLocked(caller);
5262            if (r == null) {
5263                throw new SecurityException("Unable to find app for caller "
5264                        + caller
5265                        + " when revoking permission to uri " + uri);
5266            }
5267            if (uri == null) {
5268                Slog.w(TAG, "revokeUriPermission: null uri");
5269                return;
5270            }
5271
5272            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5273                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5274            if (modeFlags == 0) {
5275                return;
5276            }
5277
5278            final IPackageManager pm = AppGlobals.getPackageManager();
5279
5280            final String authority = uri.getAuthority();
5281            ProviderInfo pi = null;
5282            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5283            if (cpr != null) {
5284                pi = cpr.info;
5285            } else {
5286                try {
5287                    pi = pm.resolveContentProvider(authority,
5288                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5289                } catch (RemoteException ex) {
5290                }
5291            }
5292            if (pi == null) {
5293                Slog.w(TAG, "No content provider found for permission revoke: "
5294                        + uri.toSafeString());
5295                return;
5296            }
5297
5298            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5299        }
5300    }
5301
5302    @Override
5303    public IBinder newUriPermissionOwner(String name) {
5304        enforceNotIsolatedCaller("newUriPermissionOwner");
5305        synchronized(this) {
5306            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5307            return owner.getExternalTokenLocked();
5308        }
5309    }
5310
5311    @Override
5312    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5313            Uri uri, int modeFlags) {
5314        synchronized(this) {
5315            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5316            if (owner == null) {
5317                throw new IllegalArgumentException("Unknown owner: " + token);
5318            }
5319            if (fromUid != Binder.getCallingUid()) {
5320                if (Binder.getCallingUid() != Process.myUid()) {
5321                    // Only system code can grant URI permissions on behalf
5322                    // of other users.
5323                    throw new SecurityException("nice try");
5324                }
5325            }
5326            if (targetPkg == null) {
5327                throw new IllegalArgumentException("null target");
5328            }
5329            if (uri == null) {
5330                throw new IllegalArgumentException("null uri");
5331            }
5332
5333            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5334        }
5335    }
5336
5337    @Override
5338    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5339        synchronized(this) {
5340            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5341            if (owner == null) {
5342                throw new IllegalArgumentException("Unknown owner: " + token);
5343            }
5344
5345            if (uri == null) {
5346                owner.removeUriPermissionsLocked(mode);
5347            } else {
5348                owner.removeUriPermissionLocked(uri, mode);
5349            }
5350        }
5351    }
5352
5353    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5354        synchronized (this) {
5355            ProcessRecord app =
5356                who != null ? getRecordForAppLocked(who) : null;
5357            if (app == null) return;
5358
5359            Message msg = Message.obtain();
5360            msg.what = WAIT_FOR_DEBUGGER_MSG;
5361            msg.obj = app;
5362            msg.arg1 = waiting ? 1 : 0;
5363            mHandler.sendMessage(msg);
5364        }
5365    }
5366
5367    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5368        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5369        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5370        outInfo.availMem = Process.getFreeMemory();
5371        outInfo.totalMem = Process.getTotalMemory();
5372        outInfo.threshold = homeAppMem;
5373        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5374        outInfo.hiddenAppThreshold = hiddenAppMem;
5375        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5376                ProcessList.SERVICE_ADJ);
5377        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5378                ProcessList.VISIBLE_APP_ADJ);
5379        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5380                ProcessList.FOREGROUND_APP_ADJ);
5381    }
5382
5383    // =========================================================
5384    // TASK MANAGEMENT
5385    // =========================================================
5386
5387    public List getTasks(int maxNum, int flags,
5388                         IThumbnailReceiver receiver) {
5389        ArrayList list = new ArrayList();
5390
5391        PendingThumbnailsRecord pending = null;
5392        IApplicationThread topThumbnail = null;
5393        ActivityRecord topRecord = null;
5394
5395        synchronized(this) {
5396            if (localLOGV) Slog.v(
5397                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5398                + ", receiver=" + receiver);
5399
5400            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5401                    != PackageManager.PERMISSION_GRANTED) {
5402                if (receiver != null) {
5403                    // If the caller wants to wait for pending thumbnails,
5404                    // it ain't gonna get them.
5405                    try {
5406                        receiver.finished();
5407                    } catch (RemoteException ex) {
5408                    }
5409                }
5410                String msg = "Permission Denial: getTasks() from pid="
5411                        + Binder.getCallingPid()
5412                        + ", uid=" + Binder.getCallingUid()
5413                        + " requires " + android.Manifest.permission.GET_TASKS;
5414                Slog.w(TAG, msg);
5415                throw new SecurityException(msg);
5416            }
5417
5418            int pos = mMainStack.mHistory.size()-1;
5419            ActivityRecord next =
5420                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5421            ActivityRecord top = null;
5422            TaskRecord curTask = null;
5423            int numActivities = 0;
5424            int numRunning = 0;
5425            while (pos >= 0 && maxNum > 0) {
5426                final ActivityRecord r = next;
5427                pos--;
5428                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5429
5430                // Initialize state for next task if needed.
5431                if (top == null ||
5432                        (top.state == ActivityState.INITIALIZING
5433                            && top.task == r.task)) {
5434                    top = r;
5435                    curTask = r.task;
5436                    numActivities = numRunning = 0;
5437                }
5438
5439                // Add 'r' into the current task.
5440                numActivities++;
5441                if (r.app != null && r.app.thread != null) {
5442                    numRunning++;
5443                }
5444
5445                if (localLOGV) Slog.v(
5446                    TAG, r.intent.getComponent().flattenToShortString()
5447                    + ": task=" + r.task);
5448
5449                // If the next one is a different task, generate a new
5450                // TaskInfo entry for what we have.
5451                if (next == null || next.task != curTask) {
5452                    ActivityManager.RunningTaskInfo ci
5453                            = new ActivityManager.RunningTaskInfo();
5454                    ci.id = curTask.taskId;
5455                    ci.baseActivity = r.intent.getComponent();
5456                    ci.topActivity = top.intent.getComponent();
5457                    if (top.thumbHolder != null) {
5458                        ci.description = top.thumbHolder.lastDescription;
5459                    }
5460                    ci.numActivities = numActivities;
5461                    ci.numRunning = numRunning;
5462                    //System.out.println(
5463                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5464                    if (ci.thumbnail == null && receiver != null) {
5465                        if (localLOGV) Slog.v(
5466                            TAG, "State=" + top.state + "Idle=" + top.idle
5467                            + " app=" + top.app
5468                            + " thr=" + (top.app != null ? top.app.thread : null));
5469                        if (top.state == ActivityState.RESUMED
5470                                || top.state == ActivityState.PAUSING) {
5471                            if (top.idle && top.app != null
5472                                && top.app.thread != null) {
5473                                topRecord = top;
5474                                topThumbnail = top.app.thread;
5475                            } else {
5476                                top.thumbnailNeeded = true;
5477                            }
5478                        }
5479                        if (pending == null) {
5480                            pending = new PendingThumbnailsRecord(receiver);
5481                        }
5482                        pending.pendingRecords.add(top);
5483                    }
5484                    list.add(ci);
5485                    maxNum--;
5486                    top = null;
5487                }
5488            }
5489
5490            if (pending != null) {
5491                mPendingThumbnails.add(pending);
5492            }
5493        }
5494
5495        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5496
5497        if (topThumbnail != null) {
5498            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5499            try {
5500                topThumbnail.requestThumbnail(topRecord.appToken);
5501            } catch (Exception e) {
5502                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5503                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5504            }
5505        }
5506
5507        if (pending == null && receiver != null) {
5508            // In this case all thumbnails were available and the client
5509            // is being asked to be told when the remaining ones come in...
5510            // which is unusually, since the top-most currently running
5511            // activity should never have a canned thumbnail!  Oh well.
5512            try {
5513                receiver.finished();
5514            } catch (RemoteException ex) {
5515            }
5516        }
5517
5518        return list;
5519    }
5520
5521    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5522            int flags, int userId) {
5523        final int callingUid = Binder.getCallingUid();
5524        if (userId != UserHandle.getCallingUserId()) {
5525            // Check if the caller is holding permissions for cross-user requests.
5526            if (checkComponentPermission(
5527                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5528                    Binder.getCallingPid(), callingUid, -1, true)
5529                    != PackageManager.PERMISSION_GRANTED) {
5530                String msg = "Permission Denial: "
5531                        + "Request to get recent tasks for user " + userId
5532                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5533                        + "; this requires "
5534                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5535                Slog.w(TAG, msg);
5536                throw new SecurityException(msg);
5537            } else {
5538                if (userId == UserHandle.USER_CURRENT) {
5539                    userId = mCurrentUserId;
5540                }
5541            }
5542        }
5543
5544        synchronized (this) {
5545            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5546                    "getRecentTasks()");
5547            final boolean detailed = checkCallingPermission(
5548                    android.Manifest.permission.GET_DETAILED_TASKS)
5549                    == PackageManager.PERMISSION_GRANTED;
5550
5551            IPackageManager pm = AppGlobals.getPackageManager();
5552
5553            final int N = mRecentTasks.size();
5554            ArrayList<ActivityManager.RecentTaskInfo> res
5555                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5556                            maxNum < N ? maxNum : N);
5557            for (int i=0; i<N && maxNum > 0; i++) {
5558                TaskRecord tr = mRecentTasks.get(i);
5559                // Only add calling user's recent tasks
5560                if (tr.userId != userId) continue;
5561                // Return the entry if desired by the caller.  We always return
5562                // the first entry, because callers always expect this to be the
5563                // foreground app.  We may filter others if the caller has
5564                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5565                // we should exclude the entry.
5566
5567                if (i == 0
5568                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5569                        || (tr.intent == null)
5570                        || ((tr.intent.getFlags()
5571                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5572                    ActivityManager.RecentTaskInfo rti
5573                            = new ActivityManager.RecentTaskInfo();
5574                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5575                    rti.persistentId = tr.taskId;
5576                    rti.baseIntent = new Intent(
5577                            tr.intent != null ? tr.intent : tr.affinityIntent);
5578                    if (!detailed) {
5579                        rti.baseIntent.replaceExtras((Bundle)null);
5580                    }
5581                    rti.origActivity = tr.origActivity;
5582                    rti.description = tr.lastDescription;
5583
5584                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5585                        // Check whether this activity is currently available.
5586                        try {
5587                            if (rti.origActivity != null) {
5588                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5589                                        == null) {
5590                                    continue;
5591                                }
5592                            } else if (rti.baseIntent != null) {
5593                                if (pm.queryIntentActivities(rti.baseIntent,
5594                                        null, 0, userId) == null) {
5595                                    continue;
5596                                }
5597                            }
5598                        } catch (RemoteException e) {
5599                            // Will never happen.
5600                        }
5601                    }
5602
5603                    res.add(rti);
5604                    maxNum--;
5605                }
5606            }
5607            return res;
5608        }
5609    }
5610
5611    private TaskRecord taskForIdLocked(int id) {
5612        final int N = mRecentTasks.size();
5613        for (int i=0; i<N; i++) {
5614            TaskRecord tr = mRecentTasks.get(i);
5615            if (tr.taskId == id) {
5616                return tr;
5617            }
5618        }
5619        return null;
5620    }
5621
5622    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5623        synchronized (this) {
5624            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5625                    "getTaskThumbnails()");
5626            TaskRecord tr = taskForIdLocked(id);
5627            if (tr != null) {
5628                return mMainStack.getTaskThumbnailsLocked(tr);
5629            }
5630        }
5631        return null;
5632    }
5633
5634    public boolean removeSubTask(int taskId, int subTaskIndex) {
5635        synchronized (this) {
5636            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5637                    "removeSubTask()");
5638            long ident = Binder.clearCallingIdentity();
5639            try {
5640                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5641                        true) != null;
5642            } finally {
5643                Binder.restoreCallingIdentity(ident);
5644            }
5645        }
5646    }
5647
5648    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5649        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5650        Intent baseIntent = new Intent(
5651                tr.intent != null ? tr.intent : tr.affinityIntent);
5652        ComponentName component = baseIntent.getComponent();
5653        if (component == null) {
5654            Slog.w(TAG, "Now component for base intent of task: " + tr);
5655            return;
5656        }
5657
5658        // Find any running services associated with this app.
5659        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5660
5661        if (killProcesses) {
5662            // Find any running processes associated with this app.
5663            final String pkg = component.getPackageName();
5664            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5665            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5666            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5667                for (int i=0; i<uids.size(); i++) {
5668                    ProcessRecord proc = uids.valueAt(i);
5669                    if (proc.userId != tr.userId) {
5670                        continue;
5671                    }
5672                    if (!proc.pkgList.contains(pkg)) {
5673                        continue;
5674                    }
5675                    procs.add(proc);
5676                }
5677            }
5678
5679            // Kill the running processes.
5680            for (int i=0; i<procs.size(); i++) {
5681                ProcessRecord pr = procs.get(i);
5682                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5683                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5684                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5685                            pr.processName, pr.setAdj, "remove task");
5686                    pr.killedBackground = true;
5687                    Process.killProcessQuiet(pr.pid);
5688                } else {
5689                    pr.waitingToKill = "remove task";
5690                }
5691            }
5692        }
5693    }
5694
5695    public boolean removeTask(int taskId, int flags) {
5696        synchronized (this) {
5697            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5698                    "removeTask()");
5699            long ident = Binder.clearCallingIdentity();
5700            try {
5701                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5702                        false);
5703                if (r != null) {
5704                    mRecentTasks.remove(r.task);
5705                    cleanUpRemovedTaskLocked(r.task, flags);
5706                    return true;
5707                } else {
5708                    TaskRecord tr = null;
5709                    int i=0;
5710                    while (i < mRecentTasks.size()) {
5711                        TaskRecord t = mRecentTasks.get(i);
5712                        if (t.taskId == taskId) {
5713                            tr = t;
5714                            break;
5715                        }
5716                        i++;
5717                    }
5718                    if (tr != null) {
5719                        if (tr.numActivities <= 0) {
5720                            // Caller is just removing a recent task that is
5721                            // not actively running.  That is easy!
5722                            mRecentTasks.remove(i);
5723                            cleanUpRemovedTaskLocked(tr, flags);
5724                            return true;
5725                        } else {
5726                            Slog.w(TAG, "removeTask: task " + taskId
5727                                    + " does not have activities to remove, "
5728                                    + " but numActivities=" + tr.numActivities
5729                                    + ": " + tr);
5730                        }
5731                    }
5732                }
5733            } finally {
5734                Binder.restoreCallingIdentity(ident);
5735            }
5736        }
5737        return false;
5738    }
5739
5740    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5741        int j;
5742        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5743        TaskRecord jt = startTask;
5744
5745        // First look backwards
5746        for (j=startIndex-1; j>=0; j--) {
5747            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5748            if (r.task != jt) {
5749                jt = r.task;
5750                if (affinity.equals(jt.affinity)) {
5751                    return j;
5752                }
5753            }
5754        }
5755
5756        // Now look forwards
5757        final int N = mMainStack.mHistory.size();
5758        jt = startTask;
5759        for (j=startIndex+1; j<N; j++) {
5760            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5761            if (r.task != jt) {
5762                if (affinity.equals(jt.affinity)) {
5763                    return j;
5764                }
5765                jt = r.task;
5766            }
5767        }
5768
5769        // Might it be at the top?
5770        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5771            return N-1;
5772        }
5773
5774        return -1;
5775    }
5776
5777    /**
5778     * TODO: Add mController hook
5779     */
5780    public void moveTaskToFront(int task, int flags, Bundle options) {
5781        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5782                "moveTaskToFront()");
5783
5784        synchronized(this) {
5785            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5786                    Binder.getCallingUid(), "Task to front")) {
5787                ActivityOptions.abort(options);
5788                return;
5789            }
5790            final long origId = Binder.clearCallingIdentity();
5791            try {
5792                TaskRecord tr = taskForIdLocked(task);
5793                if (tr != null) {
5794                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5795                        mMainStack.mUserLeaving = true;
5796                    }
5797                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5798                        // Caller wants the home activity moved with it.  To accomplish this,
5799                        // we'll just move the home task to the top first.
5800                        mMainStack.moveHomeToFrontLocked();
5801                    }
5802                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5803                    return;
5804                }
5805                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5806                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5807                    if (hr.task.taskId == task) {
5808                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5809                            mMainStack.mUserLeaving = true;
5810                        }
5811                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5812                            // Caller wants the home activity moved with it.  To accomplish this,
5813                            // we'll just move the home task to the top first.
5814                            mMainStack.moveHomeToFrontLocked();
5815                        }
5816                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5817                        return;
5818                    }
5819                }
5820            } finally {
5821                Binder.restoreCallingIdentity(origId);
5822            }
5823            ActivityOptions.abort(options);
5824        }
5825    }
5826
5827    public void moveTaskToBack(int task) {
5828        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5829                "moveTaskToBack()");
5830
5831        synchronized(this) {
5832            if (mMainStack.mResumedActivity != null
5833                    && mMainStack.mResumedActivity.task.taskId == task) {
5834                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5835                        Binder.getCallingUid(), "Task to back")) {
5836                    return;
5837                }
5838            }
5839            final long origId = Binder.clearCallingIdentity();
5840            mMainStack.moveTaskToBackLocked(task, null);
5841            Binder.restoreCallingIdentity(origId);
5842        }
5843    }
5844
5845    /**
5846     * Moves an activity, and all of the other activities within the same task, to the bottom
5847     * of the history stack.  The activity's order within the task is unchanged.
5848     *
5849     * @param token A reference to the activity we wish to move
5850     * @param nonRoot If false then this only works if the activity is the root
5851     *                of a task; if true it will work for any activity in a task.
5852     * @return Returns true if the move completed, false if not.
5853     */
5854    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5855        enforceNotIsolatedCaller("moveActivityTaskToBack");
5856        synchronized(this) {
5857            final long origId = Binder.clearCallingIdentity();
5858            int taskId = getTaskForActivityLocked(token, !nonRoot);
5859            if (taskId >= 0) {
5860                return mMainStack.moveTaskToBackLocked(taskId, null);
5861            }
5862            Binder.restoreCallingIdentity(origId);
5863        }
5864        return false;
5865    }
5866
5867    public void moveTaskBackwards(int task) {
5868        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5869                "moveTaskBackwards()");
5870
5871        synchronized(this) {
5872            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5873                    Binder.getCallingUid(), "Task backwards")) {
5874                return;
5875            }
5876            final long origId = Binder.clearCallingIdentity();
5877            moveTaskBackwardsLocked(task);
5878            Binder.restoreCallingIdentity(origId);
5879        }
5880    }
5881
5882    private final void moveTaskBackwardsLocked(int task) {
5883        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5884    }
5885
5886    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5887        synchronized(this) {
5888            return getTaskForActivityLocked(token, onlyRoot);
5889        }
5890    }
5891
5892    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5893        final int N = mMainStack.mHistory.size();
5894        TaskRecord lastTask = null;
5895        for (int i=0; i<N; i++) {
5896            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5897            if (r.appToken == token) {
5898                if (!onlyRoot || lastTask != r.task) {
5899                    return r.task.taskId;
5900                }
5901                return -1;
5902            }
5903            lastTask = r.task;
5904        }
5905
5906        return -1;
5907    }
5908
5909    // =========================================================
5910    // THUMBNAILS
5911    // =========================================================
5912
5913    public void reportThumbnail(IBinder token,
5914            Bitmap thumbnail, CharSequence description) {
5915        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5916        final long origId = Binder.clearCallingIdentity();
5917        sendPendingThumbnail(null, token, thumbnail, description, true);
5918        Binder.restoreCallingIdentity(origId);
5919    }
5920
5921    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5922            Bitmap thumbnail, CharSequence description, boolean always) {
5923        TaskRecord task = null;
5924        ArrayList receivers = null;
5925
5926        //System.out.println("Send pending thumbnail: " + r);
5927
5928        synchronized(this) {
5929            if (r == null) {
5930                r = mMainStack.isInStackLocked(token);
5931                if (r == null) {
5932                    return;
5933                }
5934            }
5935            if (thumbnail == null && r.thumbHolder != null) {
5936                thumbnail = r.thumbHolder.lastThumbnail;
5937                description = r.thumbHolder.lastDescription;
5938            }
5939            if (thumbnail == null && !always) {
5940                // If there is no thumbnail, and this entry is not actually
5941                // going away, then abort for now and pick up the next
5942                // thumbnail we get.
5943                return;
5944            }
5945            task = r.task;
5946
5947            int N = mPendingThumbnails.size();
5948            int i=0;
5949            while (i<N) {
5950                PendingThumbnailsRecord pr =
5951                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5952                //System.out.println("Looking in " + pr.pendingRecords);
5953                if (pr.pendingRecords.remove(r)) {
5954                    if (receivers == null) {
5955                        receivers = new ArrayList();
5956                    }
5957                    receivers.add(pr);
5958                    if (pr.pendingRecords.size() == 0) {
5959                        pr.finished = true;
5960                        mPendingThumbnails.remove(i);
5961                        N--;
5962                        continue;
5963                    }
5964                }
5965                i++;
5966            }
5967        }
5968
5969        if (receivers != null) {
5970            final int N = receivers.size();
5971            for (int i=0; i<N; i++) {
5972                try {
5973                    PendingThumbnailsRecord pr =
5974                        (PendingThumbnailsRecord)receivers.get(i);
5975                    pr.receiver.newThumbnail(
5976                        task != null ? task.taskId : -1, thumbnail, description);
5977                    if (pr.finished) {
5978                        pr.receiver.finished();
5979                    }
5980                } catch (Exception e) {
5981                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5982                }
5983            }
5984        }
5985    }
5986
5987    // =========================================================
5988    // CONTENT PROVIDERS
5989    // =========================================================
5990
5991    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5992        List<ProviderInfo> providers = null;
5993        try {
5994            providers = AppGlobals.getPackageManager().
5995                queryContentProviders(app.processName, app.uid,
5996                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5997        } catch (RemoteException ex) {
5998        }
5999        if (DEBUG_MU)
6000            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6001        int userId = app.userId;
6002        if (providers != null) {
6003            int N = providers.size();
6004            for (int i=0; i<N; i++) {
6005                ProviderInfo cpi =
6006                    (ProviderInfo)providers.get(i);
6007                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6008                        cpi.name, cpi.flags);
6009                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6010                    // This is a singleton provider, but a user besides the
6011                    // default user is asking to initialize a process it runs
6012                    // in...  well, no, it doesn't actually run in this process,
6013                    // it runs in the process of the default user.  Get rid of it.
6014                    providers.remove(i);
6015                    N--;
6016                    continue;
6017                }
6018
6019                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6020                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6021                if (cpr == null) {
6022                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6023                    mProviderMap.putProviderByClass(comp, cpr);
6024                }
6025                if (DEBUG_MU)
6026                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6027                app.pubProviders.put(cpi.name, cpr);
6028                app.addPackage(cpi.applicationInfo.packageName);
6029                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6030            }
6031        }
6032        return providers;
6033    }
6034
6035    /**
6036     * Check if {@link ProcessRecord} has a possible chance at accessing the
6037     * given {@link ProviderInfo}. Final permission checking is always done
6038     * in {@link ContentProvider}.
6039     */
6040    private final String checkContentProviderPermissionLocked(
6041            ProviderInfo cpi, ProcessRecord r) {
6042        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6043        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6044        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6045                cpi.applicationInfo.uid, cpi.exported)
6046                == PackageManager.PERMISSION_GRANTED) {
6047            return null;
6048        }
6049        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6050                cpi.applicationInfo.uid, cpi.exported)
6051                == PackageManager.PERMISSION_GRANTED) {
6052            return null;
6053        }
6054
6055        PathPermission[] pps = cpi.pathPermissions;
6056        if (pps != null) {
6057            int i = pps.length;
6058            while (i > 0) {
6059                i--;
6060                PathPermission pp = pps[i];
6061                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6062                        cpi.applicationInfo.uid, cpi.exported)
6063                        == PackageManager.PERMISSION_GRANTED) {
6064                    return null;
6065                }
6066                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6067                        cpi.applicationInfo.uid, cpi.exported)
6068                        == PackageManager.PERMISSION_GRANTED) {
6069                    return null;
6070                }
6071            }
6072        }
6073
6074        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6075        if (perms != null) {
6076            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6077                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6078                    return null;
6079                }
6080            }
6081        }
6082
6083        String msg;
6084        if (!cpi.exported) {
6085            msg = "Permission Denial: opening provider " + cpi.name
6086                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6087                    + ", uid=" + callingUid + ") that is not exported from uid "
6088                    + cpi.applicationInfo.uid;
6089        } else {
6090            msg = "Permission Denial: opening provider " + cpi.name
6091                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6092                    + ", uid=" + callingUid + ") requires "
6093                    + cpi.readPermission + " or " + cpi.writePermission;
6094        }
6095        Slog.w(TAG, msg);
6096        return msg;
6097    }
6098
6099    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6100            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6101        if (r != null) {
6102            for (int i=0; i<r.conProviders.size(); i++) {
6103                ContentProviderConnection conn = r.conProviders.get(i);
6104                if (conn.provider == cpr) {
6105                    if (DEBUG_PROVIDER) Slog.v(TAG,
6106                            "Adding provider requested by "
6107                            + r.processName + " from process "
6108                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6109                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6110                    if (stable) {
6111                        conn.stableCount++;
6112                        conn.numStableIncs++;
6113                    } else {
6114                        conn.unstableCount++;
6115                        conn.numUnstableIncs++;
6116                    }
6117                    return conn;
6118                }
6119            }
6120            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6121            if (stable) {
6122                conn.stableCount = 1;
6123                conn.numStableIncs = 1;
6124            } else {
6125                conn.unstableCount = 1;
6126                conn.numUnstableIncs = 1;
6127            }
6128            cpr.connections.add(conn);
6129            r.conProviders.add(conn);
6130            return conn;
6131        }
6132        cpr.addExternalProcessHandleLocked(externalProcessToken);
6133        return null;
6134    }
6135
6136    boolean decProviderCountLocked(ContentProviderConnection conn,
6137            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6138        if (conn != null) {
6139            cpr = conn.provider;
6140            if (DEBUG_PROVIDER) Slog.v(TAG,
6141                    "Removing provider requested by "
6142                    + conn.client.processName + " from process "
6143                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6144                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6145            if (stable) {
6146                conn.stableCount--;
6147            } else {
6148                conn.unstableCount--;
6149            }
6150            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6151                cpr.connections.remove(conn);
6152                conn.client.conProviders.remove(conn);
6153                return true;
6154            }
6155            return false;
6156        }
6157        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6158        return false;
6159    }
6160
6161    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6162            String name, IBinder token, boolean stable) {
6163        ContentProviderRecord cpr;
6164        ContentProviderConnection conn = null;
6165        ProviderInfo cpi = null;
6166
6167        synchronized(this) {
6168            ProcessRecord r = null;
6169            if (caller != null) {
6170                r = getRecordForAppLocked(caller);
6171                if (r == null) {
6172                    throw new SecurityException(
6173                            "Unable to find app for caller " + caller
6174                          + " (pid=" + Binder.getCallingPid()
6175                          + ") when getting content provider " + name);
6176                }
6177            }
6178
6179            // First check if this content provider has been published...
6180            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6181            cpr = mProviderMap.getProviderByName(name, userId);
6182            boolean providerRunning = cpr != null;
6183            if (providerRunning) {
6184                cpi = cpr.info;
6185                String msg;
6186                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6187                    throw new SecurityException(msg);
6188                }
6189
6190                if (r != null && cpr.canRunHere(r)) {
6191                    // This provider has been published or is in the process
6192                    // of being published...  but it is also allowed to run
6193                    // in the caller's process, so don't make a connection
6194                    // and just let the caller instantiate its own instance.
6195                    ContentProviderHolder holder = cpr.newHolder(null);
6196                    // don't give caller the provider object, it needs
6197                    // to make its own.
6198                    holder.provider = null;
6199                    return holder;
6200                }
6201
6202                final long origId = Binder.clearCallingIdentity();
6203
6204                // In this case the provider instance already exists, so we can
6205                // return it right away.
6206                conn = incProviderCountLocked(r, cpr, token, stable);
6207                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6208                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6209                        // If this is a perceptible app accessing the provider,
6210                        // make sure to count it as being accessed and thus
6211                        // back up on the LRU list.  This is good because
6212                        // content providers are often expensive to start.
6213                        updateLruProcessLocked(cpr.proc, false, true);
6214                    }
6215                }
6216
6217                if (cpr.proc != null) {
6218                    if (false) {
6219                        if (cpr.name.flattenToShortString().equals(
6220                                "com.android.providers.calendar/.CalendarProvider2")) {
6221                            Slog.v(TAG, "****************** KILLING "
6222                                + cpr.name.flattenToShortString());
6223                            Process.killProcess(cpr.proc.pid);
6224                        }
6225                    }
6226                    boolean success = updateOomAdjLocked(cpr.proc);
6227                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6228                    // NOTE: there is still a race here where a signal could be
6229                    // pending on the process even though we managed to update its
6230                    // adj level.  Not sure what to do about this, but at least
6231                    // the race is now smaller.
6232                    if (!success) {
6233                        // Uh oh...  it looks like the provider's process
6234                        // has been killed on us.  We need to wait for a new
6235                        // process to be started, and make sure its death
6236                        // doesn't kill our process.
6237                        Slog.i(TAG,
6238                                "Existing provider " + cpr.name.flattenToShortString()
6239                                + " is crashing; detaching " + r);
6240                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6241                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6242                        if (!lastRef) {
6243                            // This wasn't the last ref our process had on
6244                            // the provider...  we have now been killed, bail.
6245                            return null;
6246                        }
6247                        providerRunning = false;
6248                        conn = null;
6249                    }
6250                }
6251
6252                Binder.restoreCallingIdentity(origId);
6253            }
6254
6255            boolean singleton;
6256            if (!providerRunning) {
6257                try {
6258                    cpi = AppGlobals.getPackageManager().
6259                        resolveContentProvider(name,
6260                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6261                } catch (RemoteException ex) {
6262                }
6263                if (cpi == null) {
6264                    return null;
6265                }
6266                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6267                        cpi.name, cpi.flags);
6268                if (singleton) {
6269                    userId = 0;
6270                }
6271                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6272
6273                String msg;
6274                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6275                    throw new SecurityException(msg);
6276                }
6277
6278                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6279                        && !cpi.processName.equals("system")) {
6280                    // If this content provider does not run in the system
6281                    // process, and the system is not yet ready to run other
6282                    // processes, then fail fast instead of hanging.
6283                    throw new IllegalArgumentException(
6284                            "Attempt to launch content provider before system ready");
6285                }
6286
6287                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6288                cpr = mProviderMap.getProviderByClass(comp, userId);
6289                final boolean firstClass = cpr == null;
6290                if (firstClass) {
6291                    try {
6292                        ApplicationInfo ai =
6293                            AppGlobals.getPackageManager().
6294                                getApplicationInfo(
6295                                        cpi.applicationInfo.packageName,
6296                                        STOCK_PM_FLAGS, userId);
6297                        if (ai == null) {
6298                            Slog.w(TAG, "No package info for content provider "
6299                                    + cpi.name);
6300                            return null;
6301                        }
6302                        ai = getAppInfoForUser(ai, userId);
6303                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6304                    } catch (RemoteException ex) {
6305                        // pm is in same process, this will never happen.
6306                    }
6307                }
6308
6309                if (r != null && cpr.canRunHere(r)) {
6310                    // If this is a multiprocess provider, then just return its
6311                    // info and allow the caller to instantiate it.  Only do
6312                    // this if the provider is the same user as the caller's
6313                    // process, or can run as root (so can be in any process).
6314                    return cpr.newHolder(null);
6315                }
6316
6317                if (DEBUG_PROVIDER) {
6318                    RuntimeException e = new RuntimeException("here");
6319                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6320                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6321                }
6322
6323                // This is single process, and our app is now connecting to it.
6324                // See if we are already in the process of launching this
6325                // provider.
6326                final int N = mLaunchingProviders.size();
6327                int i;
6328                for (i=0; i<N; i++) {
6329                    if (mLaunchingProviders.get(i) == cpr) {
6330                        break;
6331                    }
6332                }
6333
6334                // If the provider is not already being launched, then get it
6335                // started.
6336                if (i >= N) {
6337                    final long origId = Binder.clearCallingIdentity();
6338
6339                    try {
6340                        // Content provider is now in use, its package can't be stopped.
6341                        try {
6342                            AppGlobals.getPackageManager().setPackageStoppedState(
6343                                    cpr.appInfo.packageName, false, userId);
6344                        } catch (RemoteException e) {
6345                        } catch (IllegalArgumentException e) {
6346                            Slog.w(TAG, "Failed trying to unstop package "
6347                                    + cpr.appInfo.packageName + ": " + e);
6348                        }
6349
6350                        ProcessRecord proc = startProcessLocked(cpi.processName,
6351                                cpr.appInfo, false, 0, "content provider",
6352                                new ComponentName(cpi.applicationInfo.packageName,
6353                                        cpi.name), false, false);
6354                        if (proc == null) {
6355                            Slog.w(TAG, "Unable to launch app "
6356                                    + cpi.applicationInfo.packageName + "/"
6357                                    + cpi.applicationInfo.uid + " for provider "
6358                                    + name + ": process is bad");
6359                            return null;
6360                        }
6361                        cpr.launchingApp = proc;
6362                        mLaunchingProviders.add(cpr);
6363                    } finally {
6364                        Binder.restoreCallingIdentity(origId);
6365                    }
6366                }
6367
6368                // Make sure the provider is published (the same provider class
6369                // may be published under multiple names).
6370                if (firstClass) {
6371                    mProviderMap.putProviderByClass(comp, cpr);
6372                }
6373
6374                mProviderMap.putProviderByName(name, cpr);
6375                conn = incProviderCountLocked(r, cpr, token, stable);
6376                if (conn != null) {
6377                    conn.waiting = true;
6378                }
6379            }
6380        }
6381
6382        // Wait for the provider to be published...
6383        synchronized (cpr) {
6384            while (cpr.provider == null) {
6385                if (cpr.launchingApp == null) {
6386                    Slog.w(TAG, "Unable to launch app "
6387                            + cpi.applicationInfo.packageName + "/"
6388                            + cpi.applicationInfo.uid + " for provider "
6389                            + name + ": launching app became null");
6390                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6391                            cpi.applicationInfo.packageName,
6392                            cpi.applicationInfo.uid, name);
6393                    return null;
6394                }
6395                try {
6396                    if (DEBUG_MU) {
6397                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6398                                + cpr.launchingApp);
6399                    }
6400                    if (conn != null) {
6401                        conn.waiting = true;
6402                    }
6403                    cpr.wait();
6404                } catch (InterruptedException ex) {
6405                } finally {
6406                    if (conn != null) {
6407                        conn.waiting = false;
6408                    }
6409                }
6410            }
6411        }
6412        return cpr != null ? cpr.newHolder(conn) : null;
6413    }
6414
6415    public final ContentProviderHolder getContentProvider(
6416            IApplicationThread caller, String name, boolean stable) {
6417        enforceNotIsolatedCaller("getContentProvider");
6418        if (caller == null) {
6419            String msg = "null IApplicationThread when getting content provider "
6420                    + name;
6421            Slog.w(TAG, msg);
6422            throw new SecurityException(msg);
6423        }
6424
6425        return getContentProviderImpl(caller, name, null, stable);
6426    }
6427
6428    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6429        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6430            "Do not have permission in call getContentProviderExternal()");
6431        return getContentProviderExternalUnchecked(name, token);
6432    }
6433
6434    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6435        return getContentProviderImpl(null, name, token, true);
6436    }
6437
6438    /**
6439     * Drop a content provider from a ProcessRecord's bookkeeping
6440     * @param cpr
6441     */
6442    public void removeContentProvider(IBinder connection, boolean stable) {
6443        enforceNotIsolatedCaller("removeContentProvider");
6444        synchronized (this) {
6445            ContentProviderConnection conn;
6446            try {
6447                conn = (ContentProviderConnection)connection;
6448            } catch (ClassCastException e) {
6449                String msg ="removeContentProvider: " + connection
6450                        + " not a ContentProviderConnection";
6451                Slog.w(TAG, msg);
6452                throw new IllegalArgumentException(msg);
6453            }
6454            if (conn == null) {
6455                throw new NullPointerException("connection is null");
6456            }
6457            if (decProviderCountLocked(conn, null, null, stable)) {
6458                updateOomAdjLocked();
6459            }
6460        }
6461    }
6462
6463    public void removeContentProviderExternal(String name, IBinder token) {
6464        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6465            "Do not have permission in call removeContentProviderExternal()");
6466        removeContentProviderExternalUnchecked(name, token);
6467    }
6468
6469    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6470        synchronized (this) {
6471            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6472                    Binder.getOrigCallingUser());
6473            if(cpr == null) {
6474                //remove from mProvidersByClass
6475                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6476                return;
6477            }
6478
6479            //update content provider record entry info
6480            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6481            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6482                    Binder.getOrigCallingUser());
6483            if (localCpr.hasExternalProcessHandles()) {
6484                if (localCpr.removeExternalProcessHandleLocked(token)) {
6485                    updateOomAdjLocked();
6486                } else {
6487                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6488                            + " with no external reference for token: "
6489                            + token + ".");
6490                }
6491            } else {
6492                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6493                        + " with no external references.");
6494            }
6495        }
6496    }
6497
6498    public final void publishContentProviders(IApplicationThread caller,
6499            List<ContentProviderHolder> providers) {
6500        if (providers == null) {
6501            return;
6502        }
6503
6504        enforceNotIsolatedCaller("publishContentProviders");
6505        synchronized (this) {
6506            final ProcessRecord r = getRecordForAppLocked(caller);
6507            if (DEBUG_MU)
6508                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6509            if (r == null) {
6510                throw new SecurityException(
6511                        "Unable to find app for caller " + caller
6512                      + " (pid=" + Binder.getCallingPid()
6513                      + ") when publishing content providers");
6514            }
6515
6516            final long origId = Binder.clearCallingIdentity();
6517
6518            final int N = providers.size();
6519            for (int i=0; i<N; i++) {
6520                ContentProviderHolder src = providers.get(i);
6521                if (src == null || src.info == null || src.provider == null) {
6522                    continue;
6523                }
6524                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6525                if (DEBUG_MU)
6526                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6527                if (dst != null) {
6528                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6529                    mProviderMap.putProviderByClass(comp, dst);
6530                    String names[] = dst.info.authority.split(";");
6531                    for (int j = 0; j < names.length; j++) {
6532                        mProviderMap.putProviderByName(names[j], dst);
6533                    }
6534
6535                    int NL = mLaunchingProviders.size();
6536                    int j;
6537                    for (j=0; j<NL; j++) {
6538                        if (mLaunchingProviders.get(j) == dst) {
6539                            mLaunchingProviders.remove(j);
6540                            j--;
6541                            NL--;
6542                        }
6543                    }
6544                    synchronized (dst) {
6545                        dst.provider = src.provider;
6546                        dst.proc = r;
6547                        dst.notifyAll();
6548                    }
6549                    updateOomAdjLocked(r);
6550                }
6551            }
6552
6553            Binder.restoreCallingIdentity(origId);
6554        }
6555    }
6556
6557    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6558        ContentProviderConnection conn;
6559        try {
6560            conn = (ContentProviderConnection)connection;
6561        } catch (ClassCastException e) {
6562            String msg ="refContentProvider: " + connection
6563                    + " not a ContentProviderConnection";
6564            Slog.w(TAG, msg);
6565            throw new IllegalArgumentException(msg);
6566        }
6567        if (conn == null) {
6568            throw new NullPointerException("connection is null");
6569        }
6570
6571        synchronized (this) {
6572            if (stable > 0) {
6573                conn.numStableIncs += stable;
6574            }
6575            stable = conn.stableCount + stable;
6576            if (stable < 0) {
6577                throw new IllegalStateException("stableCount < 0: " + stable);
6578            }
6579
6580            if (unstable > 0) {
6581                conn.numUnstableIncs += unstable;
6582            }
6583            unstable = conn.unstableCount + unstable;
6584            if (unstable < 0) {
6585                throw new IllegalStateException("unstableCount < 0: " + unstable);
6586            }
6587
6588            if ((stable+unstable) <= 0) {
6589                throw new IllegalStateException("ref counts can't go to zero here: stable="
6590                        + stable + " unstable=" + unstable);
6591            }
6592            conn.stableCount = stable;
6593            conn.unstableCount = unstable;
6594            return !conn.dead;
6595        }
6596    }
6597
6598    public void unstableProviderDied(IBinder connection) {
6599        ContentProviderConnection conn;
6600        try {
6601            conn = (ContentProviderConnection)connection;
6602        } catch (ClassCastException e) {
6603            String msg ="refContentProvider: " + connection
6604                    + " not a ContentProviderConnection";
6605            Slog.w(TAG, msg);
6606            throw new IllegalArgumentException(msg);
6607        }
6608        if (conn == null) {
6609            throw new NullPointerException("connection is null");
6610        }
6611
6612        // Safely retrieve the content provider associated with the connection.
6613        IContentProvider provider;
6614        synchronized (this) {
6615            provider = conn.provider.provider;
6616        }
6617
6618        if (provider == null) {
6619            // Um, yeah, we're way ahead of you.
6620            return;
6621        }
6622
6623        // Make sure the caller is being honest with us.
6624        if (provider.asBinder().pingBinder()) {
6625            // Er, no, still looks good to us.
6626            synchronized (this) {
6627                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6628                        + " says " + conn + " died, but we don't agree");
6629                return;
6630            }
6631        }
6632
6633        // Well look at that!  It's dead!
6634        synchronized (this) {
6635            if (conn.provider.provider != provider) {
6636                // But something changed...  good enough.
6637                return;
6638            }
6639
6640            ProcessRecord proc = conn.provider.proc;
6641            if (proc == null || proc.thread == null) {
6642                // Seems like the process is already cleaned up.
6643                return;
6644            }
6645
6646            // As far as we're concerned, this is just like receiving a
6647            // death notification...  just a bit prematurely.
6648            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6649                    + ") early provider death");
6650            final long ident = Binder.clearCallingIdentity();
6651            try {
6652                appDiedLocked(proc, proc.pid, proc.thread);
6653            } finally {
6654                Binder.restoreCallingIdentity(ident);
6655            }
6656        }
6657    }
6658
6659    public static final void installSystemProviders() {
6660        List<ProviderInfo> providers;
6661        synchronized (mSelf) {
6662            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6663            providers = mSelf.generateApplicationProvidersLocked(app);
6664            if (providers != null) {
6665                for (int i=providers.size()-1; i>=0; i--) {
6666                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6667                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6668                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6669                                + ": not system .apk");
6670                        providers.remove(i);
6671                    }
6672                }
6673            }
6674        }
6675        if (providers != null) {
6676            mSystemThread.installSystemProviders(providers);
6677        }
6678
6679        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6680
6681        mSelf.mUsageStatsService.monitorPackages();
6682    }
6683
6684    /**
6685     * Allows app to retrieve the MIME type of a URI without having permission
6686     * to access its content provider.
6687     *
6688     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6689     *
6690     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6691     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6692     */
6693    public String getProviderMimeType(Uri uri) {
6694        enforceNotIsolatedCaller("getProviderMimeType");
6695        final String name = uri.getAuthority();
6696        final long ident = Binder.clearCallingIdentity();
6697        ContentProviderHolder holder = null;
6698
6699        try {
6700            holder = getContentProviderExternalUnchecked(name, null);
6701            if (holder != null) {
6702                return holder.provider.getType(uri);
6703            }
6704        } catch (RemoteException e) {
6705            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6706            return null;
6707        } finally {
6708            if (holder != null) {
6709                removeContentProviderExternalUnchecked(name, null);
6710            }
6711            Binder.restoreCallingIdentity(ident);
6712        }
6713
6714        return null;
6715    }
6716
6717    // =========================================================
6718    // GLOBAL MANAGEMENT
6719    // =========================================================
6720
6721    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6722            ApplicationInfo info, String customProcess, boolean isolated) {
6723        String proc = customProcess != null ? customProcess : info.processName;
6724        BatteryStatsImpl.Uid.Proc ps = null;
6725        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6726        int uid = info.uid;
6727        if (isolated) {
6728            int userId = UserHandle.getUserId(uid);
6729            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6730            uid = 0;
6731            while (true) {
6732                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6733                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6734                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6735                }
6736                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6737                mNextIsolatedProcessUid++;
6738                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6739                    // No process for this uid, use it.
6740                    break;
6741                }
6742                stepsLeft--;
6743                if (stepsLeft <= 0) {
6744                    return null;
6745                }
6746            }
6747        }
6748        synchronized (stats) {
6749            ps = stats.getProcessStatsLocked(info.uid, proc);
6750        }
6751        return new ProcessRecord(ps, thread, info, proc, uid);
6752    }
6753
6754    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6755        ProcessRecord app;
6756        if (!isolated) {
6757            app = getProcessRecordLocked(info.processName, info.uid);
6758        } else {
6759            app = null;
6760        }
6761
6762        if (app == null) {
6763            app = newProcessRecordLocked(null, info, null, isolated);
6764            mProcessNames.put(info.processName, app.uid, app);
6765            if (isolated) {
6766                mIsolatedProcesses.put(app.uid, app);
6767            }
6768            updateLruProcessLocked(app, true, true);
6769        }
6770
6771        // This package really, really can not be stopped.
6772        try {
6773            AppGlobals.getPackageManager().setPackageStoppedState(
6774                    info.packageName, false, UserHandle.getUserId(app.uid));
6775        } catch (RemoteException e) {
6776        } catch (IllegalArgumentException e) {
6777            Slog.w(TAG, "Failed trying to unstop package "
6778                    + info.packageName + ": " + e);
6779        }
6780
6781        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6782                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6783            app.persistent = true;
6784            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6785        }
6786        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6787            mPersistentStartingProcesses.add(app);
6788            startProcessLocked(app, "added application", app.processName);
6789        }
6790
6791        return app;
6792    }
6793
6794    public void unhandledBack() {
6795        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6796                "unhandledBack()");
6797
6798        synchronized(this) {
6799            int count = mMainStack.mHistory.size();
6800            if (DEBUG_SWITCH) Slog.d(
6801                TAG, "Performing unhandledBack(): stack size = " + count);
6802            if (count > 1) {
6803                final long origId = Binder.clearCallingIdentity();
6804                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6805                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6806                Binder.restoreCallingIdentity(origId);
6807            }
6808        }
6809    }
6810
6811    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6812        enforceNotIsolatedCaller("openContentUri");
6813        String name = uri.getAuthority();
6814        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6815        ParcelFileDescriptor pfd = null;
6816        if (cph != null) {
6817            // We record the binder invoker's uid in thread-local storage before
6818            // going to the content provider to open the file.  Later, in the code
6819            // that handles all permissions checks, we look for this uid and use
6820            // that rather than the Activity Manager's own uid.  The effect is that
6821            // we do the check against the caller's permissions even though it looks
6822            // to the content provider like the Activity Manager itself is making
6823            // the request.
6824            sCallerIdentity.set(new Identity(
6825                    Binder.getCallingPid(), Binder.getCallingUid()));
6826            try {
6827                pfd = cph.provider.openFile(uri, "r");
6828            } catch (FileNotFoundException e) {
6829                // do nothing; pfd will be returned null
6830            } finally {
6831                // Ensure that whatever happens, we clean up the identity state
6832                sCallerIdentity.remove();
6833            }
6834
6835            // We've got the fd now, so we're done with the provider.
6836            removeContentProviderExternalUnchecked(name, null);
6837        } else {
6838            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6839        }
6840        return pfd;
6841    }
6842
6843    // Actually is sleeping or shutting down or whatever else in the future
6844    // is an inactive state.
6845    public boolean isSleeping() {
6846        return mSleeping || mShuttingDown;
6847    }
6848
6849    public void goingToSleep() {
6850        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6851                != PackageManager.PERMISSION_GRANTED) {
6852            throw new SecurityException("Requires permission "
6853                    + android.Manifest.permission.DEVICE_POWER);
6854        }
6855
6856        synchronized(this) {
6857            mWentToSleep = true;
6858            updateEventDispatchingLocked();
6859
6860            if (!mSleeping) {
6861                mSleeping = true;
6862                mMainStack.stopIfSleepingLocked();
6863
6864                // Initialize the wake times of all processes.
6865                checkExcessivePowerUsageLocked(false);
6866                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6867                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6868                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6869            }
6870        }
6871    }
6872
6873    public boolean shutdown(int timeout) {
6874        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6875                != PackageManager.PERMISSION_GRANTED) {
6876            throw new SecurityException("Requires permission "
6877                    + android.Manifest.permission.SHUTDOWN);
6878        }
6879
6880        boolean timedout = false;
6881
6882        synchronized(this) {
6883            mShuttingDown = true;
6884            updateEventDispatchingLocked();
6885
6886            if (mMainStack.mResumedActivity != null) {
6887                mMainStack.stopIfSleepingLocked();
6888                final long endTime = System.currentTimeMillis() + timeout;
6889                while (mMainStack.mResumedActivity != null
6890                        || mMainStack.mPausingActivity != null) {
6891                    long delay = endTime - System.currentTimeMillis();
6892                    if (delay <= 0) {
6893                        Slog.w(TAG, "Activity manager shutdown timed out");
6894                        timedout = true;
6895                        break;
6896                    }
6897                    try {
6898                        this.wait();
6899                    } catch (InterruptedException e) {
6900                    }
6901                }
6902            }
6903        }
6904
6905        mUsageStatsService.shutdown();
6906        mBatteryStatsService.shutdown();
6907
6908        return timedout;
6909    }
6910
6911    public final void activitySlept(IBinder token) {
6912        if (localLOGV) Slog.v(
6913            TAG, "Activity slept: token=" + token);
6914
6915        ActivityRecord r = null;
6916
6917        final long origId = Binder.clearCallingIdentity();
6918
6919        synchronized (this) {
6920            r = mMainStack.isInStackLocked(token);
6921            if (r != null) {
6922                mMainStack.activitySleptLocked(r);
6923            }
6924        }
6925
6926        Binder.restoreCallingIdentity(origId);
6927    }
6928
6929    private void comeOutOfSleepIfNeededLocked() {
6930        if (!mWentToSleep && !mLockScreenShown) {
6931            if (mSleeping) {
6932                mSleeping = false;
6933                mMainStack.awakeFromSleepingLocked();
6934                mMainStack.resumeTopActivityLocked(null);
6935            }
6936        }
6937    }
6938
6939    public void wakingUp() {
6940        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6941                != PackageManager.PERMISSION_GRANTED) {
6942            throw new SecurityException("Requires permission "
6943                    + android.Manifest.permission.DEVICE_POWER);
6944        }
6945
6946        synchronized(this) {
6947            mWentToSleep = false;
6948            updateEventDispatchingLocked();
6949            comeOutOfSleepIfNeededLocked();
6950        }
6951    }
6952
6953    private void updateEventDispatchingLocked() {
6954        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6955    }
6956
6957    public void setLockScreenShown(boolean shown) {
6958        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6959                != PackageManager.PERMISSION_GRANTED) {
6960            throw new SecurityException("Requires permission "
6961                    + android.Manifest.permission.DEVICE_POWER);
6962        }
6963
6964        synchronized(this) {
6965            mLockScreenShown = shown;
6966            comeOutOfSleepIfNeededLocked();
6967        }
6968    }
6969
6970    public void stopAppSwitches() {
6971        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6972                != PackageManager.PERMISSION_GRANTED) {
6973            throw new SecurityException("Requires permission "
6974                    + android.Manifest.permission.STOP_APP_SWITCHES);
6975        }
6976
6977        synchronized(this) {
6978            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6979                    + APP_SWITCH_DELAY_TIME;
6980            mDidAppSwitch = false;
6981            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6982            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6983            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6984        }
6985    }
6986
6987    public void resumeAppSwitches() {
6988        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6989                != PackageManager.PERMISSION_GRANTED) {
6990            throw new SecurityException("Requires permission "
6991                    + android.Manifest.permission.STOP_APP_SWITCHES);
6992        }
6993
6994        synchronized(this) {
6995            // Note that we don't execute any pending app switches... we will
6996            // let those wait until either the timeout, or the next start
6997            // activity request.
6998            mAppSwitchesAllowedTime = 0;
6999        }
7000    }
7001
7002    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7003            String name) {
7004        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7005            return true;
7006        }
7007
7008        final int perm = checkComponentPermission(
7009                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7010                callingUid, -1, true);
7011        if (perm == PackageManager.PERMISSION_GRANTED) {
7012            return true;
7013        }
7014
7015        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7016        return false;
7017    }
7018
7019    public void setDebugApp(String packageName, boolean waitForDebugger,
7020            boolean persistent) {
7021        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7022                "setDebugApp()");
7023
7024        // Note that this is not really thread safe if there are multiple
7025        // callers into it at the same time, but that's not a situation we
7026        // care about.
7027        if (persistent) {
7028            final ContentResolver resolver = mContext.getContentResolver();
7029            Settings.System.putString(
7030                resolver, Settings.System.DEBUG_APP,
7031                packageName);
7032            Settings.System.putInt(
7033                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7034                waitForDebugger ? 1 : 0);
7035        }
7036
7037        synchronized (this) {
7038            if (!persistent) {
7039                mOrigDebugApp = mDebugApp;
7040                mOrigWaitForDebugger = mWaitForDebugger;
7041            }
7042            mDebugApp = packageName;
7043            mWaitForDebugger = waitForDebugger;
7044            mDebugTransient = !persistent;
7045            if (packageName != null) {
7046                final long origId = Binder.clearCallingIdentity();
7047                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7048                Binder.restoreCallingIdentity(origId);
7049            }
7050        }
7051    }
7052
7053    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7054        synchronized (this) {
7055            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7056            if (!isDebuggable) {
7057                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7058                    throw new SecurityException("Process not debuggable: " + app.packageName);
7059                }
7060            }
7061
7062            mOpenGlTraceApp = processName;
7063        }
7064    }
7065
7066    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7067            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7068        synchronized (this) {
7069            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7070            if (!isDebuggable) {
7071                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7072                    throw new SecurityException("Process not debuggable: " + app.packageName);
7073                }
7074            }
7075            mProfileApp = processName;
7076            mProfileFile = profileFile;
7077            if (mProfileFd != null) {
7078                try {
7079                    mProfileFd.close();
7080                } catch (IOException e) {
7081                }
7082                mProfileFd = null;
7083            }
7084            mProfileFd = profileFd;
7085            mProfileType = 0;
7086            mAutoStopProfiler = autoStopProfiler;
7087        }
7088    }
7089
7090    public void setAlwaysFinish(boolean enabled) {
7091        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7092                "setAlwaysFinish()");
7093
7094        Settings.System.putInt(
7095                mContext.getContentResolver(),
7096                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7097
7098        synchronized (this) {
7099            mAlwaysFinishActivities = enabled;
7100        }
7101    }
7102
7103    public void setActivityController(IActivityController controller) {
7104        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7105                "setActivityController()");
7106        synchronized (this) {
7107            mController = controller;
7108        }
7109    }
7110
7111    public boolean isUserAMonkey() {
7112        // For now the fact that there is a controller implies
7113        // we have a monkey.
7114        synchronized (this) {
7115            return mController != null;
7116        }
7117    }
7118
7119    public void registerProcessObserver(IProcessObserver observer) {
7120        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7121                "registerProcessObserver()");
7122        synchronized (this) {
7123            mProcessObservers.register(observer);
7124        }
7125    }
7126
7127    public void unregisterProcessObserver(IProcessObserver observer) {
7128        synchronized (this) {
7129            mProcessObservers.unregister(observer);
7130        }
7131    }
7132
7133    public void setImmersive(IBinder token, boolean immersive) {
7134        synchronized(this) {
7135            ActivityRecord r = mMainStack.isInStackLocked(token);
7136            if (r == null) {
7137                throw new IllegalArgumentException();
7138            }
7139            r.immersive = immersive;
7140        }
7141    }
7142
7143    public boolean isImmersive(IBinder token) {
7144        synchronized (this) {
7145            ActivityRecord r = mMainStack.isInStackLocked(token);
7146            if (r == null) {
7147                throw new IllegalArgumentException();
7148            }
7149            return r.immersive;
7150        }
7151    }
7152
7153    public boolean isTopActivityImmersive() {
7154        enforceNotIsolatedCaller("startActivity");
7155        synchronized (this) {
7156            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7157            return (r != null) ? r.immersive : false;
7158        }
7159    }
7160
7161    public final void enterSafeMode() {
7162        synchronized(this) {
7163            // It only makes sense to do this before the system is ready
7164            // and started launching other packages.
7165            if (!mSystemReady) {
7166                try {
7167                    AppGlobals.getPackageManager().enterSafeMode();
7168                } catch (RemoteException e) {
7169                }
7170            }
7171        }
7172    }
7173
7174    public final void showSafeModeOverlay() {
7175        View v = LayoutInflater.from(mContext).inflate(
7176                com.android.internal.R.layout.safe_mode, null);
7177        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7178        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7179        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7180        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7181        lp.gravity = Gravity.BOTTOM | Gravity.START;
7182        lp.format = v.getBackground().getOpacity();
7183        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7184                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7185        ((WindowManager)mContext.getSystemService(
7186                Context.WINDOW_SERVICE)).addView(v, lp);
7187    }
7188
7189    public void noteWakeupAlarm(IIntentSender sender) {
7190        if (!(sender instanceof PendingIntentRecord)) {
7191            return;
7192        }
7193        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7194        synchronized (stats) {
7195            if (mBatteryStatsService.isOnBattery()) {
7196                mBatteryStatsService.enforceCallingPermission();
7197                PendingIntentRecord rec = (PendingIntentRecord)sender;
7198                int MY_UID = Binder.getCallingUid();
7199                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7200                BatteryStatsImpl.Uid.Pkg pkg =
7201                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7202                pkg.incWakeupsLocked();
7203            }
7204        }
7205    }
7206
7207    public boolean killPids(int[] pids, String pReason, boolean secure) {
7208        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7209            throw new SecurityException("killPids only available to the system");
7210        }
7211        String reason = (pReason == null) ? "Unknown" : pReason;
7212        // XXX Note: don't acquire main activity lock here, because the window
7213        // manager calls in with its locks held.
7214
7215        boolean killed = false;
7216        synchronized (mPidsSelfLocked) {
7217            int[] types = new int[pids.length];
7218            int worstType = 0;
7219            for (int i=0; i<pids.length; i++) {
7220                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7221                if (proc != null) {
7222                    int type = proc.setAdj;
7223                    types[i] = type;
7224                    if (type > worstType) {
7225                        worstType = type;
7226                    }
7227                }
7228            }
7229
7230            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7231            // then constrain it so we will kill all hidden procs.
7232            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7233                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7234                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7235            }
7236
7237            // If this is not a secure call, don't let it kill processes that
7238            // are important.
7239            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7240                worstType = ProcessList.SERVICE_ADJ;
7241            }
7242
7243            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7244            for (int i=0; i<pids.length; i++) {
7245                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7246                if (proc == null) {
7247                    continue;
7248                }
7249                int adj = proc.setAdj;
7250                if (adj >= worstType && !proc.killedBackground) {
7251                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7252                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7253                            proc.processName, adj, reason);
7254                    killed = true;
7255                    proc.killedBackground = true;
7256                    Process.killProcessQuiet(pids[i]);
7257                }
7258            }
7259        }
7260        return killed;
7261    }
7262
7263    @Override
7264    public boolean killProcessesBelowForeground(String reason) {
7265        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7266            throw new SecurityException("killProcessesBelowForeground() only available to system");
7267        }
7268
7269        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7270    }
7271
7272    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7273        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7274            throw new SecurityException("killProcessesBelowAdj() only available to system");
7275        }
7276
7277        boolean killed = false;
7278        synchronized (mPidsSelfLocked) {
7279            final int size = mPidsSelfLocked.size();
7280            for (int i = 0; i < size; i++) {
7281                final int pid = mPidsSelfLocked.keyAt(i);
7282                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7283                if (proc == null) continue;
7284
7285                final int adj = proc.setAdj;
7286                if (adj > belowAdj && !proc.killedBackground) {
7287                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7288                    EventLog.writeEvent(
7289                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7290                    killed = true;
7291                    proc.killedBackground = true;
7292                    Process.killProcessQuiet(pid);
7293                }
7294            }
7295        }
7296        return killed;
7297    }
7298
7299    public final void startRunning(String pkg, String cls, String action,
7300            String data) {
7301        synchronized(this) {
7302            if (mStartRunning) {
7303                return;
7304            }
7305            mStartRunning = true;
7306            mTopComponent = pkg != null && cls != null
7307                    ? new ComponentName(pkg, cls) : null;
7308            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7309            mTopData = data;
7310            if (!mSystemReady) {
7311                return;
7312            }
7313        }
7314
7315        systemReady(null);
7316    }
7317
7318    private void retrieveSettings() {
7319        final ContentResolver resolver = mContext.getContentResolver();
7320        String debugApp = Settings.System.getString(
7321            resolver, Settings.System.DEBUG_APP);
7322        boolean waitForDebugger = Settings.System.getInt(
7323            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7324        boolean alwaysFinishActivities = Settings.System.getInt(
7325            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7326
7327        Configuration configuration = new Configuration();
7328        Settings.System.getConfiguration(resolver, configuration);
7329
7330        synchronized (this) {
7331            mDebugApp = mOrigDebugApp = debugApp;
7332            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7333            mAlwaysFinishActivities = alwaysFinishActivities;
7334            // This happens before any activities are started, so we can
7335            // change mConfiguration in-place.
7336            updateConfigurationLocked(configuration, null, false, true);
7337            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7338        }
7339    }
7340
7341    public boolean testIsSystemReady() {
7342        // no need to synchronize(this) just to read & return the value
7343        return mSystemReady;
7344    }
7345
7346    private static File getCalledPreBootReceiversFile() {
7347        File dataDir = Environment.getDataDirectory();
7348        File systemDir = new File(dataDir, "system");
7349        File fname = new File(systemDir, "called_pre_boots.dat");
7350        return fname;
7351    }
7352
7353    static final int LAST_DONE_VERSION = 10000;
7354
7355    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7356        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7357        File file = getCalledPreBootReceiversFile();
7358        FileInputStream fis = null;
7359        try {
7360            fis = new FileInputStream(file);
7361            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7362            int fvers = dis.readInt();
7363            if (fvers == LAST_DONE_VERSION) {
7364                String vers = dis.readUTF();
7365                String codename = dis.readUTF();
7366                String build = dis.readUTF();
7367                if (android.os.Build.VERSION.RELEASE.equals(vers)
7368                        && android.os.Build.VERSION.CODENAME.equals(codename)
7369                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7370                    int num = dis.readInt();
7371                    while (num > 0) {
7372                        num--;
7373                        String pkg = dis.readUTF();
7374                        String cls = dis.readUTF();
7375                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7376                    }
7377                }
7378            }
7379        } catch (FileNotFoundException e) {
7380        } catch (IOException e) {
7381            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7382        } finally {
7383            if (fis != null) {
7384                try {
7385                    fis.close();
7386                } catch (IOException e) {
7387                }
7388            }
7389        }
7390        return lastDoneReceivers;
7391    }
7392
7393    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7394        File file = getCalledPreBootReceiversFile();
7395        FileOutputStream fos = null;
7396        DataOutputStream dos = null;
7397        try {
7398            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7399            fos = new FileOutputStream(file);
7400            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7401            dos.writeInt(LAST_DONE_VERSION);
7402            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7403            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7404            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7405            dos.writeInt(list.size());
7406            for (int i=0; i<list.size(); i++) {
7407                dos.writeUTF(list.get(i).getPackageName());
7408                dos.writeUTF(list.get(i).getClassName());
7409            }
7410        } catch (IOException e) {
7411            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7412            file.delete();
7413        } finally {
7414            FileUtils.sync(fos);
7415            if (dos != null) {
7416                try {
7417                    dos.close();
7418                } catch (IOException e) {
7419                    // TODO Auto-generated catch block
7420                    e.printStackTrace();
7421                }
7422            }
7423        }
7424    }
7425
7426    public void systemReady(final Runnable goingCallback) {
7427        synchronized(this) {
7428            if (mSystemReady) {
7429                if (goingCallback != null) goingCallback.run();
7430                return;
7431            }
7432
7433            // Check to see if there are any update receivers to run.
7434            if (!mDidUpdate) {
7435                if (mWaitingUpdate) {
7436                    return;
7437                }
7438                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7439                List<ResolveInfo> ris = null;
7440                try {
7441                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7442                            intent, null, 0, 0);
7443                } catch (RemoteException e) {
7444                }
7445                if (ris != null) {
7446                    for (int i=ris.size()-1; i>=0; i--) {
7447                        if ((ris.get(i).activityInfo.applicationInfo.flags
7448                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7449                            ris.remove(i);
7450                        }
7451                    }
7452                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7453
7454                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7455
7456                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7457                    for (int i=0; i<ris.size(); i++) {
7458                        ActivityInfo ai = ris.get(i).activityInfo;
7459                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7460                        if (lastDoneReceivers.contains(comp)) {
7461                            ris.remove(i);
7462                            i--;
7463                        }
7464                    }
7465
7466                    for (int i=0; i<ris.size(); i++) {
7467                        ActivityInfo ai = ris.get(i).activityInfo;
7468                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7469                        doneReceivers.add(comp);
7470                        intent.setComponent(comp);
7471                        IIntentReceiver finisher = null;
7472                        if (i == ris.size()-1) {
7473                            finisher = new IIntentReceiver.Stub() {
7474                                public void performReceive(Intent intent, int resultCode,
7475                                        String data, Bundle extras, boolean ordered,
7476                                        boolean sticky) {
7477                                    // The raw IIntentReceiver interface is called
7478                                    // with the AM lock held, so redispatch to
7479                                    // execute our code without the lock.
7480                                    mHandler.post(new Runnable() {
7481                                        public void run() {
7482                                            synchronized (ActivityManagerService.this) {
7483                                                mDidUpdate = true;
7484                                            }
7485                                            writeLastDonePreBootReceivers(doneReceivers);
7486                                            showBootMessage(mContext.getText(
7487                                                    R.string.android_upgrading_complete),
7488                                                    false);
7489                                            systemReady(goingCallback);
7490                                        }
7491                                    });
7492                                }
7493                            };
7494                        }
7495                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7496                        /* TODO: Send this to all users */
7497                        broadcastIntentLocked(null, null, intent, null, finisher,
7498                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7499                                0 /* UserId zero */);
7500                        if (finisher != null) {
7501                            mWaitingUpdate = true;
7502                        }
7503                    }
7504                }
7505                if (mWaitingUpdate) {
7506                    return;
7507                }
7508                mDidUpdate = true;
7509            }
7510
7511            mSystemReady = true;
7512            if (!mStartRunning) {
7513                return;
7514            }
7515        }
7516
7517        ArrayList<ProcessRecord> procsToKill = null;
7518        synchronized(mPidsSelfLocked) {
7519            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7520                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7521                if (!isAllowedWhileBooting(proc.info)){
7522                    if (procsToKill == null) {
7523                        procsToKill = new ArrayList<ProcessRecord>();
7524                    }
7525                    procsToKill.add(proc);
7526                }
7527            }
7528        }
7529
7530        synchronized(this) {
7531            if (procsToKill != null) {
7532                for (int i=procsToKill.size()-1; i>=0; i--) {
7533                    ProcessRecord proc = procsToKill.get(i);
7534                    Slog.i(TAG, "Removing system update proc: " + proc);
7535                    removeProcessLocked(proc, true, false, "system update done");
7536                }
7537            }
7538
7539            // Now that we have cleaned up any update processes, we
7540            // are ready to start launching real processes and know that
7541            // we won't trample on them any more.
7542            mProcessesReady = true;
7543        }
7544
7545        Slog.i(TAG, "System now ready");
7546        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7547            SystemClock.uptimeMillis());
7548
7549        synchronized(this) {
7550            // Make sure we have no pre-ready processes sitting around.
7551
7552            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7553                ResolveInfo ri = mContext.getPackageManager()
7554                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7555                                STOCK_PM_FLAGS);
7556                CharSequence errorMsg = null;
7557                if (ri != null) {
7558                    ActivityInfo ai = ri.activityInfo;
7559                    ApplicationInfo app = ai.applicationInfo;
7560                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7561                        mTopAction = Intent.ACTION_FACTORY_TEST;
7562                        mTopData = null;
7563                        mTopComponent = new ComponentName(app.packageName,
7564                                ai.name);
7565                    } else {
7566                        errorMsg = mContext.getResources().getText(
7567                                com.android.internal.R.string.factorytest_not_system);
7568                    }
7569                } else {
7570                    errorMsg = mContext.getResources().getText(
7571                            com.android.internal.R.string.factorytest_no_action);
7572                }
7573                if (errorMsg != null) {
7574                    mTopAction = null;
7575                    mTopData = null;
7576                    mTopComponent = null;
7577                    Message msg = Message.obtain();
7578                    msg.what = SHOW_FACTORY_ERROR_MSG;
7579                    msg.getData().putCharSequence("msg", errorMsg);
7580                    mHandler.sendMessage(msg);
7581                }
7582            }
7583        }
7584
7585        retrieveSettings();
7586
7587        if (goingCallback != null) goingCallback.run();
7588
7589        synchronized (this) {
7590            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7591                try {
7592                    List apps = AppGlobals.getPackageManager().
7593                        getPersistentApplications(STOCK_PM_FLAGS);
7594                    if (apps != null) {
7595                        int N = apps.size();
7596                        int i;
7597                        for (i=0; i<N; i++) {
7598                            ApplicationInfo info
7599                                = (ApplicationInfo)apps.get(i);
7600                            if (info != null &&
7601                                    !info.packageName.equals("android")) {
7602                                addAppLocked(info, false);
7603                            }
7604                        }
7605                    }
7606                } catch (RemoteException ex) {
7607                    // pm is in same process, this will never happen.
7608                }
7609            }
7610
7611            // Start up initial activity.
7612            mBooting = true;
7613
7614            try {
7615                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7616                    Message msg = Message.obtain();
7617                    msg.what = SHOW_UID_ERROR_MSG;
7618                    mHandler.sendMessage(msg);
7619                }
7620            } catch (RemoteException e) {
7621            }
7622
7623            mMainStack.resumeTopActivityLocked(null);
7624        }
7625    }
7626
7627    private boolean makeAppCrashingLocked(ProcessRecord app,
7628            String shortMsg, String longMsg, String stackTrace) {
7629        app.crashing = true;
7630        app.crashingReport = generateProcessError(app,
7631                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7632        startAppProblemLocked(app);
7633        app.stopFreezingAllLocked();
7634        return handleAppCrashLocked(app);
7635    }
7636
7637    private void makeAppNotRespondingLocked(ProcessRecord app,
7638            String activity, String shortMsg, String longMsg) {
7639        app.notResponding = true;
7640        app.notRespondingReport = generateProcessError(app,
7641                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7642                activity, shortMsg, longMsg, null);
7643        startAppProblemLocked(app);
7644        app.stopFreezingAllLocked();
7645    }
7646
7647    /**
7648     * Generate a process error record, suitable for attachment to a ProcessRecord.
7649     *
7650     * @param app The ProcessRecord in which the error occurred.
7651     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7652     *                      ActivityManager.AppErrorStateInfo
7653     * @param activity The activity associated with the crash, if known.
7654     * @param shortMsg Short message describing the crash.
7655     * @param longMsg Long message describing the crash.
7656     * @param stackTrace Full crash stack trace, may be null.
7657     *
7658     * @return Returns a fully-formed AppErrorStateInfo record.
7659     */
7660    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7661            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7662        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7663
7664        report.condition = condition;
7665        report.processName = app.processName;
7666        report.pid = app.pid;
7667        report.uid = app.info.uid;
7668        report.tag = activity;
7669        report.shortMsg = shortMsg;
7670        report.longMsg = longMsg;
7671        report.stackTrace = stackTrace;
7672
7673        return report;
7674    }
7675
7676    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7677        synchronized (this) {
7678            app.crashing = false;
7679            app.crashingReport = null;
7680            app.notResponding = false;
7681            app.notRespondingReport = null;
7682            if (app.anrDialog == fromDialog) {
7683                app.anrDialog = null;
7684            }
7685            if (app.waitDialog == fromDialog) {
7686                app.waitDialog = null;
7687            }
7688            if (app.pid > 0 && app.pid != MY_PID) {
7689                handleAppCrashLocked(app);
7690                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7691                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7692                        app.processName, app.setAdj, "user's request after error");
7693                Process.killProcessQuiet(app.pid);
7694            }
7695        }
7696    }
7697
7698    private boolean handleAppCrashLocked(ProcessRecord app) {
7699        if (mHeadless) {
7700            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7701            return false;
7702        }
7703        long now = SystemClock.uptimeMillis();
7704
7705        Long crashTime;
7706        if (!app.isolated) {
7707            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7708        } else {
7709            crashTime = null;
7710        }
7711        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7712            // This process loses!
7713            Slog.w(TAG, "Process " + app.info.processName
7714                    + " has crashed too many times: killing!");
7715            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7716                    app.info.processName, app.uid);
7717            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7718                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7719                if (r.app == app) {
7720                    Slog.w(TAG, "  Force finishing activity "
7721                        + r.intent.getComponent().flattenToShortString());
7722                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7723                }
7724            }
7725            if (!app.persistent) {
7726                // We don't want to start this process again until the user
7727                // explicitly does so...  but for persistent process, we really
7728                // need to keep it running.  If a persistent process is actually
7729                // repeatedly crashing, then badness for everyone.
7730                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7731                        app.info.processName);
7732                if (!app.isolated) {
7733                    // XXX We don't have a way to mark isolated processes
7734                    // as bad, since they don't have a peristent identity.
7735                    mBadProcesses.put(app.info.processName, app.uid, now);
7736                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7737                }
7738                app.bad = true;
7739                app.removed = true;
7740                // Don't let services in this process be restarted and potentially
7741                // annoy the user repeatedly.  Unless it is persistent, since those
7742                // processes run critical code.
7743                removeProcessLocked(app, false, false, "crash");
7744                mMainStack.resumeTopActivityLocked(null);
7745                return false;
7746            }
7747            mMainStack.resumeTopActivityLocked(null);
7748        } else {
7749            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7750            if (r != null && r.app == app) {
7751                // If the top running activity is from this crashing
7752                // process, then terminate it to avoid getting in a loop.
7753                Slog.w(TAG, "  Force finishing activity "
7754                        + r.intent.getComponent().flattenToShortString());
7755                int index = mMainStack.indexOfActivityLocked(r);
7756                r.stack.finishActivityLocked(r, index,
7757                        Activity.RESULT_CANCELED, null, "crashed");
7758                // Also terminate any activities below it that aren't yet
7759                // stopped, to avoid a situation where one will get
7760                // re-start our crashing activity once it gets resumed again.
7761                index--;
7762                if (index >= 0) {
7763                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7764                    if (r.state == ActivityState.RESUMED
7765                            || r.state == ActivityState.PAUSING
7766                            || r.state == ActivityState.PAUSED) {
7767                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7768                            Slog.w(TAG, "  Force finishing activity "
7769                                    + r.intent.getComponent().flattenToShortString());
7770                            r.stack.finishActivityLocked(r, index,
7771                                    Activity.RESULT_CANCELED, null, "crashed");
7772                        }
7773                    }
7774                }
7775            }
7776        }
7777
7778        // Bump up the crash count of any services currently running in the proc.
7779        if (app.services.size() != 0) {
7780            // Any services running in the application need to be placed
7781            // back in the pending list.
7782            Iterator<ServiceRecord> it = app.services.iterator();
7783            while (it.hasNext()) {
7784                ServiceRecord sr = it.next();
7785                sr.crashCount++;
7786            }
7787        }
7788
7789        // If the crashing process is what we consider to be the "home process" and it has been
7790        // replaced by a third-party app, clear the package preferred activities from packages
7791        // with a home activity running in the process to prevent a repeatedly crashing app
7792        // from blocking the user to manually clear the list.
7793        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7794                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7795            Iterator it = mHomeProcess.activities.iterator();
7796            while (it.hasNext()) {
7797                ActivityRecord r = (ActivityRecord)it.next();
7798                if (r.isHomeActivity) {
7799                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7800                    try {
7801                        ActivityThread.getPackageManager()
7802                                .clearPackagePreferredActivities(r.packageName);
7803                    } catch (RemoteException c) {
7804                        // pm is in same process, this will never happen.
7805                    }
7806                }
7807            }
7808        }
7809
7810        if (!app.isolated) {
7811            // XXX Can't keep track of crash times for isolated processes,
7812            // because they don't have a perisistent identity.
7813            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7814        }
7815
7816        return true;
7817    }
7818
7819    void startAppProblemLocked(ProcessRecord app) {
7820        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7821                mContext, app.info.packageName, app.info.flags);
7822        skipCurrentReceiverLocked(app);
7823    }
7824
7825    void skipCurrentReceiverLocked(ProcessRecord app) {
7826        for (BroadcastQueue queue : mBroadcastQueues) {
7827            queue.skipCurrentReceiverLocked(app);
7828        }
7829    }
7830
7831    /**
7832     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7833     * The application process will exit immediately after this call returns.
7834     * @param app object of the crashing app, null for the system server
7835     * @param crashInfo describing the exception
7836     */
7837    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7838        ProcessRecord r = findAppProcess(app, "Crash");
7839        final String processName = app == null ? "system_server"
7840                : (r == null ? "unknown" : r.processName);
7841
7842        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7843                processName,
7844                r == null ? -1 : r.info.flags,
7845                crashInfo.exceptionClassName,
7846                crashInfo.exceptionMessage,
7847                crashInfo.throwFileName,
7848                crashInfo.throwLineNumber);
7849
7850        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7851
7852        crashApplication(r, crashInfo);
7853    }
7854
7855    public void handleApplicationStrictModeViolation(
7856            IBinder app,
7857            int violationMask,
7858            StrictMode.ViolationInfo info) {
7859        ProcessRecord r = findAppProcess(app, "StrictMode");
7860        if (r == null) {
7861            return;
7862        }
7863
7864        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7865            Integer stackFingerprint = info.hashCode();
7866            boolean logIt = true;
7867            synchronized (mAlreadyLoggedViolatedStacks) {
7868                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7869                    logIt = false;
7870                    // TODO: sub-sample into EventLog for these, with
7871                    // the info.durationMillis?  Then we'd get
7872                    // the relative pain numbers, without logging all
7873                    // the stack traces repeatedly.  We'd want to do
7874                    // likewise in the client code, which also does
7875                    // dup suppression, before the Binder call.
7876                } else {
7877                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7878                        mAlreadyLoggedViolatedStacks.clear();
7879                    }
7880                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7881                }
7882            }
7883            if (logIt) {
7884                logStrictModeViolationToDropBox(r, info);
7885            }
7886        }
7887
7888        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7889            AppErrorResult result = new AppErrorResult();
7890            synchronized (this) {
7891                final long origId = Binder.clearCallingIdentity();
7892
7893                Message msg = Message.obtain();
7894                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7895                HashMap<String, Object> data = new HashMap<String, Object>();
7896                data.put("result", result);
7897                data.put("app", r);
7898                data.put("violationMask", violationMask);
7899                data.put("info", info);
7900                msg.obj = data;
7901                mHandler.sendMessage(msg);
7902
7903                Binder.restoreCallingIdentity(origId);
7904            }
7905            int res = result.get();
7906            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7907        }
7908    }
7909
7910    // Depending on the policy in effect, there could be a bunch of
7911    // these in quick succession so we try to batch these together to
7912    // minimize disk writes, number of dropbox entries, and maximize
7913    // compression, by having more fewer, larger records.
7914    private void logStrictModeViolationToDropBox(
7915            ProcessRecord process,
7916            StrictMode.ViolationInfo info) {
7917        if (info == null) {
7918            return;
7919        }
7920        final boolean isSystemApp = process == null ||
7921                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7922                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7923        final String processName = process == null ? "unknown" : process.processName;
7924        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7925        final DropBoxManager dbox = (DropBoxManager)
7926                mContext.getSystemService(Context.DROPBOX_SERVICE);
7927
7928        // Exit early if the dropbox isn't configured to accept this report type.
7929        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7930
7931        boolean bufferWasEmpty;
7932        boolean needsFlush;
7933        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7934        synchronized (sb) {
7935            bufferWasEmpty = sb.length() == 0;
7936            appendDropBoxProcessHeaders(process, processName, sb);
7937            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7938            sb.append("System-App: ").append(isSystemApp).append("\n");
7939            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7940            if (info.violationNumThisLoop != 0) {
7941                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7942            }
7943            if (info.numAnimationsRunning != 0) {
7944                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7945            }
7946            if (info.broadcastIntentAction != null) {
7947                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7948            }
7949            if (info.durationMillis != -1) {
7950                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7951            }
7952            if (info.numInstances != -1) {
7953                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7954            }
7955            if (info.tags != null) {
7956                for (String tag : info.tags) {
7957                    sb.append("Span-Tag: ").append(tag).append("\n");
7958                }
7959            }
7960            sb.append("\n");
7961            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7962                sb.append(info.crashInfo.stackTrace);
7963            }
7964            sb.append("\n");
7965
7966            // Only buffer up to ~64k.  Various logging bits truncate
7967            // things at 128k.
7968            needsFlush = (sb.length() > 64 * 1024);
7969        }
7970
7971        // Flush immediately if the buffer's grown too large, or this
7972        // is a non-system app.  Non-system apps are isolated with a
7973        // different tag & policy and not batched.
7974        //
7975        // Batching is useful during internal testing with
7976        // StrictMode settings turned up high.  Without batching,
7977        // thousands of separate files could be created on boot.
7978        if (!isSystemApp || needsFlush) {
7979            new Thread("Error dump: " + dropboxTag) {
7980                @Override
7981                public void run() {
7982                    String report;
7983                    synchronized (sb) {
7984                        report = sb.toString();
7985                        sb.delete(0, sb.length());
7986                        sb.trimToSize();
7987                    }
7988                    if (report.length() != 0) {
7989                        dbox.addText(dropboxTag, report);
7990                    }
7991                }
7992            }.start();
7993            return;
7994        }
7995
7996        // System app batching:
7997        if (!bufferWasEmpty) {
7998            // An existing dropbox-writing thread is outstanding, so
7999            // we don't need to start it up.  The existing thread will
8000            // catch the buffer appends we just did.
8001            return;
8002        }
8003
8004        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8005        // (After this point, we shouldn't access AMS internal data structures.)
8006        new Thread("Error dump: " + dropboxTag) {
8007            @Override
8008            public void run() {
8009                // 5 second sleep to let stacks arrive and be batched together
8010                try {
8011                    Thread.sleep(5000);  // 5 seconds
8012                } catch (InterruptedException e) {}
8013
8014                String errorReport;
8015                synchronized (mStrictModeBuffer) {
8016                    errorReport = mStrictModeBuffer.toString();
8017                    if (errorReport.length() == 0) {
8018                        return;
8019                    }
8020                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8021                    mStrictModeBuffer.trimToSize();
8022                }
8023                dbox.addText(dropboxTag, errorReport);
8024            }
8025        }.start();
8026    }
8027
8028    /**
8029     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8030     * @param app object of the crashing app, null for the system server
8031     * @param tag reported by the caller
8032     * @param crashInfo describing the context of the error
8033     * @return true if the process should exit immediately (WTF is fatal)
8034     */
8035    public boolean handleApplicationWtf(IBinder app, String tag,
8036            ApplicationErrorReport.CrashInfo crashInfo) {
8037        ProcessRecord r = findAppProcess(app, "WTF");
8038        final String processName = app == null ? "system_server"
8039                : (r == null ? "unknown" : r.processName);
8040
8041        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8042                processName,
8043                r == null ? -1 : r.info.flags,
8044                tag, crashInfo.exceptionMessage);
8045
8046        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8047
8048        if (r != null && r.pid != Process.myPid() &&
8049                Settings.Secure.getInt(mContext.getContentResolver(),
8050                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8051            crashApplication(r, crashInfo);
8052            return true;
8053        } else {
8054            return false;
8055        }
8056    }
8057
8058    /**
8059     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8060     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8061     */
8062    private ProcessRecord findAppProcess(IBinder app, String reason) {
8063        if (app == null) {
8064            return null;
8065        }
8066
8067        synchronized (this) {
8068            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8069                final int NA = apps.size();
8070                for (int ia=0; ia<NA; ia++) {
8071                    ProcessRecord p = apps.valueAt(ia);
8072                    if (p.thread != null && p.thread.asBinder() == app) {
8073                        return p;
8074                    }
8075                }
8076            }
8077
8078            Slog.w(TAG, "Can't find mystery application for " + reason
8079                    + " from pid=" + Binder.getCallingPid()
8080                    + " uid=" + Binder.getCallingUid() + ": " + app);
8081            return null;
8082        }
8083    }
8084
8085    /**
8086     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8087     * to append various headers to the dropbox log text.
8088     */
8089    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8090            StringBuilder sb) {
8091        // Watchdog thread ends up invoking this function (with
8092        // a null ProcessRecord) to add the stack file to dropbox.
8093        // Do not acquire a lock on this (am) in such cases, as it
8094        // could cause a potential deadlock, if and when watchdog
8095        // is invoked due to unavailability of lock on am and it
8096        // would prevent watchdog from killing system_server.
8097        if (process == null) {
8098            sb.append("Process: ").append(processName).append("\n");
8099            return;
8100        }
8101        // Note: ProcessRecord 'process' is guarded by the service
8102        // instance.  (notably process.pkgList, which could otherwise change
8103        // concurrently during execution of this method)
8104        synchronized (this) {
8105            sb.append("Process: ").append(processName).append("\n");
8106            int flags = process.info.flags;
8107            IPackageManager pm = AppGlobals.getPackageManager();
8108            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8109            for (String pkg : process.pkgList) {
8110                sb.append("Package: ").append(pkg);
8111                try {
8112                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8113                    if (pi != null) {
8114                        sb.append(" v").append(pi.versionCode);
8115                        if (pi.versionName != null) {
8116                            sb.append(" (").append(pi.versionName).append(")");
8117                        }
8118                    }
8119                } catch (RemoteException e) {
8120                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8121                }
8122                sb.append("\n");
8123            }
8124        }
8125    }
8126
8127    private static String processClass(ProcessRecord process) {
8128        if (process == null || process.pid == MY_PID) {
8129            return "system_server";
8130        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8131            return "system_app";
8132        } else {
8133            return "data_app";
8134        }
8135    }
8136
8137    /**
8138     * Write a description of an error (crash, WTF, ANR) to the drop box.
8139     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8140     * @param process which caused the error, null means the system server
8141     * @param activity which triggered the error, null if unknown
8142     * @param parent activity related to the error, null if unknown
8143     * @param subject line related to the error, null if absent
8144     * @param report in long form describing the error, null if absent
8145     * @param logFile to include in the report, null if none
8146     * @param crashInfo giving an application stack trace, null if absent
8147     */
8148    public void addErrorToDropBox(String eventType,
8149            ProcessRecord process, String processName, ActivityRecord activity,
8150            ActivityRecord parent, String subject,
8151            final String report, final File logFile,
8152            final ApplicationErrorReport.CrashInfo crashInfo) {
8153        // NOTE -- this must never acquire the ActivityManagerService lock,
8154        // otherwise the watchdog may be prevented from resetting the system.
8155
8156        final String dropboxTag = processClass(process) + "_" + eventType;
8157        final DropBoxManager dbox = (DropBoxManager)
8158                mContext.getSystemService(Context.DROPBOX_SERVICE);
8159
8160        // Exit early if the dropbox isn't configured to accept this report type.
8161        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8162
8163        final StringBuilder sb = new StringBuilder(1024);
8164        appendDropBoxProcessHeaders(process, processName, sb);
8165        if (activity != null) {
8166            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8167        }
8168        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8169            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8170        }
8171        if (parent != null && parent != activity) {
8172            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8173        }
8174        if (subject != null) {
8175            sb.append("Subject: ").append(subject).append("\n");
8176        }
8177        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8178        if (Debug.isDebuggerConnected()) {
8179            sb.append("Debugger: Connected\n");
8180        }
8181        sb.append("\n");
8182
8183        // Do the rest in a worker thread to avoid blocking the caller on I/O
8184        // (After this point, we shouldn't access AMS internal data structures.)
8185        Thread worker = new Thread("Error dump: " + dropboxTag) {
8186            @Override
8187            public void run() {
8188                if (report != null) {
8189                    sb.append(report);
8190                }
8191                if (logFile != null) {
8192                    try {
8193                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8194                    } catch (IOException e) {
8195                        Slog.e(TAG, "Error reading " + logFile, e);
8196                    }
8197                }
8198                if (crashInfo != null && crashInfo.stackTrace != null) {
8199                    sb.append(crashInfo.stackTrace);
8200                }
8201
8202                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8203                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8204                if (lines > 0) {
8205                    sb.append("\n");
8206
8207                    // Merge several logcat streams, and take the last N lines
8208                    InputStreamReader input = null;
8209                    try {
8210                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8211                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8212                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8213
8214                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8215                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8216                        input = new InputStreamReader(logcat.getInputStream());
8217
8218                        int num;
8219                        char[] buf = new char[8192];
8220                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8221                    } catch (IOException e) {
8222                        Slog.e(TAG, "Error running logcat", e);
8223                    } finally {
8224                        if (input != null) try { input.close(); } catch (IOException e) {}
8225                    }
8226                }
8227
8228                dbox.addText(dropboxTag, sb.toString());
8229            }
8230        };
8231
8232        if (process == null) {
8233            // If process is null, we are being called from some internal code
8234            // and may be about to die -- run this synchronously.
8235            worker.run();
8236        } else {
8237            worker.start();
8238        }
8239    }
8240
8241    /**
8242     * Bring up the "unexpected error" dialog box for a crashing app.
8243     * Deal with edge cases (intercepts from instrumented applications,
8244     * ActivityController, error intent receivers, that sort of thing).
8245     * @param r the application crashing
8246     * @param crashInfo describing the failure
8247     */
8248    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8249        long timeMillis = System.currentTimeMillis();
8250        String shortMsg = crashInfo.exceptionClassName;
8251        String longMsg = crashInfo.exceptionMessage;
8252        String stackTrace = crashInfo.stackTrace;
8253        if (shortMsg != null && longMsg != null) {
8254            longMsg = shortMsg + ": " + longMsg;
8255        } else if (shortMsg != null) {
8256            longMsg = shortMsg;
8257        }
8258
8259        AppErrorResult result = new AppErrorResult();
8260        synchronized (this) {
8261            if (mController != null) {
8262                try {
8263                    String name = r != null ? r.processName : null;
8264                    int pid = r != null ? r.pid : Binder.getCallingPid();
8265                    if (!mController.appCrashed(name, pid,
8266                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8267                        Slog.w(TAG, "Force-killing crashed app " + name
8268                                + " at watcher's request");
8269                        Process.killProcess(pid);
8270                        return;
8271                    }
8272                } catch (RemoteException e) {
8273                    mController = null;
8274                }
8275            }
8276
8277            final long origId = Binder.clearCallingIdentity();
8278
8279            // If this process is running instrumentation, finish it.
8280            if (r != null && r.instrumentationClass != null) {
8281                Slog.w(TAG, "Error in app " + r.processName
8282                      + " running instrumentation " + r.instrumentationClass + ":");
8283                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8284                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8285                Bundle info = new Bundle();
8286                info.putString("shortMsg", shortMsg);
8287                info.putString("longMsg", longMsg);
8288                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8289                Binder.restoreCallingIdentity(origId);
8290                return;
8291            }
8292
8293            // If we can't identify the process or it's already exceeded its crash quota,
8294            // quit right away without showing a crash dialog.
8295            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8296                Binder.restoreCallingIdentity(origId);
8297                return;
8298            }
8299
8300            Message msg = Message.obtain();
8301            msg.what = SHOW_ERROR_MSG;
8302            HashMap data = new HashMap();
8303            data.put("result", result);
8304            data.put("app", r);
8305            msg.obj = data;
8306            mHandler.sendMessage(msg);
8307
8308            Binder.restoreCallingIdentity(origId);
8309        }
8310
8311        int res = result.get();
8312
8313        Intent appErrorIntent = null;
8314        synchronized (this) {
8315            if (r != null && !r.isolated) {
8316                // XXX Can't keep track of crash time for isolated processes,
8317                // since they don't have a persistent identity.
8318                mProcessCrashTimes.put(r.info.processName, r.uid,
8319                        SystemClock.uptimeMillis());
8320            }
8321            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8322                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8323            }
8324        }
8325
8326        if (appErrorIntent != null) {
8327            try {
8328                mContext.startActivity(appErrorIntent);
8329            } catch (ActivityNotFoundException e) {
8330                Slog.w(TAG, "bug report receiver dissappeared", e);
8331            }
8332        }
8333    }
8334
8335    Intent createAppErrorIntentLocked(ProcessRecord r,
8336            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8337        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8338        if (report == null) {
8339            return null;
8340        }
8341        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8342        result.setComponent(r.errorReportReceiver);
8343        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8344        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8345        return result;
8346    }
8347
8348    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8349            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8350        if (r.errorReportReceiver == null) {
8351            return null;
8352        }
8353
8354        if (!r.crashing && !r.notResponding) {
8355            return null;
8356        }
8357
8358        ApplicationErrorReport report = new ApplicationErrorReport();
8359        report.packageName = r.info.packageName;
8360        report.installerPackageName = r.errorReportReceiver.getPackageName();
8361        report.processName = r.processName;
8362        report.time = timeMillis;
8363        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8364
8365        if (r.crashing) {
8366            report.type = ApplicationErrorReport.TYPE_CRASH;
8367            report.crashInfo = crashInfo;
8368        } else if (r.notResponding) {
8369            report.type = ApplicationErrorReport.TYPE_ANR;
8370            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8371
8372            report.anrInfo.activity = r.notRespondingReport.tag;
8373            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8374            report.anrInfo.info = r.notRespondingReport.longMsg;
8375        }
8376
8377        return report;
8378    }
8379
8380    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8381        enforceNotIsolatedCaller("getProcessesInErrorState");
8382        // assume our apps are happy - lazy create the list
8383        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8384
8385        synchronized (this) {
8386
8387            // iterate across all processes
8388            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8389                ProcessRecord app = mLruProcesses.get(i);
8390                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8391                    // This one's in trouble, so we'll generate a report for it
8392                    // crashes are higher priority (in case there's a crash *and* an anr)
8393                    ActivityManager.ProcessErrorStateInfo report = null;
8394                    if (app.crashing) {
8395                        report = app.crashingReport;
8396                    } else if (app.notResponding) {
8397                        report = app.notRespondingReport;
8398                    }
8399
8400                    if (report != null) {
8401                        if (errList == null) {
8402                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8403                        }
8404                        errList.add(report);
8405                    } else {
8406                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8407                                " crashing = " + app.crashing +
8408                                " notResponding = " + app.notResponding);
8409                    }
8410                }
8411            }
8412        }
8413
8414        return errList;
8415    }
8416
8417    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8418        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8419            if (currApp != null) {
8420                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8421            }
8422            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8423        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8424            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8425        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8426            if (currApp != null) {
8427                currApp.lru = 0;
8428            }
8429            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8430        } else if (adj >= ProcessList.SERVICE_ADJ) {
8431            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8432        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8433            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8434        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8435            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8436        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8437            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8438        } else {
8439            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8440        }
8441    }
8442
8443    private void fillInProcMemInfo(ProcessRecord app,
8444            ActivityManager.RunningAppProcessInfo outInfo) {
8445        outInfo.pid = app.pid;
8446        outInfo.uid = app.info.uid;
8447        if (mHeavyWeightProcess == app) {
8448            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8449        }
8450        if (app.persistent) {
8451            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8452        }
8453        outInfo.lastTrimLevel = app.trimMemoryLevel;
8454        int adj = app.curAdj;
8455        outInfo.importance = oomAdjToImportance(adj, outInfo);
8456        outInfo.importanceReasonCode = app.adjTypeCode;
8457    }
8458
8459    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8460        enforceNotIsolatedCaller("getRunningAppProcesses");
8461        // Lazy instantiation of list
8462        List<ActivityManager.RunningAppProcessInfo> runList = null;
8463        synchronized (this) {
8464            // Iterate across all processes
8465            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8466                ProcessRecord app = mLruProcesses.get(i);
8467                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8468                    // Generate process state info for running application
8469                    ActivityManager.RunningAppProcessInfo currApp =
8470                        new ActivityManager.RunningAppProcessInfo(app.processName,
8471                                app.pid, app.getPackageList());
8472                    fillInProcMemInfo(app, currApp);
8473                    if (app.adjSource instanceof ProcessRecord) {
8474                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8475                        currApp.importanceReasonImportance = oomAdjToImportance(
8476                                app.adjSourceOom, null);
8477                    } else if (app.adjSource instanceof ActivityRecord) {
8478                        ActivityRecord r = (ActivityRecord)app.adjSource;
8479                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8480                    }
8481                    if (app.adjTarget instanceof ComponentName) {
8482                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8483                    }
8484                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8485                    //        + " lru=" + currApp.lru);
8486                    if (runList == null) {
8487                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8488                    }
8489                    runList.add(currApp);
8490                }
8491            }
8492        }
8493        return runList;
8494    }
8495
8496    public List<ApplicationInfo> getRunningExternalApplications() {
8497        enforceNotIsolatedCaller("getRunningExternalApplications");
8498        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8499        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8500        if (runningApps != null && runningApps.size() > 0) {
8501            Set<String> extList = new HashSet<String>();
8502            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8503                if (app.pkgList != null) {
8504                    for (String pkg : app.pkgList) {
8505                        extList.add(pkg);
8506                    }
8507                }
8508            }
8509            IPackageManager pm = AppGlobals.getPackageManager();
8510            for (String pkg : extList) {
8511                try {
8512                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8513                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8514                        retList.add(info);
8515                    }
8516                } catch (RemoteException e) {
8517                }
8518            }
8519        }
8520        return retList;
8521    }
8522
8523    @Override
8524    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8525        enforceNotIsolatedCaller("getMyMemoryState");
8526        synchronized (this) {
8527            ProcessRecord proc;
8528            synchronized (mPidsSelfLocked) {
8529                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8530            }
8531            fillInProcMemInfo(proc, outInfo);
8532        }
8533    }
8534
8535    @Override
8536    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8537        if (checkCallingPermission(android.Manifest.permission.DUMP)
8538                != PackageManager.PERMISSION_GRANTED) {
8539            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8540                    + Binder.getCallingPid()
8541                    + ", uid=" + Binder.getCallingUid()
8542                    + " without permission "
8543                    + android.Manifest.permission.DUMP);
8544            return;
8545        }
8546
8547        boolean dumpAll = false;
8548        boolean dumpClient = false;
8549        String dumpPackage = null;
8550
8551        int opti = 0;
8552        while (opti < args.length) {
8553            String opt = args[opti];
8554            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8555                break;
8556            }
8557            opti++;
8558            if ("-a".equals(opt)) {
8559                dumpAll = true;
8560            } else if ("-c".equals(opt)) {
8561                dumpClient = true;
8562            } else if ("-h".equals(opt)) {
8563                pw.println("Activity manager dump options:");
8564                pw.println("  [-a] [-c] [-h] [cmd] ...");
8565                pw.println("  cmd may be one of:");
8566                pw.println("    a[ctivities]: activity stack state");
8567                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8568                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8569                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8570                pw.println("    o[om]: out of memory management");
8571                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8572                pw.println("    provider [COMP_SPEC]: provider client-side state");
8573                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8574                pw.println("    service [COMP_SPEC]: service client-side state");
8575                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8576                pw.println("    all: dump all activities");
8577                pw.println("    top: dump the top activity");
8578                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8579                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8580                pw.println("    a partial substring in a component name, a");
8581                pw.println("    hex object identifier.");
8582                pw.println("  -a: include all available server state.");
8583                pw.println("  -c: include client state.");
8584                return;
8585            } else {
8586                pw.println("Unknown argument: " + opt + "; use -h for help");
8587            }
8588        }
8589
8590        long origId = Binder.clearCallingIdentity();
8591        boolean more = false;
8592        // Is the caller requesting to dump a particular piece of data?
8593        if (opti < args.length) {
8594            String cmd = args[opti];
8595            opti++;
8596            if ("activities".equals(cmd) || "a".equals(cmd)) {
8597                synchronized (this) {
8598                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8599                }
8600            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8601                String[] newArgs;
8602                String name;
8603                if (opti >= args.length) {
8604                    name = null;
8605                    newArgs = EMPTY_STRING_ARRAY;
8606                } else {
8607                    name = args[opti];
8608                    opti++;
8609                    newArgs = new String[args.length - opti];
8610                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8611                            args.length - opti);
8612                }
8613                synchronized (this) {
8614                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8615                }
8616            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8617                String[] newArgs;
8618                String name;
8619                if (opti >= args.length) {
8620                    name = null;
8621                    newArgs = EMPTY_STRING_ARRAY;
8622                } else {
8623                    name = args[opti];
8624                    opti++;
8625                    newArgs = new String[args.length - opti];
8626                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8627                            args.length - opti);
8628                }
8629                synchronized (this) {
8630                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8631                }
8632            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8633                String[] newArgs;
8634                String name;
8635                if (opti >= args.length) {
8636                    name = null;
8637                    newArgs = EMPTY_STRING_ARRAY;
8638                } else {
8639                    name = args[opti];
8640                    opti++;
8641                    newArgs = new String[args.length - opti];
8642                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8643                            args.length - opti);
8644                }
8645                synchronized (this) {
8646                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8647                }
8648            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8649                synchronized (this) {
8650                    dumpOomLocked(fd, pw, args, opti, true);
8651                }
8652            } else if ("provider".equals(cmd)) {
8653                String[] newArgs;
8654                String name;
8655                if (opti >= args.length) {
8656                    name = null;
8657                    newArgs = EMPTY_STRING_ARRAY;
8658                } else {
8659                    name = args[opti];
8660                    opti++;
8661                    newArgs = new String[args.length - opti];
8662                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8663                }
8664                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8665                    pw.println("No providers match: " + name);
8666                    pw.println("Use -h for help.");
8667                }
8668            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8669                synchronized (this) {
8670                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8671                }
8672            } else if ("service".equals(cmd)) {
8673                String[] newArgs;
8674                String name;
8675                if (opti >= args.length) {
8676                    name = null;
8677                    newArgs = EMPTY_STRING_ARRAY;
8678                } else {
8679                    name = args[opti];
8680                    opti++;
8681                    newArgs = new String[args.length - opti];
8682                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8683                            args.length - opti);
8684                }
8685                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8686                    pw.println("No services match: " + name);
8687                    pw.println("Use -h for help.");
8688                }
8689            } else if ("package".equals(cmd)) {
8690                String[] newArgs;
8691                if (opti >= args.length) {
8692                    pw.println("package: no package name specified");
8693                    pw.println("Use -h for help.");
8694                } else {
8695                    dumpPackage = args[opti];
8696                    opti++;
8697                    newArgs = new String[args.length - opti];
8698                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8699                            args.length - opti);
8700                    args = newArgs;
8701                    opti = 0;
8702                    more = true;
8703                }
8704            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8705                synchronized (this) {
8706                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8707                }
8708            } else {
8709                // Dumping a single activity?
8710                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8711                    pw.println("Bad activity command, or no activities match: " + cmd);
8712                    pw.println("Use -h for help.");
8713                }
8714            }
8715            if (!more) {
8716                Binder.restoreCallingIdentity(origId);
8717                return;
8718            }
8719        }
8720
8721        // No piece of data specified, dump everything.
8722        synchronized (this) {
8723            boolean needSep;
8724            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8725            if (needSep) {
8726                pw.println(" ");
8727            }
8728            if (dumpAll) {
8729                pw.println("-------------------------------------------------------------------------------");
8730            }
8731            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8732            if (needSep) {
8733                pw.println(" ");
8734            }
8735            if (dumpAll) {
8736                pw.println("-------------------------------------------------------------------------------");
8737            }
8738            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8739            if (needSep) {
8740                pw.println(" ");
8741            }
8742            if (dumpAll) {
8743                pw.println("-------------------------------------------------------------------------------");
8744            }
8745            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8746            if (needSep) {
8747                pw.println(" ");
8748            }
8749            if (dumpAll) {
8750                pw.println("-------------------------------------------------------------------------------");
8751            }
8752            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8753            if (needSep) {
8754                pw.println(" ");
8755            }
8756            if (dumpAll) {
8757                pw.println("-------------------------------------------------------------------------------");
8758            }
8759            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8760        }
8761        Binder.restoreCallingIdentity(origId);
8762    }
8763
8764    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8765            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8766        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8767        pw.println("  Main stack:");
8768        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8769                dumpPackage);
8770        pw.println(" ");
8771        pw.println("  Running activities (most recent first):");
8772        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8773                dumpPackage);
8774        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8775            pw.println(" ");
8776            pw.println("  Activities waiting for another to become visible:");
8777            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8778                    !dumpAll, false, dumpPackage);
8779        }
8780        if (mMainStack.mStoppingActivities.size() > 0) {
8781            pw.println(" ");
8782            pw.println("  Activities waiting to stop:");
8783            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8784                    !dumpAll, false, dumpPackage);
8785        }
8786        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8787            pw.println(" ");
8788            pw.println("  Activities waiting to sleep:");
8789            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8790                    !dumpAll, false, dumpPackage);
8791        }
8792        if (mMainStack.mFinishingActivities.size() > 0) {
8793            pw.println(" ");
8794            pw.println("  Activities waiting to finish:");
8795            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8796                    !dumpAll, false, dumpPackage);
8797        }
8798
8799        pw.println(" ");
8800        if (mMainStack.mPausingActivity != null) {
8801            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8802        }
8803        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8804        pw.println("  mFocusedActivity: " + mFocusedActivity);
8805        if (dumpAll) {
8806            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8807            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8808            pw.println("  mDismissKeyguardOnNextActivity: "
8809                    + mMainStack.mDismissKeyguardOnNextActivity);
8810        }
8811
8812        if (mRecentTasks.size() > 0) {
8813            pw.println();
8814            pw.println("  Recent tasks:");
8815
8816            final int N = mRecentTasks.size();
8817            for (int i=0; i<N; i++) {
8818                TaskRecord tr = mRecentTasks.get(i);
8819                if (dumpPackage != null) {
8820                    if (tr.realActivity == null ||
8821                            !dumpPackage.equals(tr.realActivity)) {
8822                        continue;
8823                    }
8824                }
8825                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8826                        pw.println(tr);
8827                if (dumpAll) {
8828                    mRecentTasks.get(i).dump(pw, "    ");
8829                }
8830            }
8831        }
8832
8833        if (dumpAll) {
8834            pw.println(" ");
8835            pw.println("  mCurTask: " + mCurTask);
8836        }
8837
8838        return true;
8839    }
8840
8841    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8842            int opti, boolean dumpAll, String dumpPackage) {
8843        boolean needSep = false;
8844        int numPers = 0;
8845
8846        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8847
8848        if (dumpAll) {
8849            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8850                final int NA = procs.size();
8851                for (int ia=0; ia<NA; ia++) {
8852                    ProcessRecord r = procs.valueAt(ia);
8853                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8854                        continue;
8855                    }
8856                    if (!needSep) {
8857                        pw.println("  All known processes:");
8858                        needSep = true;
8859                    }
8860                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8861                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8862                        pw.print(" "); pw.println(r);
8863                    r.dump(pw, "    ");
8864                    if (r.persistent) {
8865                        numPers++;
8866                    }
8867                }
8868            }
8869        }
8870
8871        if (mIsolatedProcesses.size() > 0) {
8872            if (needSep) pw.println(" ");
8873            needSep = true;
8874            pw.println("  Isolated process list (sorted by uid):");
8875            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8876                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8877                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8878                    continue;
8879                }
8880                pw.println(String.format("%sIsolated #%2d: %s",
8881                        "    ", i, r.toString()));
8882            }
8883        }
8884
8885        if (mLruProcesses.size() > 0) {
8886            if (needSep) pw.println(" ");
8887            needSep = true;
8888            pw.println("  Process LRU list (sorted by oom_adj):");
8889            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8890                    "Proc", "PERS", false, dumpPackage);
8891            needSep = true;
8892        }
8893
8894        if (dumpAll) {
8895            synchronized (mPidsSelfLocked) {
8896                boolean printed = false;
8897                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8898                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8899                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8900                        continue;
8901                    }
8902                    if (!printed) {
8903                        if (needSep) pw.println(" ");
8904                        needSep = true;
8905                        pw.println("  PID mappings:");
8906                        printed = true;
8907                    }
8908                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8909                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8910                }
8911            }
8912        }
8913
8914        if (mForegroundProcesses.size() > 0) {
8915            synchronized (mPidsSelfLocked) {
8916                boolean printed = false;
8917                for (int i=0; i<mForegroundProcesses.size(); i++) {
8918                    ProcessRecord r = mPidsSelfLocked.get(
8919                            mForegroundProcesses.valueAt(i).pid);
8920                    if (dumpPackage != null && (r == null
8921                            || !dumpPackage.equals(r.info.packageName))) {
8922                        continue;
8923                    }
8924                    if (!printed) {
8925                        if (needSep) pw.println(" ");
8926                        needSep = true;
8927                        pw.println("  Foreground Processes:");
8928                        printed = true;
8929                    }
8930                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8931                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8932                }
8933            }
8934        }
8935
8936        if (mPersistentStartingProcesses.size() > 0) {
8937            if (needSep) pw.println(" ");
8938            needSep = true;
8939            pw.println("  Persisent processes that are starting:");
8940            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8941                    "Starting Norm", "Restarting PERS", dumpPackage);
8942        }
8943
8944        if (mRemovedProcesses.size() > 0) {
8945            if (needSep) pw.println(" ");
8946            needSep = true;
8947            pw.println("  Processes that are being removed:");
8948            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8949                    "Removed Norm", "Removed PERS", dumpPackage);
8950        }
8951
8952        if (mProcessesOnHold.size() > 0) {
8953            if (needSep) pw.println(" ");
8954            needSep = true;
8955            pw.println("  Processes that are on old until the system is ready:");
8956            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8957                    "OnHold Norm", "OnHold PERS", dumpPackage);
8958        }
8959
8960        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8961
8962        if (mProcessCrashTimes.getMap().size() > 0) {
8963            boolean printed = false;
8964            long now = SystemClock.uptimeMillis();
8965            for (Map.Entry<String, SparseArray<Long>> procs
8966                    : mProcessCrashTimes.getMap().entrySet()) {
8967                String pname = procs.getKey();
8968                SparseArray<Long> uids = procs.getValue();
8969                final int N = uids.size();
8970                for (int i=0; i<N; i++) {
8971                    int puid = uids.keyAt(i);
8972                    ProcessRecord r = mProcessNames.get(pname, puid);
8973                    if (dumpPackage != null && (r == null
8974                            || !dumpPackage.equals(r.info.packageName))) {
8975                        continue;
8976                    }
8977                    if (!printed) {
8978                        if (needSep) pw.println(" ");
8979                        needSep = true;
8980                        pw.println("  Time since processes crashed:");
8981                        printed = true;
8982                    }
8983                    pw.print("    Process "); pw.print(pname);
8984                            pw.print(" uid "); pw.print(puid);
8985                            pw.print(": last crashed ");
8986                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
8987                            pw.println(" ago");
8988                }
8989            }
8990        }
8991
8992        if (mBadProcesses.getMap().size() > 0) {
8993            boolean printed = false;
8994            for (Map.Entry<String, SparseArray<Long>> procs
8995                    : mBadProcesses.getMap().entrySet()) {
8996                String pname = procs.getKey();
8997                SparseArray<Long> uids = procs.getValue();
8998                final int N = uids.size();
8999                for (int i=0; i<N; i++) {
9000                    int puid = uids.keyAt(i);
9001                    ProcessRecord r = mProcessNames.get(pname, puid);
9002                    if (dumpPackage != null && (r == null
9003                            || !dumpPackage.equals(r.info.packageName))) {
9004                        continue;
9005                    }
9006                    if (!printed) {
9007                        if (needSep) pw.println(" ");
9008                        needSep = true;
9009                        pw.println("  Bad processes:");
9010                    }
9011                    pw.print("    Bad process "); pw.print(pname);
9012                            pw.print(" uid "); pw.print(puid);
9013                            pw.print(": crashed at time ");
9014                            pw.println(uids.valueAt(i));
9015                }
9016            }
9017        }
9018
9019        pw.println();
9020        pw.println("  mHomeProcess: " + mHomeProcess);
9021        pw.println("  mPreviousProcess: " + mPreviousProcess);
9022        if (dumpAll) {
9023            StringBuilder sb = new StringBuilder(128);
9024            sb.append("  mPreviousProcessVisibleTime: ");
9025            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9026            pw.println(sb);
9027        }
9028        if (mHeavyWeightProcess != null) {
9029            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9030        }
9031        pw.println("  mConfiguration: " + mConfiguration);
9032        if (dumpAll) {
9033            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9034            if (mCompatModePackages.getPackages().size() > 0) {
9035                boolean printed = false;
9036                for (Map.Entry<String, Integer> entry
9037                        : mCompatModePackages.getPackages().entrySet()) {
9038                    String pkg = entry.getKey();
9039                    int mode = entry.getValue();
9040                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9041                        continue;
9042                    }
9043                    if (!printed) {
9044                        pw.println("  mScreenCompatPackages:");
9045                        printed = true;
9046                    }
9047                    pw.print("    "); pw.print(pkg); pw.print(": ");
9048                            pw.print(mode); pw.println();
9049                }
9050            }
9051        }
9052        if (mSleeping || mWentToSleep || mLockScreenShown) {
9053            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9054                    + " mLockScreenShown " + mLockScreenShown);
9055        }
9056        if (mShuttingDown) {
9057            pw.println("  mShuttingDown=" + mShuttingDown);
9058        }
9059        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9060                || mOrigWaitForDebugger) {
9061            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9062                    + " mDebugTransient=" + mDebugTransient
9063                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9064        }
9065        if (mOpenGlTraceApp != null) {
9066            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9067        }
9068        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9069                || mProfileFd != null) {
9070            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9071            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9072            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9073                    + mAutoStopProfiler);
9074        }
9075        if (mAlwaysFinishActivities || mController != null) {
9076            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9077                    + " mController=" + mController);
9078        }
9079        if (dumpAll) {
9080            pw.println("  Total persistent processes: " + numPers);
9081            pw.println("  mStartRunning=" + mStartRunning
9082                    + " mProcessesReady=" + mProcessesReady
9083                    + " mSystemReady=" + mSystemReady);
9084            pw.println("  mBooting=" + mBooting
9085                    + " mBooted=" + mBooted
9086                    + " mFactoryTest=" + mFactoryTest);
9087            pw.print("  mLastPowerCheckRealtime=");
9088                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9089                    pw.println("");
9090            pw.print("  mLastPowerCheckUptime=");
9091                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9092                    pw.println("");
9093            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9094            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9095            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9096            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9097                    + " mNumHiddenProcs=" + mNumHiddenProcs
9098                    + " mNumServiceProcs=" + mNumServiceProcs
9099                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9100        }
9101
9102        return true;
9103    }
9104
9105    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9106            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9107        if (mProcessesToGc.size() > 0) {
9108            boolean printed = false;
9109            long now = SystemClock.uptimeMillis();
9110            for (int i=0; i<mProcessesToGc.size(); i++) {
9111                ProcessRecord proc = mProcessesToGc.get(i);
9112                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9113                    continue;
9114                }
9115                if (!printed) {
9116                    if (needSep) pw.println(" ");
9117                    needSep = true;
9118                    pw.println("  Processes that are waiting to GC:");
9119                    printed = true;
9120                }
9121                pw.print("    Process "); pw.println(proc);
9122                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9123                        pw.print(", last gced=");
9124                        pw.print(now-proc.lastRequestedGc);
9125                        pw.print(" ms ago, last lowMem=");
9126                        pw.print(now-proc.lastLowMemory);
9127                        pw.println(" ms ago");
9128
9129            }
9130        }
9131        return needSep;
9132    }
9133
9134    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9135            int opti, boolean dumpAll) {
9136        boolean needSep = false;
9137
9138        if (mLruProcesses.size() > 0) {
9139            if (needSep) pw.println(" ");
9140            needSep = true;
9141            pw.println("  OOM levels:");
9142            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9143            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9144            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9145            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9146            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9147            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9148            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9149            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9150            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9151            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9152            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9153            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9154            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9155
9156            if (needSep) pw.println(" ");
9157            needSep = true;
9158            pw.println("  Process OOM control:");
9159            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9160                    "Proc", "PERS", true, null);
9161            needSep = true;
9162        }
9163
9164        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9165
9166        pw.println();
9167        pw.println("  mHomeProcess: " + mHomeProcess);
9168        pw.println("  mPreviousProcess: " + mPreviousProcess);
9169        if (mHeavyWeightProcess != null) {
9170            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9171        }
9172
9173        return true;
9174    }
9175
9176    /**
9177     * There are three ways to call this:
9178     *  - no provider specified: dump all the providers
9179     *  - a flattened component name that matched an existing provider was specified as the
9180     *    first arg: dump that one provider
9181     *  - the first arg isn't the flattened component name of an existing provider:
9182     *    dump all providers whose component contains the first arg as a substring
9183     */
9184    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9185            int opti, boolean dumpAll) {
9186        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9187    }
9188
9189    static class ItemMatcher {
9190        ArrayList<ComponentName> components;
9191        ArrayList<String> strings;
9192        ArrayList<Integer> objects;
9193        boolean all;
9194
9195        ItemMatcher() {
9196            all = true;
9197        }
9198
9199        void build(String name) {
9200            ComponentName componentName = ComponentName.unflattenFromString(name);
9201            if (componentName != null) {
9202                if (components == null) {
9203                    components = new ArrayList<ComponentName>();
9204                }
9205                components.add(componentName);
9206                all = false;
9207            } else {
9208                int objectId = 0;
9209                // Not a '/' separated full component name; maybe an object ID?
9210                try {
9211                    objectId = Integer.parseInt(name, 16);
9212                    if (objects == null) {
9213                        objects = new ArrayList<Integer>();
9214                    }
9215                    objects.add(objectId);
9216                    all = false;
9217                } catch (RuntimeException e) {
9218                    // Not an integer; just do string match.
9219                    if (strings == null) {
9220                        strings = new ArrayList<String>();
9221                    }
9222                    strings.add(name);
9223                    all = false;
9224                }
9225            }
9226        }
9227
9228        int build(String[] args, int opti) {
9229            for (; opti<args.length; opti++) {
9230                String name = args[opti];
9231                if ("--".equals(name)) {
9232                    return opti+1;
9233                }
9234                build(name);
9235            }
9236            return opti;
9237        }
9238
9239        boolean match(Object object, ComponentName comp) {
9240            if (all) {
9241                return true;
9242            }
9243            if (components != null) {
9244                for (int i=0; i<components.size(); i++) {
9245                    if (components.get(i).equals(comp)) {
9246                        return true;
9247                    }
9248                }
9249            }
9250            if (objects != null) {
9251                for (int i=0; i<objects.size(); i++) {
9252                    if (System.identityHashCode(object) == objects.get(i)) {
9253                        return true;
9254                    }
9255                }
9256            }
9257            if (strings != null) {
9258                String flat = comp.flattenToString();
9259                for (int i=0; i<strings.size(); i++) {
9260                    if (flat.contains(strings.get(i))) {
9261                        return true;
9262                    }
9263                }
9264            }
9265            return false;
9266        }
9267    }
9268
9269    /**
9270     * There are three things that cmd can be:
9271     *  - a flattened component name that matches an existing activity
9272     *  - the cmd arg isn't the flattened component name of an existing activity:
9273     *    dump all activity whose component contains the cmd as a substring
9274     *  - A hex number of the ActivityRecord object instance.
9275     */
9276    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9277            int opti, boolean dumpAll) {
9278        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9279
9280        if ("all".equals(name)) {
9281            synchronized (this) {
9282                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9283                    activities.add(r1);
9284                }
9285            }
9286        } else if ("top".equals(name)) {
9287            synchronized (this) {
9288                final int N = mMainStack.mHistory.size();
9289                if (N > 0) {
9290                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9291                }
9292            }
9293        } else {
9294            ItemMatcher matcher = new ItemMatcher();
9295            matcher.build(name);
9296
9297            synchronized (this) {
9298                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9299                    if (matcher.match(r1, r1.intent.getComponent())) {
9300                        activities.add(r1);
9301                    }
9302                }
9303            }
9304        }
9305
9306        if (activities.size() <= 0) {
9307            return false;
9308        }
9309
9310        String[] newArgs = new String[args.length - opti];
9311        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9312
9313        TaskRecord lastTask = null;
9314        boolean needSep = false;
9315        for (int i=activities.size()-1; i>=0; i--) {
9316            ActivityRecord r = (ActivityRecord)activities.get(i);
9317            if (needSep) {
9318                pw.println();
9319            }
9320            needSep = true;
9321            synchronized (this) {
9322                if (lastTask != r.task) {
9323                    lastTask = r.task;
9324                    pw.print("TASK "); pw.print(lastTask.affinity);
9325                            pw.print(" id="); pw.println(lastTask.taskId);
9326                    if (dumpAll) {
9327                        lastTask.dump(pw, "  ");
9328                    }
9329                }
9330            }
9331            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9332        }
9333        return true;
9334    }
9335
9336    /**
9337     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9338     * there is a thread associated with the activity.
9339     */
9340    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9341            final ActivityRecord r, String[] args, boolean dumpAll) {
9342        String innerPrefix = prefix + "  ";
9343        synchronized (this) {
9344            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9345                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9346                    pw.print(" pid=");
9347                    if (r.app != null) pw.println(r.app.pid);
9348                    else pw.println("(not running)");
9349            if (dumpAll) {
9350                r.dump(pw, innerPrefix);
9351            }
9352        }
9353        if (r.app != null && r.app.thread != null) {
9354            // flush anything that is already in the PrintWriter since the thread is going
9355            // to write to the file descriptor directly
9356            pw.flush();
9357            try {
9358                TransferPipe tp = new TransferPipe();
9359                try {
9360                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9361                            r.appToken, innerPrefix, args);
9362                    tp.go(fd);
9363                } finally {
9364                    tp.kill();
9365                }
9366            } catch (IOException e) {
9367                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9368            } catch (RemoteException e) {
9369                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9370            }
9371        }
9372    }
9373
9374    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9375            int opti, boolean dumpAll, String dumpPackage) {
9376        boolean needSep = false;
9377
9378        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9379        if (dumpAll) {
9380            if (mRegisteredReceivers.size() > 0) {
9381                boolean printed = false;
9382                Iterator it = mRegisteredReceivers.values().iterator();
9383                while (it.hasNext()) {
9384                    ReceiverList r = (ReceiverList)it.next();
9385                    if (dumpPackage != null && (r.app == null ||
9386                            !dumpPackage.equals(r.app.info.packageName))) {
9387                        continue;
9388                    }
9389                    if (!printed) {
9390                        pw.println("  Registered Receivers:");
9391                        needSep = true;
9392                        printed = true;
9393                    }
9394                    pw.print("  * "); pw.println(r);
9395                    r.dump(pw, "    ");
9396                }
9397            }
9398
9399            if (mReceiverResolver.dump(pw, needSep ?
9400                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9401                    "    ", dumpPackage, false)) {
9402                needSep = true;
9403            }
9404        }
9405
9406        for (BroadcastQueue q : mBroadcastQueues) {
9407            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9408        }
9409
9410        needSep = true;
9411
9412        if (mStickyBroadcasts != null && dumpPackage == null) {
9413            if (needSep) {
9414                pw.println();
9415            }
9416            needSep = true;
9417            pw.println("  Sticky broadcasts:");
9418            StringBuilder sb = new StringBuilder(128);
9419            for (Map.Entry<String, ArrayList<Intent>> ent
9420                    : mStickyBroadcasts.entrySet()) {
9421                pw.print("  * Sticky action "); pw.print(ent.getKey());
9422                if (dumpAll) {
9423                    pw.println(":");
9424                    ArrayList<Intent> intents = ent.getValue();
9425                    final int N = intents.size();
9426                    for (int i=0; i<N; i++) {
9427                        sb.setLength(0);
9428                        sb.append("    Intent: ");
9429                        intents.get(i).toShortString(sb, false, true, false, false);
9430                        pw.println(sb.toString());
9431                        Bundle bundle = intents.get(i).getExtras();
9432                        if (bundle != null) {
9433                            pw.print("      ");
9434                            pw.println(bundle.toString());
9435                        }
9436                    }
9437                } else {
9438                    pw.println("");
9439                }
9440            }
9441            needSep = true;
9442        }
9443
9444        if (dumpAll) {
9445            pw.println();
9446            for (BroadcastQueue queue : mBroadcastQueues) {
9447                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9448                        + queue.mBroadcastsScheduled);
9449            }
9450            pw.println("  mHandler:");
9451            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9452            needSep = true;
9453        }
9454
9455        return needSep;
9456    }
9457
9458    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9459            int opti, boolean dumpAll, String dumpPackage) {
9460        boolean needSep = true;
9461
9462        ItemMatcher matcher = new ItemMatcher();
9463        matcher.build(args, opti);
9464
9465        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9466
9467        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9468
9469        if (mLaunchingProviders.size() > 0) {
9470            boolean printed = false;
9471            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9472                ContentProviderRecord r = mLaunchingProviders.get(i);
9473                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9474                    continue;
9475                }
9476                if (!printed) {
9477                    if (needSep) pw.println(" ");
9478                    needSep = true;
9479                    pw.println("  Launching content providers:");
9480                    printed = true;
9481                }
9482                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9483                        pw.println(r);
9484            }
9485        }
9486
9487        if (mGrantedUriPermissions.size() > 0) {
9488            if (needSep) pw.println();
9489            needSep = true;
9490            pw.println("Granted Uri Permissions:");
9491            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9492                int uid = mGrantedUriPermissions.keyAt(i);
9493                HashMap<Uri, UriPermission> perms
9494                        = mGrantedUriPermissions.valueAt(i);
9495                pw.print("  * UID "); pw.print(uid);
9496                        pw.println(" holds:");
9497                for (UriPermission perm : perms.values()) {
9498                    pw.print("    "); pw.println(perm);
9499                    if (dumpAll) {
9500                        perm.dump(pw, "      ");
9501                    }
9502                }
9503            }
9504            needSep = true;
9505        }
9506
9507        return needSep;
9508    }
9509
9510    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9511            int opti, boolean dumpAll, String dumpPackage) {
9512        boolean needSep = false;
9513
9514        if (mIntentSenderRecords.size() > 0) {
9515            boolean printed = false;
9516            Iterator<WeakReference<PendingIntentRecord>> it
9517                    = mIntentSenderRecords.values().iterator();
9518            while (it.hasNext()) {
9519                WeakReference<PendingIntentRecord> ref = it.next();
9520                PendingIntentRecord rec = ref != null ? ref.get(): null;
9521                if (dumpPackage != null && (rec == null
9522                        || !dumpPackage.equals(rec.key.packageName))) {
9523                    continue;
9524                }
9525                if (!printed) {
9526                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9527                    printed = true;
9528                }
9529                needSep = true;
9530                if (rec != null) {
9531                    pw.print("  * "); pw.println(rec);
9532                    if (dumpAll) {
9533                        rec.dump(pw, "    ");
9534                    }
9535                } else {
9536                    pw.print("  * "); pw.println(ref);
9537                }
9538            }
9539        }
9540
9541        return needSep;
9542    }
9543
9544    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9545            String prefix, String label, boolean complete, boolean brief, boolean client,
9546            String dumpPackage) {
9547        TaskRecord lastTask = null;
9548        boolean needNL = false;
9549        final String innerPrefix = prefix + "      ";
9550        final String[] args = new String[0];
9551        for (int i=list.size()-1; i>=0; i--) {
9552            final ActivityRecord r = (ActivityRecord)list.get(i);
9553            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9554                continue;
9555            }
9556            final boolean full = !brief && (complete || !r.isInHistory());
9557            if (needNL) {
9558                pw.println(" ");
9559                needNL = false;
9560            }
9561            if (lastTask != r.task) {
9562                lastTask = r.task;
9563                pw.print(prefix);
9564                pw.print(full ? "* " : "  ");
9565                pw.println(lastTask);
9566                if (full) {
9567                    lastTask.dump(pw, prefix + "  ");
9568                } else if (complete) {
9569                    // Complete + brief == give a summary.  Isn't that obvious?!?
9570                    if (lastTask.intent != null) {
9571                        pw.print(prefix); pw.print("  ");
9572                                pw.println(lastTask.intent.toInsecureStringWithClip());
9573                    }
9574                }
9575            }
9576            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9577            pw.print(" #"); pw.print(i); pw.print(": ");
9578            pw.println(r);
9579            if (full) {
9580                r.dump(pw, innerPrefix);
9581            } else if (complete) {
9582                // Complete + brief == give a summary.  Isn't that obvious?!?
9583                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9584                if (r.app != null) {
9585                    pw.print(innerPrefix); pw.println(r.app);
9586                }
9587            }
9588            if (client && r.app != null && r.app.thread != null) {
9589                // flush anything that is already in the PrintWriter since the thread is going
9590                // to write to the file descriptor directly
9591                pw.flush();
9592                try {
9593                    TransferPipe tp = new TransferPipe();
9594                    try {
9595                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9596                                r.appToken, innerPrefix, args);
9597                        // Short timeout, since blocking here can
9598                        // deadlock with the application.
9599                        tp.go(fd, 2000);
9600                    } finally {
9601                        tp.kill();
9602                    }
9603                } catch (IOException e) {
9604                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9605                } catch (RemoteException e) {
9606                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9607                }
9608                needNL = true;
9609            }
9610        }
9611    }
9612
9613    private static String buildOomTag(String prefix, String space, int val, int base) {
9614        if (val == base) {
9615            if (space == null) return prefix;
9616            return prefix + "  ";
9617        }
9618        return prefix + "+" + Integer.toString(val-base);
9619    }
9620
9621    private static final int dumpProcessList(PrintWriter pw,
9622            ActivityManagerService service, List list,
9623            String prefix, String normalLabel, String persistentLabel,
9624            String dumpPackage) {
9625        int numPers = 0;
9626        final int N = list.size()-1;
9627        for (int i=N; i>=0; i--) {
9628            ProcessRecord r = (ProcessRecord)list.get(i);
9629            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9630                continue;
9631            }
9632            pw.println(String.format("%s%s #%2d: %s",
9633                    prefix, (r.persistent ? persistentLabel : normalLabel),
9634                    i, r.toString()));
9635            if (r.persistent) {
9636                numPers++;
9637            }
9638        }
9639        return numPers;
9640    }
9641
9642    private static final boolean dumpProcessOomList(PrintWriter pw,
9643            ActivityManagerService service, List<ProcessRecord> origList,
9644            String prefix, String normalLabel, String persistentLabel,
9645            boolean inclDetails, String dumpPackage) {
9646
9647        ArrayList<Pair<ProcessRecord, Integer>> list
9648                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9649        for (int i=0; i<origList.size(); i++) {
9650            ProcessRecord r = origList.get(i);
9651            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9652                continue;
9653            }
9654            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9655        }
9656
9657        if (list.size() <= 0) {
9658            return false;
9659        }
9660
9661        Comparator<Pair<ProcessRecord, Integer>> comparator
9662                = new Comparator<Pair<ProcessRecord, Integer>>() {
9663            @Override
9664            public int compare(Pair<ProcessRecord, Integer> object1,
9665                    Pair<ProcessRecord, Integer> object2) {
9666                if (object1.first.setAdj != object2.first.setAdj) {
9667                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9668                }
9669                if (object1.second.intValue() != object2.second.intValue()) {
9670                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9671                }
9672                return 0;
9673            }
9674        };
9675
9676        Collections.sort(list, comparator);
9677
9678        final long curRealtime = SystemClock.elapsedRealtime();
9679        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9680        final long curUptime = SystemClock.uptimeMillis();
9681        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9682
9683        for (int i=list.size()-1; i>=0; i--) {
9684            ProcessRecord r = list.get(i).first;
9685            String oomAdj;
9686            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9687                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9688            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9689                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9690            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9691                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9692            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9693                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9694            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9695                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9696            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9697                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9698            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9699                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9700            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9701                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9702            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9703                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9704            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9705                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9706            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9707                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9708            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9709                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9710            } else {
9711                oomAdj = Integer.toString(r.setAdj);
9712            }
9713            String schedGroup;
9714            switch (r.setSchedGroup) {
9715                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9716                    schedGroup = "B";
9717                    break;
9718                case Process.THREAD_GROUP_DEFAULT:
9719                    schedGroup = "F";
9720                    break;
9721                default:
9722                    schedGroup = Integer.toString(r.setSchedGroup);
9723                    break;
9724            }
9725            String foreground;
9726            if (r.foregroundActivities) {
9727                foreground = "A";
9728            } else if (r.foregroundServices) {
9729                foreground = "S";
9730            } else {
9731                foreground = " ";
9732            }
9733            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9734                    prefix, (r.persistent ? persistentLabel : normalLabel),
9735                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9736                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9737            if (r.adjSource != null || r.adjTarget != null) {
9738                pw.print(prefix);
9739                pw.print("    ");
9740                if (r.adjTarget instanceof ComponentName) {
9741                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9742                } else if (r.adjTarget != null) {
9743                    pw.print(r.adjTarget.toString());
9744                } else {
9745                    pw.print("{null}");
9746                }
9747                pw.print("<=");
9748                if (r.adjSource instanceof ProcessRecord) {
9749                    pw.print("Proc{");
9750                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9751                    pw.println("}");
9752                } else if (r.adjSource != null) {
9753                    pw.println(r.adjSource.toString());
9754                } else {
9755                    pw.println("{null}");
9756                }
9757            }
9758            if (inclDetails) {
9759                pw.print(prefix);
9760                pw.print("    ");
9761                pw.print("oom: max="); pw.print(r.maxAdj);
9762                pw.print(" hidden="); pw.print(r.hiddenAdj);
9763                pw.print(" empty="); pw.print(r.emptyAdj);
9764                pw.print(" curRaw="); pw.print(r.curRawAdj);
9765                pw.print(" setRaw="); pw.print(r.setRawAdj);
9766                pw.print(" cur="); pw.print(r.curAdj);
9767                pw.print(" set="); pw.println(r.setAdj);
9768                pw.print(prefix);
9769                pw.print("    ");
9770                pw.print("keeping="); pw.print(r.keeping);
9771                pw.print(" hidden="); pw.print(r.hidden);
9772                pw.print(" empty="); pw.print(r.empty);
9773                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9774
9775                if (!r.keeping) {
9776                    if (r.lastWakeTime != 0) {
9777                        long wtime;
9778                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9779                        synchronized (stats) {
9780                            wtime = stats.getProcessWakeTime(r.info.uid,
9781                                    r.pid, curRealtime);
9782                        }
9783                        long timeUsed = wtime - r.lastWakeTime;
9784                        pw.print(prefix);
9785                        pw.print("    ");
9786                        pw.print("keep awake over ");
9787                        TimeUtils.formatDuration(realtimeSince, pw);
9788                        pw.print(" used ");
9789                        TimeUtils.formatDuration(timeUsed, pw);
9790                        pw.print(" (");
9791                        pw.print((timeUsed*100)/realtimeSince);
9792                        pw.println("%)");
9793                    }
9794                    if (r.lastCpuTime != 0) {
9795                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9796                        pw.print(prefix);
9797                        pw.print("    ");
9798                        pw.print("run cpu over ");
9799                        TimeUtils.formatDuration(uptimeSince, pw);
9800                        pw.print(" used ");
9801                        TimeUtils.formatDuration(timeUsed, pw);
9802                        pw.print(" (");
9803                        pw.print((timeUsed*100)/uptimeSince);
9804                        pw.println("%)");
9805                    }
9806                }
9807            }
9808        }
9809        return true;
9810    }
9811
9812    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9813        ArrayList<ProcessRecord> procs;
9814        synchronized (this) {
9815            if (args != null && args.length > start
9816                    && args[start].charAt(0) != '-') {
9817                procs = new ArrayList<ProcessRecord>();
9818                int pid = -1;
9819                try {
9820                    pid = Integer.parseInt(args[start]);
9821                } catch (NumberFormatException e) {
9822
9823                }
9824                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9825                    ProcessRecord proc = mLruProcesses.get(i);
9826                    if (proc.pid == pid) {
9827                        procs.add(proc);
9828                    } else if (proc.processName.equals(args[start])) {
9829                        procs.add(proc);
9830                    }
9831                }
9832                if (procs.size() <= 0) {
9833                    pw.println("No process found for: " + args[start]);
9834                    return null;
9835                }
9836            } else {
9837                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9838            }
9839        }
9840        return procs;
9841    }
9842
9843    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9844            PrintWriter pw, String[] args) {
9845        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9846        if (procs == null) {
9847            return;
9848        }
9849
9850        long uptime = SystemClock.uptimeMillis();
9851        long realtime = SystemClock.elapsedRealtime();
9852        pw.println("Applications Graphics Acceleration Info:");
9853        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9854
9855        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9856            ProcessRecord r = procs.get(i);
9857            if (r.thread != null) {
9858                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9859                pw.flush();
9860                try {
9861                    TransferPipe tp = new TransferPipe();
9862                    try {
9863                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9864                        tp.go(fd);
9865                    } finally {
9866                        tp.kill();
9867                    }
9868                } catch (IOException e) {
9869                    pw.println("Failure while dumping the app: " + r);
9870                    pw.flush();
9871                } catch (RemoteException e) {
9872                    pw.println("Got a RemoteException while dumping the app " + r);
9873                    pw.flush();
9874                }
9875            }
9876        }
9877    }
9878
9879    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9880        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9881        if (procs == null) {
9882            return;
9883        }
9884
9885        pw.println("Applications Database Info:");
9886
9887        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9888            ProcessRecord r = procs.get(i);
9889            if (r.thread != null) {
9890                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9891                pw.flush();
9892                try {
9893                    TransferPipe tp = new TransferPipe();
9894                    try {
9895                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9896                        tp.go(fd);
9897                    } finally {
9898                        tp.kill();
9899                    }
9900                } catch (IOException e) {
9901                    pw.println("Failure while dumping the app: " + r);
9902                    pw.flush();
9903                } catch (RemoteException e) {
9904                    pw.println("Got a RemoteException while dumping the app " + r);
9905                    pw.flush();
9906                }
9907            }
9908        }
9909    }
9910
9911    final static class MemItem {
9912        final String label;
9913        final String shortLabel;
9914        final long pss;
9915        final int id;
9916        ArrayList<MemItem> subitems;
9917
9918        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9919            label = _label;
9920            shortLabel = _shortLabel;
9921            pss = _pss;
9922            id = _id;
9923        }
9924    }
9925
9926    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9927            boolean sort) {
9928        if (sort) {
9929            Collections.sort(items, new Comparator<MemItem>() {
9930                @Override
9931                public int compare(MemItem lhs, MemItem rhs) {
9932                    if (lhs.pss < rhs.pss) {
9933                        return 1;
9934                    } else if (lhs.pss > rhs.pss) {
9935                        return -1;
9936                    }
9937                    return 0;
9938                }
9939            });
9940        }
9941
9942        for (int i=0; i<items.size(); i++) {
9943            MemItem mi = items.get(i);
9944            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9945            if (mi.subitems != null) {
9946                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9947            }
9948        }
9949    }
9950
9951    // These are in KB.
9952    static final long[] DUMP_MEM_BUCKETS = new long[] {
9953        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9954        120*1024, 160*1024, 200*1024,
9955        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9956        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9957    };
9958
9959    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9960            boolean stackLike) {
9961        int start = label.lastIndexOf('.');
9962        if (start >= 0) start++;
9963        else start = 0;
9964        int end = label.length();
9965        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9966            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9967                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9968                out.append(bucket);
9969                out.append(stackLike ? "MB." : "MB ");
9970                out.append(label, start, end);
9971                return;
9972            }
9973        }
9974        out.append(memKB/1024);
9975        out.append(stackLike ? "MB." : "MB ");
9976        out.append(label, start, end);
9977    }
9978
9979    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9980            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9981            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9982            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9983            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9984    };
9985    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9986            "System", "Persistent", "Foreground",
9987            "Visible", "Perceptible", "Heavy Weight",
9988            "Backup", "A Services", "Home", "Previous",
9989            "B Services", "Background"
9990    };
9991
9992    final void dumpApplicationMemoryUsage(FileDescriptor fd,
9993            PrintWriter pw, String prefix, String[] args, boolean brief,
9994            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
9995        boolean dumpAll = false;
9996        boolean oomOnly = false;
9997
9998        int opti = 0;
9999        while (opti < args.length) {
10000            String opt = args[opti];
10001            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10002                break;
10003            }
10004            opti++;
10005            if ("-a".equals(opt)) {
10006                dumpAll = true;
10007            } else if ("--oom".equals(opt)) {
10008                oomOnly = true;
10009            } else if ("-h".equals(opt)) {
10010                pw.println("meminfo dump options: [-a] [--oom] [process]");
10011                pw.println("  -a: include all available information for each process.");
10012                pw.println("  --oom: only show processes organized by oom adj.");
10013                pw.println("If [process] is specified it can be the name or ");
10014                pw.println("pid of a specific process to dump.");
10015                return;
10016            } else {
10017                pw.println("Unknown argument: " + opt + "; use -h for help");
10018            }
10019        }
10020
10021        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10022        if (procs == null) {
10023            return;
10024        }
10025
10026        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10027        long uptime = SystemClock.uptimeMillis();
10028        long realtime = SystemClock.elapsedRealtime();
10029
10030        if (procs.size() == 1 || isCheckinRequest) {
10031            dumpAll = true;
10032        }
10033
10034        if (isCheckinRequest) {
10035            // short checkin version
10036            pw.println(uptime + "," + realtime);
10037            pw.flush();
10038        } else {
10039            pw.println("Applications Memory Usage (kB):");
10040            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10041        }
10042
10043        String[] innerArgs = new String[args.length-opti];
10044        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10045
10046        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10047        long nativePss=0, dalvikPss=0, otherPss=0;
10048        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10049
10050        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10051        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10052                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10053
10054        long totalPss = 0;
10055
10056        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10057            ProcessRecord r = procs.get(i);
10058            if (r.thread != null) {
10059                if (!isCheckinRequest && dumpAll) {
10060                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10061                    pw.flush();
10062                }
10063                Debug.MemoryInfo mi = null;
10064                if (dumpAll) {
10065                    try {
10066                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10067                    } catch (RemoteException e) {
10068                        if (!isCheckinRequest) {
10069                            pw.println("Got RemoteException!");
10070                            pw.flush();
10071                        }
10072                    }
10073                } else {
10074                    mi = new Debug.MemoryInfo();
10075                    Debug.getMemoryInfo(r.pid, mi);
10076                }
10077
10078                if (!isCheckinRequest && mi != null) {
10079                    long myTotalPss = mi.getTotalPss();
10080                    totalPss += myTotalPss;
10081                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10082                            r.processName, myTotalPss, 0);
10083                    procMems.add(pssItem);
10084
10085                    nativePss += mi.nativePss;
10086                    dalvikPss += mi.dalvikPss;
10087                    otherPss += mi.otherPss;
10088                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10089                        long mem = mi.getOtherPss(j);
10090                        miscPss[j] += mem;
10091                        otherPss -= mem;
10092                    }
10093
10094                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10095                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10096                                || oomIndex == (oomPss.length-1)) {
10097                            oomPss[oomIndex] += myTotalPss;
10098                            if (oomProcs[oomIndex] == null) {
10099                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10100                            }
10101                            oomProcs[oomIndex].add(pssItem);
10102                            break;
10103                        }
10104                    }
10105                }
10106            }
10107        }
10108
10109        if (!isCheckinRequest && procs.size() > 1) {
10110            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10111
10112            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10113            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10114            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10115            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10116                String label = Debug.MemoryInfo.getOtherLabel(j);
10117                catMems.add(new MemItem(label, label, miscPss[j], j));
10118            }
10119
10120            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10121            for (int j=0; j<oomPss.length; j++) {
10122                if (oomPss[j] != 0) {
10123                    String label = DUMP_MEM_OOM_LABEL[j];
10124                    MemItem item = new MemItem(label, label, oomPss[j],
10125                            DUMP_MEM_OOM_ADJ[j]);
10126                    item.subitems = oomProcs[j];
10127                    oomMems.add(item);
10128                }
10129            }
10130
10131            if (outTag != null || outStack != null) {
10132                if (outTag != null) {
10133                    appendMemBucket(outTag, totalPss, "total", false);
10134                }
10135                if (outStack != null) {
10136                    appendMemBucket(outStack, totalPss, "total", true);
10137                }
10138                boolean firstLine = true;
10139                for (int i=0; i<oomMems.size(); i++) {
10140                    MemItem miCat = oomMems.get(i);
10141                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10142                        continue;
10143                    }
10144                    if (miCat.id < ProcessList.SERVICE_ADJ
10145                            || miCat.id == ProcessList.HOME_APP_ADJ
10146                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10147                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10148                            outTag.append(" / ");
10149                        }
10150                        if (outStack != null) {
10151                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10152                                if (firstLine) {
10153                                    outStack.append(":");
10154                                    firstLine = false;
10155                                }
10156                                outStack.append("\n\t at ");
10157                            } else {
10158                                outStack.append("$");
10159                            }
10160                        }
10161                        for (int j=0; j<miCat.subitems.size(); j++) {
10162                            MemItem mi = miCat.subitems.get(j);
10163                            if (j > 0) {
10164                                if (outTag != null) {
10165                                    outTag.append(" ");
10166                                }
10167                                if (outStack != null) {
10168                                    outStack.append("$");
10169                                }
10170                            }
10171                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10172                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10173                            }
10174                            if (outStack != null) {
10175                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10176                            }
10177                        }
10178                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10179                            outStack.append("(");
10180                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10181                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10182                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10183                                    outStack.append(":");
10184                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10185                                }
10186                            }
10187                            outStack.append(")");
10188                        }
10189                    }
10190                }
10191            }
10192
10193            if (!brief && !oomOnly) {
10194                pw.println();
10195                pw.println("Total PSS by process:");
10196                dumpMemItems(pw, "  ", procMems, true);
10197                pw.println();
10198            }
10199            pw.println("Total PSS by OOM adjustment:");
10200            dumpMemItems(pw, "  ", oomMems, false);
10201            if (!oomOnly) {
10202                PrintWriter out = categoryPw != null ? categoryPw : pw;
10203                out.println();
10204                out.println("Total PSS by category:");
10205                dumpMemItems(out, "  ", catMems, true);
10206            }
10207            pw.println();
10208            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10209            final int[] SINGLE_LONG_FORMAT = new int[] {
10210                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10211            };
10212            long[] longOut = new long[1];
10213            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10214                    SINGLE_LONG_FORMAT, null, longOut, null);
10215            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10216            longOut[0] = 0;
10217            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10218                    SINGLE_LONG_FORMAT, null, longOut, null);
10219            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10220            longOut[0] = 0;
10221            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10222                    SINGLE_LONG_FORMAT, null, longOut, null);
10223            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10224            longOut[0] = 0;
10225            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10226                    SINGLE_LONG_FORMAT, null, longOut, null);
10227            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10228            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10229                    pw.print(shared); pw.println(" kB");
10230            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10231                    pw.print(voltile); pw.println(" kB volatile");
10232        }
10233    }
10234
10235    /**
10236     * Searches array of arguments for the specified string
10237     * @param args array of argument strings
10238     * @param value value to search for
10239     * @return true if the value is contained in the array
10240     */
10241    private static boolean scanArgs(String[] args, String value) {
10242        if (args != null) {
10243            for (String arg : args) {
10244                if (value.equals(arg)) {
10245                    return true;
10246                }
10247            }
10248        }
10249        return false;
10250    }
10251
10252    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10253            ContentProviderRecord cpr, boolean always) {
10254        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10255
10256        if (!inLaunching || always) {
10257            synchronized (cpr) {
10258                cpr.launchingApp = null;
10259                cpr.notifyAll();
10260            }
10261            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10262            String names[] = cpr.info.authority.split(";");
10263            for (int j = 0; j < names.length; j++) {
10264                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10265            }
10266        }
10267
10268        for (int i=0; i<cpr.connections.size(); i++) {
10269            ContentProviderConnection conn = cpr.connections.get(i);
10270            if (conn.waiting) {
10271                // If this connection is waiting for the provider, then we don't
10272                // need to mess with its process unless we are always removing
10273                // or for some reason the provider is not currently launching.
10274                if (inLaunching && !always) {
10275                    continue;
10276                }
10277            }
10278            ProcessRecord capp = conn.client;
10279            conn.dead = true;
10280            if (conn.stableCount > 0) {
10281                if (!capp.persistent && capp.thread != null
10282                        && capp.pid != 0
10283                        && capp.pid != MY_PID) {
10284                    Slog.i(TAG, "Kill " + capp.processName
10285                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10286                            + " in dying process " + (proc != null ? proc.processName : "??"));
10287                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10288                            capp.processName, capp.setAdj, "dying provider "
10289                                    + cpr.name.toShortString());
10290                    Process.killProcessQuiet(capp.pid);
10291                }
10292            } else if (capp.thread != null && conn.provider.provider != null) {
10293                try {
10294                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10295                } catch (RemoteException e) {
10296                }
10297                // In the protocol here, we don't expect the client to correctly
10298                // clean up this connection, we'll just remove it.
10299                cpr.connections.remove(i);
10300                conn.client.conProviders.remove(conn);
10301            }
10302        }
10303
10304        if (inLaunching && always) {
10305            mLaunchingProviders.remove(cpr);
10306        }
10307        return inLaunching;
10308    }
10309
10310    /**
10311     * Main code for cleaning up a process when it has gone away.  This is
10312     * called both as a result of the process dying, or directly when stopping
10313     * a process when running in single process mode.
10314     */
10315    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10316            boolean restarting, boolean allowRestart, int index) {
10317        if (index >= 0) {
10318            mLruProcesses.remove(index);
10319        }
10320
10321        mProcessesToGc.remove(app);
10322
10323        // Dismiss any open dialogs.
10324        if (app.crashDialog != null) {
10325            app.crashDialog.dismiss();
10326            app.crashDialog = null;
10327        }
10328        if (app.anrDialog != null) {
10329            app.anrDialog.dismiss();
10330            app.anrDialog = null;
10331        }
10332        if (app.waitDialog != null) {
10333            app.waitDialog.dismiss();
10334            app.waitDialog = null;
10335        }
10336
10337        app.crashing = false;
10338        app.notResponding = false;
10339
10340        app.resetPackageList();
10341        app.unlinkDeathRecipient();
10342        app.thread = null;
10343        app.forcingToForeground = null;
10344        app.foregroundServices = false;
10345        app.foregroundActivities = false;
10346        app.hasShownUi = false;
10347        app.hasAboveClient = false;
10348
10349        mServices.killServicesLocked(app, allowRestart);
10350
10351        boolean restart = false;
10352
10353        // Remove published content providers.
10354        if (!app.pubProviders.isEmpty()) {
10355            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10356            while (it.hasNext()) {
10357                ContentProviderRecord cpr = it.next();
10358
10359                final boolean always = app.bad || !allowRestart;
10360                if (removeDyingProviderLocked(app, cpr, always) || always) {
10361                    // We left the provider in the launching list, need to
10362                    // restart it.
10363                    restart = true;
10364                }
10365
10366                cpr.provider = null;
10367                cpr.proc = null;
10368            }
10369            app.pubProviders.clear();
10370        }
10371
10372        // Take care of any launching providers waiting for this process.
10373        if (checkAppInLaunchingProvidersLocked(app, false)) {
10374            restart = true;
10375        }
10376
10377        // Unregister from connected content providers.
10378        if (!app.conProviders.isEmpty()) {
10379            for (int i=0; i<app.conProviders.size(); i++) {
10380                ContentProviderConnection conn = app.conProviders.get(i);
10381                conn.provider.connections.remove(conn);
10382            }
10383            app.conProviders.clear();
10384        }
10385
10386        // At this point there may be remaining entries in mLaunchingProviders
10387        // where we were the only one waiting, so they are no longer of use.
10388        // Look for these and clean up if found.
10389        // XXX Commented out for now.  Trying to figure out a way to reproduce
10390        // the actual situation to identify what is actually going on.
10391        if (false) {
10392            for (int i=0; i<mLaunchingProviders.size(); i++) {
10393                ContentProviderRecord cpr = (ContentProviderRecord)
10394                        mLaunchingProviders.get(i);
10395                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10396                    synchronized (cpr) {
10397                        cpr.launchingApp = null;
10398                        cpr.notifyAll();
10399                    }
10400                }
10401            }
10402        }
10403
10404        skipCurrentReceiverLocked(app);
10405
10406        // Unregister any receivers.
10407        if (app.receivers.size() > 0) {
10408            Iterator<ReceiverList> it = app.receivers.iterator();
10409            while (it.hasNext()) {
10410                removeReceiverLocked(it.next());
10411            }
10412            app.receivers.clear();
10413        }
10414
10415        // If the app is undergoing backup, tell the backup manager about it
10416        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10417            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10418            try {
10419                IBackupManager bm = IBackupManager.Stub.asInterface(
10420                        ServiceManager.getService(Context.BACKUP_SERVICE));
10421                bm.agentDisconnected(app.info.packageName);
10422            } catch (RemoteException e) {
10423                // can't happen; backup manager is local
10424            }
10425        }
10426
10427        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10428            ProcessChangeItem item = mPendingProcessChanges.get(i);
10429            if (item.pid == app.pid) {
10430                mPendingProcessChanges.remove(i);
10431                mAvailProcessChanges.add(item);
10432            }
10433        }
10434        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10435
10436        // If the caller is restarting this app, then leave it in its
10437        // current lists and let the caller take care of it.
10438        if (restarting) {
10439            return;
10440        }
10441
10442        if (!app.persistent || app.isolated) {
10443            if (DEBUG_PROCESSES) Slog.v(TAG,
10444                    "Removing non-persistent process during cleanup: " + app);
10445            mProcessNames.remove(app.processName, app.uid);
10446            mIsolatedProcesses.remove(app.uid);
10447            if (mHeavyWeightProcess == app) {
10448                mHeavyWeightProcess = null;
10449                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10450            }
10451        } else if (!app.removed) {
10452            // This app is persistent, so we need to keep its record around.
10453            // If it is not already on the pending app list, add it there
10454            // and start a new process for it.
10455            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10456                mPersistentStartingProcesses.add(app);
10457                restart = true;
10458            }
10459        }
10460        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10461                "Clean-up removing on hold: " + app);
10462        mProcessesOnHold.remove(app);
10463
10464        if (app == mHomeProcess) {
10465            mHomeProcess = null;
10466        }
10467        if (app == mPreviousProcess) {
10468            mPreviousProcess = null;
10469        }
10470
10471        if (restart && !app.isolated) {
10472            // We have components that still need to be running in the
10473            // process, so re-launch it.
10474            mProcessNames.put(app.processName, app.uid, app);
10475            startProcessLocked(app, "restart", app.processName);
10476        } else if (app.pid > 0 && app.pid != MY_PID) {
10477            // Goodbye!
10478            synchronized (mPidsSelfLocked) {
10479                mPidsSelfLocked.remove(app.pid);
10480                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10481            }
10482            app.setPid(0);
10483        }
10484    }
10485
10486    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10487        // Look through the content providers we are waiting to have launched,
10488        // and if any run in this process then either schedule a restart of
10489        // the process or kill the client waiting for it if this process has
10490        // gone bad.
10491        int NL = mLaunchingProviders.size();
10492        boolean restart = false;
10493        for (int i=0; i<NL; i++) {
10494            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10495            if (cpr.launchingApp == app) {
10496                if (!alwaysBad && !app.bad) {
10497                    restart = true;
10498                } else {
10499                    removeDyingProviderLocked(app, cpr, true);
10500                    NL = mLaunchingProviders.size();
10501                }
10502            }
10503        }
10504        return restart;
10505    }
10506
10507    // =========================================================
10508    // SERVICES
10509    // =========================================================
10510
10511    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10512            int flags) {
10513        enforceNotIsolatedCaller("getServices");
10514        synchronized (this) {
10515            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10516        }
10517    }
10518
10519    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10520        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10521        synchronized (this) {
10522            return mServices.getRunningServiceControlPanelLocked(name);
10523        }
10524    }
10525
10526    public ComponentName startService(IApplicationThread caller, Intent service,
10527            String resolvedType) {
10528        enforceNotIsolatedCaller("startService");
10529        // Refuse possible leaked file descriptors
10530        if (service != null && service.hasFileDescriptors() == true) {
10531            throw new IllegalArgumentException("File descriptors passed in Intent");
10532        }
10533
10534        if (DEBUG_SERVICE)
10535            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10536        synchronized(this) {
10537            final int callingPid = Binder.getCallingPid();
10538            final int callingUid = Binder.getCallingUid();
10539            final long origId = Binder.clearCallingIdentity();
10540            ComponentName res = mServices.startServiceLocked(caller, service,
10541                    resolvedType, callingPid, callingUid);
10542            Binder.restoreCallingIdentity(origId);
10543            return res;
10544        }
10545    }
10546
10547    ComponentName startServiceInPackage(int uid,
10548            Intent service, String resolvedType) {
10549        synchronized(this) {
10550            if (DEBUG_SERVICE)
10551                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10552            final long origId = Binder.clearCallingIdentity();
10553            ComponentName res = mServices.startServiceLocked(null, service,
10554                    resolvedType, -1, uid);
10555            Binder.restoreCallingIdentity(origId);
10556            return res;
10557        }
10558    }
10559
10560    public int stopService(IApplicationThread caller, Intent service,
10561            String resolvedType) {
10562        enforceNotIsolatedCaller("stopService");
10563        // Refuse possible leaked file descriptors
10564        if (service != null && service.hasFileDescriptors() == true) {
10565            throw new IllegalArgumentException("File descriptors passed in Intent");
10566        }
10567
10568        synchronized(this) {
10569            return mServices.stopServiceLocked(caller, service, resolvedType);
10570        }
10571    }
10572
10573    public IBinder peekService(Intent service, String resolvedType) {
10574        enforceNotIsolatedCaller("peekService");
10575        // Refuse possible leaked file descriptors
10576        if (service != null && service.hasFileDescriptors() == true) {
10577            throw new IllegalArgumentException("File descriptors passed in Intent");
10578        }
10579        synchronized(this) {
10580            return mServices.peekServiceLocked(service, resolvedType);
10581        }
10582    }
10583
10584    public boolean stopServiceToken(ComponentName className, IBinder token,
10585            int startId) {
10586        synchronized(this) {
10587            return mServices.stopServiceTokenLocked(className, token, startId);
10588        }
10589    }
10590
10591    public void setServiceForeground(ComponentName className, IBinder token,
10592            int id, Notification notification, boolean removeNotification) {
10593        synchronized(this) {
10594            mServices.setServiceForegroundLocked(className, token, id, notification,
10595                    removeNotification);
10596        }
10597    }
10598
10599    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10600            String className, int flags) {
10601        boolean result = false;
10602        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10603            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10604                if (ActivityManager.checkUidPermission(
10605                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10606                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10607                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10608                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10609                            + " requests FLAG_SINGLE_USER, but app does not hold "
10610                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10611                    Slog.w(TAG, msg);
10612                    throw new SecurityException(msg);
10613                }
10614                result = true;
10615            }
10616        } else if (componentProcessName == aInfo.packageName) {
10617            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10618        } else if ("system".equals(componentProcessName)) {
10619            result = true;
10620        }
10621        if (DEBUG_MU) {
10622            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10623                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10624        }
10625        return result;
10626    }
10627
10628    public int bindService(IApplicationThread caller, IBinder token,
10629            Intent service, String resolvedType,
10630            IServiceConnection connection, int flags, int userId) {
10631        enforceNotIsolatedCaller("bindService");
10632        // Refuse possible leaked file descriptors
10633        if (service != null && service.hasFileDescriptors() == true) {
10634            throw new IllegalArgumentException("File descriptors passed in Intent");
10635        }
10636
10637        checkValidCaller(Binder.getCallingUid(), userId);
10638
10639        synchronized(this) {
10640            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10641                    connection, flags, userId);
10642        }
10643    }
10644
10645    public boolean unbindService(IServiceConnection connection) {
10646        synchronized (this) {
10647            return mServices.unbindServiceLocked(connection);
10648        }
10649    }
10650
10651    public void publishService(IBinder token, Intent intent, IBinder service) {
10652        // Refuse possible leaked file descriptors
10653        if (intent != null && intent.hasFileDescriptors() == true) {
10654            throw new IllegalArgumentException("File descriptors passed in Intent");
10655        }
10656
10657        synchronized(this) {
10658            if (!(token instanceof ServiceRecord)) {
10659                throw new IllegalArgumentException("Invalid service token");
10660            }
10661            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10662        }
10663    }
10664
10665    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10666        // Refuse possible leaked file descriptors
10667        if (intent != null && intent.hasFileDescriptors() == true) {
10668            throw new IllegalArgumentException("File descriptors passed in Intent");
10669        }
10670
10671        synchronized(this) {
10672            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10673        }
10674    }
10675
10676    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10677        synchronized(this) {
10678            if (!(token instanceof ServiceRecord)) {
10679                throw new IllegalArgumentException("Invalid service token");
10680            }
10681            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10682        }
10683    }
10684
10685    // =========================================================
10686    // BACKUP AND RESTORE
10687    // =========================================================
10688
10689    // Cause the target app to be launched if necessary and its backup agent
10690    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10691    // activity manager to announce its creation.
10692    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10693        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10694        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10695
10696        synchronized(this) {
10697            // !!! TODO: currently no check here that we're already bound
10698            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10699            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10700            synchronized (stats) {
10701                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10702            }
10703
10704            // Backup agent is now in use, its package can't be stopped.
10705            try {
10706                AppGlobals.getPackageManager().setPackageStoppedState(
10707                        app.packageName, false, UserHandle.getUserId(app.uid));
10708            } catch (RemoteException e) {
10709            } catch (IllegalArgumentException e) {
10710                Slog.w(TAG, "Failed trying to unstop package "
10711                        + app.packageName + ": " + e);
10712            }
10713
10714            BackupRecord r = new BackupRecord(ss, app, backupMode);
10715            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10716                    ? new ComponentName(app.packageName, app.backupAgentName)
10717                    : new ComponentName("android", "FullBackupAgent");
10718            // startProcessLocked() returns existing proc's record if it's already running
10719            ProcessRecord proc = startProcessLocked(app.processName, app,
10720                    false, 0, "backup", hostingName, false, false);
10721            if (proc == null) {
10722                Slog.e(TAG, "Unable to start backup agent process " + r);
10723                return false;
10724            }
10725
10726            r.app = proc;
10727            mBackupTarget = r;
10728            mBackupAppName = app.packageName;
10729
10730            // Try not to kill the process during backup
10731            updateOomAdjLocked(proc);
10732
10733            // If the process is already attached, schedule the creation of the backup agent now.
10734            // If it is not yet live, this will be done when it attaches to the framework.
10735            if (proc.thread != null) {
10736                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10737                try {
10738                    proc.thread.scheduleCreateBackupAgent(app,
10739                            compatibilityInfoForPackageLocked(app), backupMode);
10740                } catch (RemoteException e) {
10741                    // Will time out on the backup manager side
10742                }
10743            } else {
10744                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10745            }
10746            // Invariants: at this point, the target app process exists and the application
10747            // is either already running or in the process of coming up.  mBackupTarget and
10748            // mBackupAppName describe the app, so that when it binds back to the AM we
10749            // know that it's scheduled for a backup-agent operation.
10750        }
10751
10752        return true;
10753    }
10754
10755    // A backup agent has just come up
10756    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10757        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10758                + " = " + agent);
10759
10760        synchronized(this) {
10761            if (!agentPackageName.equals(mBackupAppName)) {
10762                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10763                return;
10764            }
10765        }
10766
10767        long oldIdent = Binder.clearCallingIdentity();
10768        try {
10769            IBackupManager bm = IBackupManager.Stub.asInterface(
10770                    ServiceManager.getService(Context.BACKUP_SERVICE));
10771            bm.agentConnected(agentPackageName, agent);
10772        } catch (RemoteException e) {
10773            // can't happen; the backup manager service is local
10774        } catch (Exception e) {
10775            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10776            e.printStackTrace();
10777        } finally {
10778            Binder.restoreCallingIdentity(oldIdent);
10779        }
10780    }
10781
10782    // done with this agent
10783    public void unbindBackupAgent(ApplicationInfo appInfo) {
10784        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10785        if (appInfo == null) {
10786            Slog.w(TAG, "unbind backup agent for null app");
10787            return;
10788        }
10789
10790        synchronized(this) {
10791            if (mBackupAppName == null) {
10792                Slog.w(TAG, "Unbinding backup agent with no active backup");
10793                return;
10794            }
10795
10796            if (!mBackupAppName.equals(appInfo.packageName)) {
10797                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10798                return;
10799            }
10800
10801            ProcessRecord proc = mBackupTarget.app;
10802            mBackupTarget = null;
10803            mBackupAppName = null;
10804
10805            // Not backing this app up any more; reset its OOM adjustment
10806            updateOomAdjLocked(proc);
10807
10808            // If the app crashed during backup, 'thread' will be null here
10809            if (proc.thread != null) {
10810                try {
10811                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10812                            compatibilityInfoForPackageLocked(appInfo));
10813                } catch (Exception e) {
10814                    Slog.e(TAG, "Exception when unbinding backup agent:");
10815                    e.printStackTrace();
10816                }
10817            }
10818        }
10819    }
10820    // =========================================================
10821    // BROADCASTS
10822    // =========================================================
10823
10824    private final List getStickiesLocked(String action, IntentFilter filter,
10825            List cur) {
10826        final ContentResolver resolver = mContext.getContentResolver();
10827        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10828        if (list == null) {
10829            return cur;
10830        }
10831        int N = list.size();
10832        for (int i=0; i<N; i++) {
10833            Intent intent = list.get(i);
10834            if (filter.match(resolver, intent, true, TAG) >= 0) {
10835                if (cur == null) {
10836                    cur = new ArrayList<Intent>();
10837                }
10838                cur.add(intent);
10839            }
10840        }
10841        return cur;
10842    }
10843
10844    boolean isPendingBroadcastProcessLocked(int pid) {
10845        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10846                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10847    }
10848
10849    void skipPendingBroadcastLocked(int pid) {
10850            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10851            for (BroadcastQueue queue : mBroadcastQueues) {
10852                queue.skipPendingBroadcastLocked(pid);
10853            }
10854    }
10855
10856    // The app just attached; send any pending broadcasts that it should receive
10857    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10858        boolean didSomething = false;
10859        for (BroadcastQueue queue : mBroadcastQueues) {
10860            didSomething |= queue.sendPendingBroadcastsLocked(app);
10861        }
10862        return didSomething;
10863    }
10864
10865    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10866            IIntentReceiver receiver, IntentFilter filter, String permission) {
10867        enforceNotIsolatedCaller("registerReceiver");
10868        int callingUid;
10869        synchronized(this) {
10870            ProcessRecord callerApp = null;
10871            if (caller != null) {
10872                callerApp = getRecordForAppLocked(caller);
10873                if (callerApp == null) {
10874                    throw new SecurityException(
10875                            "Unable to find app for caller " + caller
10876                            + " (pid=" + Binder.getCallingPid()
10877                            + ") when registering receiver " + receiver);
10878                }
10879                if (callerApp.info.uid != Process.SYSTEM_UID &&
10880                        !callerApp.pkgList.contains(callerPackage)) {
10881                    throw new SecurityException("Given caller package " + callerPackage
10882                            + " is not running in process " + callerApp);
10883                }
10884                callingUid = callerApp.info.uid;
10885            } else {
10886                callerPackage = null;
10887                callingUid = Binder.getCallingUid();
10888            }
10889
10890            List allSticky = null;
10891
10892            // Look for any matching sticky broadcasts...
10893            Iterator actions = filter.actionsIterator();
10894            if (actions != null) {
10895                while (actions.hasNext()) {
10896                    String action = (String)actions.next();
10897                    allSticky = getStickiesLocked(action, filter, allSticky);
10898                }
10899            } else {
10900                allSticky = getStickiesLocked(null, filter, allSticky);
10901            }
10902
10903            // The first sticky in the list is returned directly back to
10904            // the client.
10905            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10906
10907            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10908                    + ": " + sticky);
10909
10910            if (receiver == null) {
10911                return sticky;
10912            }
10913
10914            ReceiverList rl
10915                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10916            if (rl == null) {
10917                rl = new ReceiverList(this, callerApp,
10918                        Binder.getCallingPid(),
10919                        Binder.getCallingUid(), receiver);
10920                if (rl.app != null) {
10921                    rl.app.receivers.add(rl);
10922                } else {
10923                    try {
10924                        receiver.asBinder().linkToDeath(rl, 0);
10925                    } catch (RemoteException e) {
10926                        return sticky;
10927                    }
10928                    rl.linkedToDeath = true;
10929                }
10930                mRegisteredReceivers.put(receiver.asBinder(), rl);
10931            }
10932            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10933                    permission, callingUid);
10934            rl.add(bf);
10935            if (!bf.debugCheck()) {
10936                Slog.w(TAG, "==> For Dynamic broadast");
10937            }
10938            mReceiverResolver.addFilter(bf);
10939
10940            // Enqueue broadcasts for all existing stickies that match
10941            // this filter.
10942            if (allSticky != null) {
10943                ArrayList receivers = new ArrayList();
10944                receivers.add(bf);
10945
10946                int N = allSticky.size();
10947                for (int i=0; i<N; i++) {
10948                    Intent intent = (Intent)allSticky.get(i);
10949                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10950                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10951                            null, -1, -1, null, receivers, null, 0, null, null,
10952                            false, true, true, false);
10953                    queue.enqueueParallelBroadcastLocked(r);
10954                    queue.scheduleBroadcastsLocked();
10955                }
10956            }
10957
10958            return sticky;
10959        }
10960    }
10961
10962    public void unregisterReceiver(IIntentReceiver receiver) {
10963        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10964
10965        final long origId = Binder.clearCallingIdentity();
10966        try {
10967            boolean doTrim = false;
10968
10969            synchronized(this) {
10970                ReceiverList rl
10971                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10972                if (rl != null) {
10973                    if (rl.curBroadcast != null) {
10974                        BroadcastRecord r = rl.curBroadcast;
10975                        final boolean doNext = finishReceiverLocked(
10976                                receiver.asBinder(), r.resultCode, r.resultData,
10977                                r.resultExtras, r.resultAbort, true);
10978                        if (doNext) {
10979                            doTrim = true;
10980                            r.queue.processNextBroadcast(false);
10981                        }
10982                    }
10983
10984                    if (rl.app != null) {
10985                        rl.app.receivers.remove(rl);
10986                    }
10987                    removeReceiverLocked(rl);
10988                    if (rl.linkedToDeath) {
10989                        rl.linkedToDeath = false;
10990                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
10991                    }
10992                }
10993            }
10994
10995            // If we actually concluded any broadcasts, we might now be able
10996            // to trim the recipients' apps from our working set
10997            if (doTrim) {
10998                trimApplications();
10999                return;
11000            }
11001
11002        } finally {
11003            Binder.restoreCallingIdentity(origId);
11004        }
11005    }
11006
11007    void removeReceiverLocked(ReceiverList rl) {
11008        mRegisteredReceivers.remove(rl.receiver.asBinder());
11009        int N = rl.size();
11010        for (int i=0; i<N; i++) {
11011            mReceiverResolver.removeFilter(rl.get(i));
11012        }
11013    }
11014
11015    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11016        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11017            ProcessRecord r = mLruProcesses.get(i);
11018            if (r.thread != null) {
11019                try {
11020                    r.thread.dispatchPackageBroadcast(cmd, packages);
11021                } catch (RemoteException ex) {
11022                }
11023            }
11024        }
11025    }
11026
11027    private final int broadcastIntentLocked(ProcessRecord callerApp,
11028            String callerPackage, Intent intent, String resolvedType,
11029            IIntentReceiver resultTo, int resultCode, String resultData,
11030            Bundle map, String requiredPermission,
11031            boolean ordered, boolean sticky, int callingPid, int callingUid,
11032            int userId) {
11033        intent = new Intent(intent);
11034
11035        // By default broadcasts do not go to stopped apps.
11036        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11037
11038        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11039            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11040            + " ordered=" + ordered + " userid=" + userId);
11041        if ((resultTo != null) && !ordered) {
11042            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11043        }
11044
11045        boolean onlySendToCaller = false;
11046
11047        // If the caller is trying to send this broadcast to a different
11048        // user, verify that is allowed.
11049        if (UserHandle.getUserId(callingUid) != userId) {
11050            if (checkComponentPermission(
11051                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11052                    callingPid, callingUid, -1, true)
11053                    != PackageManager.PERMISSION_GRANTED) {
11054                if (checkComponentPermission(
11055                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11056                        callingPid, callingUid, -1, true)
11057                        == PackageManager.PERMISSION_GRANTED) {
11058                    onlySendToCaller = true;
11059                } else {
11060                    String msg = "Permission Denial: " + intent.getAction()
11061                            + " broadcast from " + callerPackage
11062                            + " asks to send as user " + userId
11063                            + " but is calling from user " + UserHandle.getUserId(callingUid)
11064                            + "; this requires "
11065                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11066                    Slog.w(TAG, msg);
11067                    throw new SecurityException(msg);
11068                }
11069            }
11070        }
11071
11072        // Handle special intents: if this broadcast is from the package
11073        // manager about a package being removed, we need to remove all of
11074        // its activities from the history stack.
11075        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11076                intent.getAction());
11077        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11078                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11079                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11080                || uidRemoved) {
11081            if (checkComponentPermission(
11082                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11083                    callingPid, callingUid, -1, true)
11084                    == PackageManager.PERMISSION_GRANTED) {
11085                if (uidRemoved) {
11086                    final Bundle intentExtras = intent.getExtras();
11087                    final int uid = intentExtras != null
11088                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11089                    if (uid >= 0) {
11090                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11091                        synchronized (bs) {
11092                            bs.removeUidStatsLocked(uid);
11093                        }
11094                    }
11095                } else {
11096                    // If resources are unvailble just force stop all
11097                    // those packages and flush the attribute cache as well.
11098                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11099                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11100                        if (list != null && (list.length > 0)) {
11101                            for (String pkg : list) {
11102                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11103                            }
11104                            sendPackageBroadcastLocked(
11105                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11106                        }
11107                    } else {
11108                        Uri data = intent.getData();
11109                        String ssp;
11110                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11111                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11112                                forceStopPackageLocked(ssp,
11113                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11114                                        false, userId);
11115                            }
11116                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11117                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11118                                        new String[] {ssp});
11119                            }
11120                        }
11121                    }
11122                }
11123            } else {
11124                String msg = "Permission Denial: " + intent.getAction()
11125                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11126                        + ", uid=" + callingUid + ")"
11127                        + " requires "
11128                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11129                Slog.w(TAG, msg);
11130                throw new SecurityException(msg);
11131            }
11132
11133        // Special case for adding a package: by default turn on compatibility
11134        // mode.
11135        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11136            Uri data = intent.getData();
11137            String ssp;
11138            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11139                mCompatModePackages.handlePackageAddedLocked(ssp,
11140                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11141            }
11142        }
11143
11144        /*
11145         * If this is the time zone changed action, queue up a message that will reset the timezone
11146         * of all currently running processes. This message will get queued up before the broadcast
11147         * happens.
11148         */
11149        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11150            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11151        }
11152
11153        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11154            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11155        }
11156
11157        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11158            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11159            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11160        }
11161
11162        /*
11163         * Prevent non-system code (defined here to be non-persistent
11164         * processes) from sending protected broadcasts.
11165         */
11166        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11167            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11168            callingUid == 0) {
11169            // Always okay.
11170        } else if (callerApp == null || !callerApp.persistent) {
11171            try {
11172                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11173                        intent.getAction())) {
11174                    String msg = "Permission Denial: not allowed to send broadcast "
11175                            + intent.getAction() + " from pid="
11176                            + callingPid + ", uid=" + callingUid;
11177                    Slog.w(TAG, msg);
11178                    throw new SecurityException(msg);
11179                }
11180            } catch (RemoteException e) {
11181                Slog.w(TAG, "Remote exception", e);
11182                return ActivityManager.BROADCAST_SUCCESS;
11183            }
11184        }
11185
11186        // Add to the sticky list if requested.
11187        if (sticky) {
11188            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11189                    callingPid, callingUid)
11190                    != PackageManager.PERMISSION_GRANTED) {
11191                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11192                        + callingPid + ", uid=" + callingUid
11193                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11194                Slog.w(TAG, msg);
11195                throw new SecurityException(msg);
11196            }
11197            if (requiredPermission != null) {
11198                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11199                        + " and enforce permission " + requiredPermission);
11200                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11201            }
11202            if (intent.getComponent() != null) {
11203                throw new SecurityException(
11204                        "Sticky broadcasts can't target a specific component");
11205            }
11206            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11207            if (list == null) {
11208                list = new ArrayList<Intent>();
11209                mStickyBroadcasts.put(intent.getAction(), list);
11210            }
11211            int N = list.size();
11212            int i;
11213            for (i=0; i<N; i++) {
11214                if (intent.filterEquals(list.get(i))) {
11215                    // This sticky already exists, replace it.
11216                    list.set(i, new Intent(intent));
11217                    break;
11218                }
11219            }
11220            if (i >= N) {
11221                list.add(new Intent(intent));
11222            }
11223        }
11224
11225        // Figure out who all will receive this broadcast.
11226        List receivers = null;
11227        List<BroadcastFilter> registeredReceivers = null;
11228        try {
11229            // Need to resolve the intent to interested receivers...
11230            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11231                     == 0) {
11232                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11233                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11234            }
11235            if (intent.getComponent() == null) {
11236                registeredReceivers = mReceiverResolver.queryIntent(intent,
11237                        resolvedType, false, userId);
11238            }
11239        } catch (RemoteException ex) {
11240            // pm is in same process, this will never happen.
11241        }
11242
11243        final boolean replacePending =
11244                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11245
11246        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11247                + " replacePending=" + replacePending);
11248
11249        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11250        if (!ordered && NR > 0) {
11251            // If we are not serializing this broadcast, then send the
11252            // registered receivers separately so they don't wait for the
11253            // components to be launched.
11254            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11255            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11256                    callerPackage, callingPid, callingUid, requiredPermission,
11257                    registeredReceivers, resultTo, resultCode, resultData, map,
11258                    ordered, sticky, false, onlySendToCaller);
11259            if (DEBUG_BROADCAST) Slog.v(
11260                    TAG, "Enqueueing parallel broadcast " + r);
11261            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11262            if (!replaced) {
11263                queue.enqueueParallelBroadcastLocked(r);
11264                queue.scheduleBroadcastsLocked();
11265            }
11266            registeredReceivers = null;
11267            NR = 0;
11268        }
11269
11270        // Merge into one list.
11271        int ir = 0;
11272        if (receivers != null) {
11273            // A special case for PACKAGE_ADDED: do not allow the package
11274            // being added to see this broadcast.  This prevents them from
11275            // using this as a back door to get run as soon as they are
11276            // installed.  Maybe in the future we want to have a special install
11277            // broadcast or such for apps, but we'd like to deliberately make
11278            // this decision.
11279            String skipPackages[] = null;
11280            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11281                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11282                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11283                Uri data = intent.getData();
11284                if (data != null) {
11285                    String pkgName = data.getSchemeSpecificPart();
11286                    if (pkgName != null) {
11287                        skipPackages = new String[] { pkgName };
11288                    }
11289                }
11290            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11291                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11292            }
11293            if (skipPackages != null && (skipPackages.length > 0)) {
11294                for (String skipPackage : skipPackages) {
11295                    if (skipPackage != null) {
11296                        int NT = receivers.size();
11297                        for (int it=0; it<NT; it++) {
11298                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11299                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11300                                receivers.remove(it);
11301                                it--;
11302                                NT--;
11303                            }
11304                        }
11305                    }
11306                }
11307            }
11308
11309            int NT = receivers != null ? receivers.size() : 0;
11310            int it = 0;
11311            ResolveInfo curt = null;
11312            BroadcastFilter curr = null;
11313            while (it < NT && ir < NR) {
11314                if (curt == null) {
11315                    curt = (ResolveInfo)receivers.get(it);
11316                }
11317                if (curr == null) {
11318                    curr = registeredReceivers.get(ir);
11319                }
11320                if (curr.getPriority() >= curt.priority) {
11321                    // Insert this broadcast record into the final list.
11322                    receivers.add(it, curr);
11323                    ir++;
11324                    curr = null;
11325                    it++;
11326                    NT++;
11327                } else {
11328                    // Skip to the next ResolveInfo in the final list.
11329                    it++;
11330                    curt = null;
11331                }
11332            }
11333        }
11334        while (ir < NR) {
11335            if (receivers == null) {
11336                receivers = new ArrayList();
11337            }
11338            receivers.add(registeredReceivers.get(ir));
11339            ir++;
11340        }
11341
11342        if ((receivers != null && receivers.size() > 0)
11343                || resultTo != null) {
11344            BroadcastQueue queue = broadcastQueueForIntent(intent);
11345            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11346                    callerPackage, callingPid, callingUid, requiredPermission,
11347                    receivers, resultTo, resultCode, resultData, map, ordered,
11348                    sticky, false, onlySendToCaller);
11349            if (DEBUG_BROADCAST) Slog.v(
11350                    TAG, "Enqueueing ordered broadcast " + r
11351                    + ": prev had " + queue.mOrderedBroadcasts.size());
11352            if (DEBUG_BROADCAST) {
11353                int seq = r.intent.getIntExtra("seq", -1);
11354                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11355            }
11356            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11357            if (!replaced) {
11358                queue.enqueueOrderedBroadcastLocked(r);
11359                queue.scheduleBroadcastsLocked();
11360            }
11361        }
11362
11363        return ActivityManager.BROADCAST_SUCCESS;
11364    }
11365
11366    final Intent verifyBroadcastLocked(Intent intent) {
11367        // Refuse possible leaked file descriptors
11368        if (intent != null && intent.hasFileDescriptors() == true) {
11369            throw new IllegalArgumentException("File descriptors passed in Intent");
11370        }
11371
11372        int flags = intent.getFlags();
11373
11374        if (!mProcessesReady) {
11375            // if the caller really truly claims to know what they're doing, go
11376            // ahead and allow the broadcast without launching any receivers
11377            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11378                intent = new Intent(intent);
11379                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11380            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11381                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11382                        + " before boot completion");
11383                throw new IllegalStateException("Cannot broadcast before boot completed");
11384            }
11385        }
11386
11387        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11388            throw new IllegalArgumentException(
11389                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11390        }
11391
11392        return intent;
11393    }
11394
11395    public final int broadcastIntent(IApplicationThread caller,
11396            Intent intent, String resolvedType, IIntentReceiver resultTo,
11397            int resultCode, String resultData, Bundle map,
11398            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11399        enforceNotIsolatedCaller("broadcastIntent");
11400        synchronized(this) {
11401            intent = verifyBroadcastLocked(intent);
11402
11403            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11404            final int callingPid = Binder.getCallingPid();
11405            final int callingUid = Binder.getCallingUid();
11406            final long origId = Binder.clearCallingIdentity();
11407            int res = broadcastIntentLocked(callerApp,
11408                    callerApp != null ? callerApp.info.packageName : null,
11409                    intent, resolvedType, resultTo,
11410                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11411                    callingPid, callingUid, userId);
11412            Binder.restoreCallingIdentity(origId);
11413            return res;
11414        }
11415    }
11416
11417    int broadcastIntentInPackage(String packageName, int uid,
11418            Intent intent, String resolvedType, IIntentReceiver resultTo,
11419            int resultCode, String resultData, Bundle map,
11420            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11421        synchronized(this) {
11422            intent = verifyBroadcastLocked(intent);
11423
11424            final long origId = Binder.clearCallingIdentity();
11425            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11426                    resultTo, resultCode, resultData, map, requiredPermission,
11427                    serialized, sticky, -1, uid, userId);
11428            Binder.restoreCallingIdentity(origId);
11429            return res;
11430        }
11431    }
11432
11433    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11434    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11435        // Refuse possible leaked file descriptors
11436        if (intent != null && intent.hasFileDescriptors() == true) {
11437            throw new IllegalArgumentException("File descriptors passed in Intent");
11438        }
11439
11440        synchronized(this) {
11441            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11442                    != PackageManager.PERMISSION_GRANTED) {
11443                String msg = "Permission Denial: unbroadcastIntent() from pid="
11444                        + Binder.getCallingPid()
11445                        + ", uid=" + Binder.getCallingUid()
11446                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11447                Slog.w(TAG, msg);
11448                throw new SecurityException(msg);
11449            }
11450            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11451            if (list != null) {
11452                int N = list.size();
11453                int i;
11454                for (i=0; i<N; i++) {
11455                    if (intent.filterEquals(list.get(i))) {
11456                        list.remove(i);
11457                        break;
11458                    }
11459                }
11460            }
11461        }
11462    }
11463
11464    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11465            String resultData, Bundle resultExtras, boolean resultAbort,
11466            boolean explicit) {
11467        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11468        if (r == null) {
11469            Slog.w(TAG, "finishReceiver called but not found on queue");
11470            return false;
11471        }
11472
11473        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11474                explicit);
11475    }
11476
11477    public void finishReceiver(IBinder who, int resultCode, String resultData,
11478            Bundle resultExtras, boolean resultAbort) {
11479        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11480
11481        // Refuse possible leaked file descriptors
11482        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11483            throw new IllegalArgumentException("File descriptors passed in Bundle");
11484        }
11485
11486        final long origId = Binder.clearCallingIdentity();
11487        try {
11488            boolean doNext = false;
11489            BroadcastRecord r = null;
11490
11491            synchronized(this) {
11492                r = broadcastRecordForReceiverLocked(who);
11493                if (r != null) {
11494                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11495                        resultData, resultExtras, resultAbort, true);
11496                }
11497            }
11498
11499            if (doNext) {
11500                r.queue.processNextBroadcast(false);
11501            }
11502            trimApplications();
11503        } finally {
11504            Binder.restoreCallingIdentity(origId);
11505        }
11506    }
11507
11508    // =========================================================
11509    // INSTRUMENTATION
11510    // =========================================================
11511
11512    public boolean startInstrumentation(ComponentName className,
11513            String profileFile, int flags, Bundle arguments,
11514            IInstrumentationWatcher watcher) {
11515        enforceNotIsolatedCaller("startInstrumentation");
11516        // Refuse possible leaked file descriptors
11517        if (arguments != null && arguments.hasFileDescriptors()) {
11518            throw new IllegalArgumentException("File descriptors passed in Bundle");
11519        }
11520
11521        synchronized(this) {
11522            InstrumentationInfo ii = null;
11523            ApplicationInfo ai = null;
11524            try {
11525                ii = mContext.getPackageManager().getInstrumentationInfo(
11526                    className, STOCK_PM_FLAGS);
11527                ai = mContext.getPackageManager().getApplicationInfo(
11528                        ii.targetPackage, STOCK_PM_FLAGS);
11529            } catch (PackageManager.NameNotFoundException e) {
11530            }
11531            if (ii == null) {
11532                reportStartInstrumentationFailure(watcher, className,
11533                        "Unable to find instrumentation info for: " + className);
11534                return false;
11535            }
11536            if (ai == null) {
11537                reportStartInstrumentationFailure(watcher, className,
11538                        "Unable to find instrumentation target package: " + ii.targetPackage);
11539                return false;
11540            }
11541
11542            int match = mContext.getPackageManager().checkSignatures(
11543                    ii.targetPackage, ii.packageName);
11544            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11545                String msg = "Permission Denial: starting instrumentation "
11546                        + className + " from pid="
11547                        + Binder.getCallingPid()
11548                        + ", uid=" + Binder.getCallingPid()
11549                        + " not allowed because package " + ii.packageName
11550                        + " does not have a signature matching the target "
11551                        + ii.targetPackage;
11552                reportStartInstrumentationFailure(watcher, className, msg);
11553                throw new SecurityException(msg);
11554            }
11555
11556            int userId = UserHandle.getCallingUserId();
11557            final long origId = Binder.clearCallingIdentity();
11558            // Instrumentation can kill and relaunch even persistent processes
11559            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11560            ProcessRecord app = addAppLocked(ai, false);
11561            app.instrumentationClass = className;
11562            app.instrumentationInfo = ai;
11563            app.instrumentationProfileFile = profileFile;
11564            app.instrumentationArguments = arguments;
11565            app.instrumentationWatcher = watcher;
11566            app.instrumentationResultClass = className;
11567            Binder.restoreCallingIdentity(origId);
11568        }
11569
11570        return true;
11571    }
11572
11573    /**
11574     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11575     * error to the logs, but if somebody is watching, send the report there too.  This enables
11576     * the "am" command to report errors with more information.
11577     *
11578     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11579     * @param cn The component name of the instrumentation.
11580     * @param report The error report.
11581     */
11582    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11583            ComponentName cn, String report) {
11584        Slog.w(TAG, report);
11585        try {
11586            if (watcher != null) {
11587                Bundle results = new Bundle();
11588                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11589                results.putString("Error", report);
11590                watcher.instrumentationStatus(cn, -1, results);
11591            }
11592        } catch (RemoteException e) {
11593            Slog.w(TAG, e);
11594        }
11595    }
11596
11597    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11598        if (app.instrumentationWatcher != null) {
11599            try {
11600                // NOTE:  IInstrumentationWatcher *must* be oneway here
11601                app.instrumentationWatcher.instrumentationFinished(
11602                    app.instrumentationClass,
11603                    resultCode,
11604                    results);
11605            } catch (RemoteException e) {
11606            }
11607        }
11608        app.instrumentationWatcher = null;
11609        app.instrumentationClass = null;
11610        app.instrumentationInfo = null;
11611        app.instrumentationProfileFile = null;
11612        app.instrumentationArguments = null;
11613
11614        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11615    }
11616
11617    public void finishInstrumentation(IApplicationThread target,
11618            int resultCode, Bundle results) {
11619        int userId = UserHandle.getCallingUserId();
11620        // Refuse possible leaked file descriptors
11621        if (results != null && results.hasFileDescriptors()) {
11622            throw new IllegalArgumentException("File descriptors passed in Intent");
11623        }
11624
11625        synchronized(this) {
11626            ProcessRecord app = getRecordForAppLocked(target);
11627            if (app == null) {
11628                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11629                return;
11630            }
11631            final long origId = Binder.clearCallingIdentity();
11632            finishInstrumentationLocked(app, resultCode, results);
11633            Binder.restoreCallingIdentity(origId);
11634        }
11635    }
11636
11637    // =========================================================
11638    // CONFIGURATION
11639    // =========================================================
11640
11641    public ConfigurationInfo getDeviceConfigurationInfo() {
11642        ConfigurationInfo config = new ConfigurationInfo();
11643        synchronized (this) {
11644            config.reqTouchScreen = mConfiguration.touchscreen;
11645            config.reqKeyboardType = mConfiguration.keyboard;
11646            config.reqNavigation = mConfiguration.navigation;
11647            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11648                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11649                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11650            }
11651            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11652                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11653                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11654            }
11655            config.reqGlEsVersion = GL_ES_VERSION;
11656        }
11657        return config;
11658    }
11659
11660    public Configuration getConfiguration() {
11661        Configuration ci;
11662        synchronized(this) {
11663            ci = new Configuration(mConfiguration);
11664        }
11665        return ci;
11666    }
11667
11668    public void updatePersistentConfiguration(Configuration values) {
11669        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11670                "updateConfiguration()");
11671        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11672                "updateConfiguration()");
11673        if (values == null) {
11674            throw new NullPointerException("Configuration must not be null");
11675        }
11676
11677        synchronized(this) {
11678            final long origId = Binder.clearCallingIdentity();
11679            updateConfigurationLocked(values, null, true, false);
11680            Binder.restoreCallingIdentity(origId);
11681        }
11682    }
11683
11684    public void updateConfiguration(Configuration values) {
11685        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11686                "updateConfiguration()");
11687
11688        synchronized(this) {
11689            if (values == null && mWindowManager != null) {
11690                // sentinel: fetch the current configuration from the window manager
11691                values = mWindowManager.computeNewConfiguration();
11692            }
11693
11694            if (mWindowManager != null) {
11695                mProcessList.applyDisplaySize(mWindowManager);
11696            }
11697
11698            final long origId = Binder.clearCallingIdentity();
11699            if (values != null) {
11700                Settings.System.clearConfiguration(values);
11701            }
11702            updateConfigurationLocked(values, null, false, false);
11703            Binder.restoreCallingIdentity(origId);
11704        }
11705    }
11706
11707    /**
11708     * Do either or both things: (1) change the current configuration, and (2)
11709     * make sure the given activity is running with the (now) current
11710     * configuration.  Returns true if the activity has been left running, or
11711     * false if <var>starting</var> is being destroyed to match the new
11712     * configuration.
11713     * @param persistent TODO
11714     */
11715    boolean updateConfigurationLocked(Configuration values,
11716            ActivityRecord starting, boolean persistent, boolean initLocale) {
11717        // do nothing if we are headless
11718        if (mHeadless) return true;
11719
11720        int changes = 0;
11721
11722        boolean kept = true;
11723
11724        if (values != null) {
11725            Configuration newConfig = new Configuration(mConfiguration);
11726            changes = newConfig.updateFrom(values);
11727            if (changes != 0) {
11728                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11729                    Slog.i(TAG, "Updating configuration to: " + values);
11730                }
11731
11732                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11733
11734                if (values.locale != null && !initLocale) {
11735                    saveLocaleLocked(values.locale,
11736                                     !values.locale.equals(mConfiguration.locale),
11737                                     values.userSetLocale);
11738                }
11739
11740                mConfigurationSeq++;
11741                if (mConfigurationSeq <= 0) {
11742                    mConfigurationSeq = 1;
11743                }
11744                newConfig.seq = mConfigurationSeq;
11745                mConfiguration = newConfig;
11746                Slog.i(TAG, "Config changed: " + newConfig);
11747
11748                final Configuration configCopy = new Configuration(mConfiguration);
11749
11750                // TODO: If our config changes, should we auto dismiss any currently
11751                // showing dialogs?
11752                mShowDialogs = shouldShowDialogs(newConfig);
11753
11754                AttributeCache ac = AttributeCache.instance();
11755                if (ac != null) {
11756                    ac.updateConfiguration(configCopy);
11757                }
11758
11759                // Make sure all resources in our process are updated
11760                // right now, so that anyone who is going to retrieve
11761                // resource values after we return will be sure to get
11762                // the new ones.  This is especially important during
11763                // boot, where the first config change needs to guarantee
11764                // all resources have that config before following boot
11765                // code is executed.
11766                mSystemThread.applyConfigurationToResources(configCopy);
11767
11768                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11769                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11770                    msg.obj = new Configuration(configCopy);
11771                    mHandler.sendMessage(msg);
11772                }
11773
11774                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11775                    ProcessRecord app = mLruProcesses.get(i);
11776                    try {
11777                        if (app.thread != null) {
11778                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11779                                    + app.processName + " new config " + mConfiguration);
11780                            app.thread.scheduleConfigurationChanged(configCopy);
11781                        }
11782                    } catch (Exception e) {
11783                    }
11784                }
11785                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11786                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11787                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11788                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11789                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11790                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11791                    broadcastIntentLocked(null, null,
11792                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11793                            null, null, 0, null, null,
11794                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11795                }
11796            }
11797        }
11798
11799        if (changes != 0 && starting == null) {
11800            // If the configuration changed, and the caller is not already
11801            // in the process of starting an activity, then find the top
11802            // activity to check if its configuration needs to change.
11803            starting = mMainStack.topRunningActivityLocked(null);
11804        }
11805
11806        if (starting != null) {
11807            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11808            // And we need to make sure at this point that all other activities
11809            // are made visible with the correct configuration.
11810            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11811        }
11812
11813        if (values != null && mWindowManager != null) {
11814            mWindowManager.setNewConfiguration(mConfiguration);
11815        }
11816
11817        return kept;
11818    }
11819
11820    /**
11821     * Decide based on the configuration whether we should shouw the ANR,
11822     * crash, etc dialogs.  The idea is that if there is no affordnace to
11823     * press the on-screen buttons, we shouldn't show the dialog.
11824     *
11825     * A thought: SystemUI might also want to get told about this, the Power
11826     * dialog / global actions also might want different behaviors.
11827     */
11828    private static final boolean shouldShowDialogs(Configuration config) {
11829        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11830                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11831    }
11832
11833    /**
11834     * Save the locale.  You must be inside a synchronized (this) block.
11835     */
11836    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11837        if(isDiff) {
11838            SystemProperties.set("user.language", l.getLanguage());
11839            SystemProperties.set("user.region", l.getCountry());
11840        }
11841
11842        if(isPersist) {
11843            SystemProperties.set("persist.sys.language", l.getLanguage());
11844            SystemProperties.set("persist.sys.country", l.getCountry());
11845            SystemProperties.set("persist.sys.localevar", l.getVariant());
11846        }
11847    }
11848
11849    @Override
11850    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11851        ActivityRecord srec = ActivityRecord.forToken(token);
11852        return srec != null && srec.task.affinity != null &&
11853                srec.task.affinity.equals(destAffinity);
11854    }
11855
11856    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11857            Intent resultData) {
11858        ComponentName dest = destIntent.getComponent();
11859
11860        synchronized (this) {
11861            ActivityRecord srec = ActivityRecord.forToken(token);
11862            if (srec == null) {
11863                return false;
11864            }
11865            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11866            final int start = history.indexOf(srec);
11867            if (start < 0) {
11868                // Current activity is not in history stack; do nothing.
11869                return false;
11870            }
11871            int finishTo = start - 1;
11872            ActivityRecord parent = null;
11873            boolean foundParentInTask = false;
11874            if (dest != null) {
11875                TaskRecord tr = srec.task;
11876                for (int i = start - 1; i >= 0; i--) {
11877                    ActivityRecord r = history.get(i);
11878                    if (tr != r.task) {
11879                        // Couldn't find parent in the same task; stop at the one above this.
11880                        // (Root of current task; in-app "home" behavior)
11881                        // Always at least finish the current activity.
11882                        finishTo = Math.min(start - 1, i + 1);
11883                        parent = history.get(finishTo);
11884                        break;
11885                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11886                            r.info.name.equals(dest.getClassName())) {
11887                        finishTo = i;
11888                        parent = r;
11889                        foundParentInTask = true;
11890                        break;
11891                    }
11892                }
11893            }
11894
11895            if (mController != null) {
11896                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11897                if (next != null) {
11898                    // ask watcher if this is allowed
11899                    boolean resumeOK = true;
11900                    try {
11901                        resumeOK = mController.activityResuming(next.packageName);
11902                    } catch (RemoteException e) {
11903                        mController = null;
11904                    }
11905
11906                    if (!resumeOK) {
11907                        return false;
11908                    }
11909                }
11910            }
11911            final long origId = Binder.clearCallingIdentity();
11912            for (int i = start; i > finishTo; i--) {
11913                ActivityRecord r = history.get(i);
11914                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11915                        "navigate-up");
11916                // Only return the supplied result for the first activity finished
11917                resultCode = Activity.RESULT_CANCELED;
11918                resultData = null;
11919            }
11920
11921            if (parent != null && foundParentInTask) {
11922                final int parentLaunchMode = parent.info.launchMode;
11923                final int destIntentFlags = destIntent.getFlags();
11924                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11925                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11926                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11927                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11928                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11929                } else {
11930                    try {
11931                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11932                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
11933                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11934                                null, aInfo, parent.appToken, null,
11935                                0, -1, parent.launchedFromUid, 0, null, true, null);
11936                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11937                    } catch (RemoteException e) {
11938                        foundParentInTask = false;
11939                    }
11940                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11941                            resultData, "navigate-up");
11942                }
11943            }
11944            Binder.restoreCallingIdentity(origId);
11945            return foundParentInTask;
11946        }
11947    }
11948
11949    public int getLaunchedFromUid(IBinder activityToken) {
11950        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11951        if (srec == null) {
11952            return -1;
11953        }
11954        return srec.launchedFromUid;
11955    }
11956
11957    // =========================================================
11958    // LIFETIME MANAGEMENT
11959    // =========================================================
11960
11961    // Returns which broadcast queue the app is the current [or imminent] receiver
11962    // on, or 'null' if the app is not an active broadcast recipient.
11963    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11964        BroadcastRecord r = app.curReceiver;
11965        if (r != null) {
11966            return r.queue;
11967        }
11968
11969        // It's not the current receiver, but it might be starting up to become one
11970        synchronized (this) {
11971            for (BroadcastQueue queue : mBroadcastQueues) {
11972                r = queue.mPendingBroadcast;
11973                if (r != null && r.curApp == app) {
11974                    // found it; report which queue it's in
11975                    return queue;
11976                }
11977            }
11978        }
11979
11980        return null;
11981    }
11982
11983    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11984            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
11985        if (mAdjSeq == app.adjSeq) {
11986            // This adjustment has already been computed.  If we are calling
11987            // from the top, we may have already computed our adjustment with
11988            // an earlier hidden adjustment that isn't really for us... if
11989            // so, use the new hidden adjustment.
11990            if (!recursed && app.hidden) {
11991                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
11992                        app.hasActivities ? hiddenAdj : emptyAdj;
11993            }
11994            return app.curRawAdj;
11995        }
11996
11997        if (app.thread == null) {
11998            app.adjSeq = mAdjSeq;
11999            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12000            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12001        }
12002
12003        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12004        app.adjSource = null;
12005        app.adjTarget = null;
12006        app.empty = false;
12007        app.hidden = false;
12008
12009        final int activitiesSize = app.activities.size();
12010
12011        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12012            // The max adjustment doesn't allow this app to be anything
12013            // below foreground, so it is not worth doing work for it.
12014            app.adjType = "fixed";
12015            app.adjSeq = mAdjSeq;
12016            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12017            app.hasActivities = false;
12018            app.foregroundActivities = false;
12019            app.keeping = true;
12020            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12021            // System process can do UI, and when they do we want to have
12022            // them trim their memory after the user leaves the UI.  To
12023            // facilitate this, here we need to determine whether or not it
12024            // is currently showing UI.
12025            app.systemNoUi = true;
12026            if (app == TOP_APP) {
12027                app.systemNoUi = false;
12028                app.hasActivities = true;
12029            } else if (activitiesSize > 0) {
12030                for (int j = 0; j < activitiesSize; j++) {
12031                    final ActivityRecord r = app.activities.get(j);
12032                    if (r.visible) {
12033                        app.systemNoUi = false;
12034                    }
12035                    if (r.app == app) {
12036                        app.hasActivities = true;
12037                    }
12038                }
12039            }
12040            return (app.curAdj=app.maxAdj);
12041        }
12042
12043        app.keeping = false;
12044        app.systemNoUi = false;
12045        app.hasActivities = false;
12046
12047        // Determine the importance of the process, starting with most
12048        // important to least, and assign an appropriate OOM adjustment.
12049        int adj;
12050        int schedGroup;
12051        boolean foregroundActivities = false;
12052        boolean interesting = false;
12053        BroadcastQueue queue;
12054        if (app == TOP_APP) {
12055            // The last app on the list is the foreground app.
12056            adj = ProcessList.FOREGROUND_APP_ADJ;
12057            schedGroup = Process.THREAD_GROUP_DEFAULT;
12058            app.adjType = "top-activity";
12059            foregroundActivities = true;
12060            interesting = true;
12061            app.hasActivities = true;
12062        } else if (app.instrumentationClass != null) {
12063            // Don't want to kill running instrumentation.
12064            adj = ProcessList.FOREGROUND_APP_ADJ;
12065            schedGroup = Process.THREAD_GROUP_DEFAULT;
12066            app.adjType = "instrumentation";
12067            interesting = true;
12068        } else if ((queue = isReceivingBroadcast(app)) != null) {
12069            // An app that is currently receiving a broadcast also
12070            // counts as being in the foreground for OOM killer purposes.
12071            // It's placed in a sched group based on the nature of the
12072            // broadcast as reflected by which queue it's active in.
12073            adj = ProcessList.FOREGROUND_APP_ADJ;
12074            schedGroup = (queue == mFgBroadcastQueue)
12075                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12076            app.adjType = "broadcast";
12077        } else if (app.executingServices.size() > 0) {
12078            // An app that is currently executing a service callback also
12079            // counts as being in the foreground.
12080            adj = ProcessList.FOREGROUND_APP_ADJ;
12081            schedGroup = Process.THREAD_GROUP_DEFAULT;
12082            app.adjType = "exec-service";
12083        } else {
12084            // Assume process is hidden (has activities); we will correct
12085            // later if this is not the case.
12086            adj = hiddenAdj;
12087            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12088            app.hidden = true;
12089            app.adjType = "bg-activities";
12090        }
12091
12092        boolean hasStoppingActivities = false;
12093
12094        // Examine all activities if not already foreground.
12095        if (!foregroundActivities && activitiesSize > 0) {
12096            for (int j = 0; j < activitiesSize; j++) {
12097                final ActivityRecord r = app.activities.get(j);
12098                if (r.visible) {
12099                    // App has a visible activity; only upgrade adjustment.
12100                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12101                        adj = ProcessList.VISIBLE_APP_ADJ;
12102                        app.adjType = "visible";
12103                    }
12104                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12105                    app.hidden = false;
12106                    app.hasActivities = true;
12107                    foregroundActivities = true;
12108                    break;
12109                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12110                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12111                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12112                        app.adjType = "pausing";
12113                    }
12114                    app.hidden = false;
12115                    foregroundActivities = true;
12116                } else if (r.state == ActivityState.STOPPING) {
12117                    // We will apply the actual adjustment later, because
12118                    // we want to allow this process to immediately go through
12119                    // any memory trimming that is in effect.
12120                    app.hidden = false;
12121                    foregroundActivities = true;
12122                    hasStoppingActivities = true;
12123                }
12124                if (r.app == app) {
12125                    app.hasActivities = true;
12126                }
12127            }
12128        }
12129
12130        if (adj == hiddenAdj && !app.hasActivities) {
12131            // Whoops, this process is completely empty as far as we know
12132            // at this point.
12133            adj = emptyAdj;
12134            app.empty = true;
12135            app.adjType = "bg-empty";
12136        }
12137
12138        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12139            if (app.foregroundServices) {
12140                // The user is aware of this app, so make it visible.
12141                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12142                app.hidden = false;
12143                app.adjType = "foreground-service";
12144                schedGroup = Process.THREAD_GROUP_DEFAULT;
12145            } else if (app.forcingToForeground != null) {
12146                // The user is aware of this app, so make it visible.
12147                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12148                app.hidden = false;
12149                app.adjType = "force-foreground";
12150                app.adjSource = app.forcingToForeground;
12151                schedGroup = Process.THREAD_GROUP_DEFAULT;
12152            }
12153        }
12154
12155        if (app.foregroundServices) {
12156            interesting = true;
12157        }
12158
12159        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12160            // We don't want to kill the current heavy-weight process.
12161            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12162            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12163            app.hidden = false;
12164            app.adjType = "heavy";
12165        }
12166
12167        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12168            // This process is hosting what we currently consider to be the
12169            // home app, so we don't want to let it go into the background.
12170            adj = ProcessList.HOME_APP_ADJ;
12171            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12172            app.hidden = false;
12173            app.adjType = "home";
12174        }
12175
12176        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12177                && app.activities.size() > 0) {
12178            // This was the previous process that showed UI to the user.
12179            // We want to try to keep it around more aggressively, to give
12180            // a good experience around switching between two apps.
12181            adj = ProcessList.PREVIOUS_APP_ADJ;
12182            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12183            app.hidden = false;
12184            app.adjType = "previous";
12185        }
12186
12187        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12188                + " reason=" + app.adjType);
12189
12190        // By default, we use the computed adjustment.  It may be changed if
12191        // there are applications dependent on our services or providers, but
12192        // this gives us a baseline and makes sure we don't get into an
12193        // infinite recursion.
12194        app.adjSeq = mAdjSeq;
12195        app.curRawAdj = app.nonStoppingAdj = adj;
12196
12197        if (mBackupTarget != null && app == mBackupTarget.app) {
12198            // If possible we want to avoid killing apps while they're being backed up
12199            if (adj > ProcessList.BACKUP_APP_ADJ) {
12200                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12201                adj = ProcessList.BACKUP_APP_ADJ;
12202                app.adjType = "backup";
12203                app.hidden = false;
12204            }
12205        }
12206
12207        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12208                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12209            final long now = SystemClock.uptimeMillis();
12210            // This process is more important if the top activity is
12211            // bound to the service.
12212            Iterator<ServiceRecord> jt = app.services.iterator();
12213            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12214                ServiceRecord s = jt.next();
12215                if (s.startRequested) {
12216                    if (app.hasShownUi && app != mHomeProcess) {
12217                        // If this process has shown some UI, let it immediately
12218                        // go to the LRU list because it may be pretty heavy with
12219                        // UI stuff.  We'll tag it with a label just to help
12220                        // debug and understand what is going on.
12221                        if (adj > ProcessList.SERVICE_ADJ) {
12222                            app.adjType = "started-bg-ui-services";
12223                        }
12224                    } else {
12225                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12226                            // This service has seen some activity within
12227                            // recent memory, so we will keep its process ahead
12228                            // of the background processes.
12229                            if (adj > ProcessList.SERVICE_ADJ) {
12230                                adj = ProcessList.SERVICE_ADJ;
12231                                app.adjType = "started-services";
12232                                app.hidden = false;
12233                            }
12234                        }
12235                        // If we have let the service slide into the background
12236                        // state, still have some text describing what it is doing
12237                        // even though the service no longer has an impact.
12238                        if (adj > ProcessList.SERVICE_ADJ) {
12239                            app.adjType = "started-bg-services";
12240                        }
12241                    }
12242                    // Don't kill this process because it is doing work; it
12243                    // has said it is doing work.
12244                    app.keeping = true;
12245                }
12246                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12247                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12248                    Iterator<ArrayList<ConnectionRecord>> kt
12249                            = s.connections.values().iterator();
12250                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12251                        ArrayList<ConnectionRecord> clist = kt.next();
12252                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12253                            // XXX should compute this based on the max of
12254                            // all connected clients.
12255                            ConnectionRecord cr = clist.get(i);
12256                            if (cr.binding.client == app) {
12257                                // Binding to ourself is not interesting.
12258                                continue;
12259                            }
12260                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12261                                ProcessRecord client = cr.binding.client;
12262                                int clientAdj = adj;
12263                                int myHiddenAdj = hiddenAdj;
12264                                if (myHiddenAdj > client.hiddenAdj) {
12265                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12266                                        myHiddenAdj = client.hiddenAdj;
12267                                    } else {
12268                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12269                                    }
12270                                }
12271                                int myEmptyAdj = emptyAdj;
12272                                if (myEmptyAdj > client.emptyAdj) {
12273                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12274                                        myEmptyAdj = client.emptyAdj;
12275                                    } else {
12276                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12277                                    }
12278                                }
12279                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12280                                        myEmptyAdj, TOP_APP, true, doingAll);
12281                                String adjType = null;
12282                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12283                                    // Not doing bind OOM management, so treat
12284                                    // this guy more like a started service.
12285                                    if (app.hasShownUi && app != mHomeProcess) {
12286                                        // If this process has shown some UI, let it immediately
12287                                        // go to the LRU list because it may be pretty heavy with
12288                                        // UI stuff.  We'll tag it with a label just to help
12289                                        // debug and understand what is going on.
12290                                        if (adj > clientAdj) {
12291                                            adjType = "bound-bg-ui-services";
12292                                        }
12293                                        app.hidden = false;
12294                                        clientAdj = adj;
12295                                    } else {
12296                                        if (now >= (s.lastActivity
12297                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12298                                            // This service has not seen activity within
12299                                            // recent memory, so allow it to drop to the
12300                                            // LRU list if there is no other reason to keep
12301                                            // it around.  We'll also tag it with a label just
12302                                            // to help debug and undertand what is going on.
12303                                            if (adj > clientAdj) {
12304                                                adjType = "bound-bg-services";
12305                                            }
12306                                            clientAdj = adj;
12307                                        }
12308                                    }
12309                                }
12310                                if (adj > clientAdj) {
12311                                    // If this process has recently shown UI, and
12312                                    // the process that is binding to it is less
12313                                    // important than being visible, then we don't
12314                                    // care about the binding as much as we care
12315                                    // about letting this process get into the LRU
12316                                    // list to be killed and restarted if needed for
12317                                    // memory.
12318                                    if (app.hasShownUi && app != mHomeProcess
12319                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12320                                        adjType = "bound-bg-ui-services";
12321                                    } else {
12322                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12323                                                |Context.BIND_IMPORTANT)) != 0) {
12324                                            adj = clientAdj;
12325                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12326                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12327                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12328                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12329                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12330                                            adj = clientAdj;
12331                                        } else {
12332                                            app.pendingUiClean = true;
12333                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12334                                                adj = ProcessList.VISIBLE_APP_ADJ;
12335                                            }
12336                                        }
12337                                        if (!client.hidden) {
12338                                            app.hidden = false;
12339                                        }
12340                                        if (client.keeping) {
12341                                            app.keeping = true;
12342                                        }
12343                                        adjType = "service";
12344                                    }
12345                                }
12346                                if (adjType != null) {
12347                                    app.adjType = adjType;
12348                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12349                                            .REASON_SERVICE_IN_USE;
12350                                    app.adjSource = cr.binding.client;
12351                                    app.adjSourceOom = clientAdj;
12352                                    app.adjTarget = s.name;
12353                                }
12354                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12355                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12356                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12357                                    }
12358                                }
12359                            }
12360                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12361                                ActivityRecord a = cr.activity;
12362                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12363                                        (a.visible || a.state == ActivityState.RESUMED
12364                                         || a.state == ActivityState.PAUSING)) {
12365                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12366                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12367                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12368                                    }
12369                                    app.hidden = false;
12370                                    app.adjType = "service";
12371                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12372                                            .REASON_SERVICE_IN_USE;
12373                                    app.adjSource = a;
12374                                    app.adjSourceOom = adj;
12375                                    app.adjTarget = s.name;
12376                                }
12377                            }
12378                        }
12379                    }
12380                }
12381            }
12382
12383            // Finally, if this process has active services running in it, we
12384            // would like to avoid killing it unless it would prevent the current
12385            // application from running.  By default we put the process in
12386            // with the rest of the background processes; as we scan through
12387            // its services we may bump it up from there.
12388            if (adj > hiddenAdj) {
12389                adj = hiddenAdj;
12390                app.hidden = false;
12391                app.adjType = "bg-services";
12392            }
12393        }
12394
12395        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12396                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12397            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12398            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12399                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12400                ContentProviderRecord cpr = jt.next();
12401                for (int i = cpr.connections.size()-1;
12402                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12403                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12404                        i--) {
12405                    ContentProviderConnection conn = cpr.connections.get(i);
12406                    ProcessRecord client = conn.client;
12407                    if (client == app) {
12408                        // Being our own client is not interesting.
12409                        continue;
12410                    }
12411                    int myHiddenAdj = hiddenAdj;
12412                    if (myHiddenAdj > client.hiddenAdj) {
12413                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12414                            myHiddenAdj = client.hiddenAdj;
12415                        } else {
12416                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12417                        }
12418                    }
12419                    int myEmptyAdj = emptyAdj;
12420                    if (myEmptyAdj > client.emptyAdj) {
12421                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12422                            myEmptyAdj = client.emptyAdj;
12423                        } else {
12424                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12425                        }
12426                    }
12427                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12428                            myEmptyAdj, TOP_APP, true, doingAll);
12429                    if (adj > clientAdj) {
12430                        if (app.hasShownUi && app != mHomeProcess
12431                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12432                            app.adjType = "bg-ui-provider";
12433                        } else {
12434                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12435                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12436                            app.adjType = "provider";
12437                        }
12438                        if (!client.hidden) {
12439                            app.hidden = false;
12440                        }
12441                        if (client.keeping) {
12442                            app.keeping = true;
12443                        }
12444                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12445                                .REASON_PROVIDER_IN_USE;
12446                        app.adjSource = client;
12447                        app.adjSourceOom = clientAdj;
12448                        app.adjTarget = cpr.name;
12449                    }
12450                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12451                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12452                    }
12453                }
12454                // If the provider has external (non-framework) process
12455                // dependencies, ensure that its adjustment is at least
12456                // FOREGROUND_APP_ADJ.
12457                if (cpr.hasExternalProcessHandles()) {
12458                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12459                        adj = ProcessList.FOREGROUND_APP_ADJ;
12460                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12461                        app.hidden = false;
12462                        app.keeping = true;
12463                        app.adjType = "provider";
12464                        app.adjTarget = cpr.name;
12465                    }
12466                }
12467            }
12468        }
12469
12470        if (adj == ProcessList.SERVICE_ADJ) {
12471            if (doingAll) {
12472                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12473                mNewNumServiceProcs++;
12474            }
12475            if (app.serviceb) {
12476                adj = ProcessList.SERVICE_B_ADJ;
12477            }
12478        } else {
12479            app.serviceb = false;
12480        }
12481
12482        app.nonStoppingAdj = adj;
12483
12484        if (hasStoppingActivities) {
12485            // Only upgrade adjustment.
12486            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12487                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12488                app.adjType = "stopping";
12489            }
12490        }
12491
12492        app.curRawAdj = adj;
12493
12494        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12495        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12496        if (adj > app.maxAdj) {
12497            adj = app.maxAdj;
12498            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12499                schedGroup = Process.THREAD_GROUP_DEFAULT;
12500            }
12501        }
12502        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12503            app.keeping = true;
12504        }
12505
12506        if (app.hasAboveClient) {
12507            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12508            // then we need to drop its adjustment to be lower than the service's
12509            // in order to honor the request.  We want to drop it by one adjustment
12510            // level...  but there is special meaning applied to various levels so
12511            // we will skip some of them.
12512            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12513                // System process will not get dropped, ever
12514            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12515                adj = ProcessList.VISIBLE_APP_ADJ;
12516            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12517                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12518            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12519                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12520            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12521                adj++;
12522            }
12523        }
12524
12525        int importance = app.memImportance;
12526        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12527            app.curAdj = adj;
12528            app.curSchedGroup = schedGroup;
12529            if (!interesting) {
12530                // For this reporting, if there is not something explicitly
12531                // interesting in this process then we will push it to the
12532                // background importance.
12533                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12534            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12535                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12536            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12537                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12538            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12539                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12540            } else if (adj >= ProcessList.SERVICE_ADJ) {
12541                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12542            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12543                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12544            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12545                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12546            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12547                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12548            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12549                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12550            } else {
12551                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12552            }
12553        }
12554
12555        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12556        if (foregroundActivities != app.foregroundActivities) {
12557            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12558        }
12559        if (changes != 0) {
12560            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12561            app.memImportance = importance;
12562            app.foregroundActivities = foregroundActivities;
12563            int i = mPendingProcessChanges.size()-1;
12564            ProcessChangeItem item = null;
12565            while (i >= 0) {
12566                item = mPendingProcessChanges.get(i);
12567                if (item.pid == app.pid) {
12568                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12569                    break;
12570                }
12571                i--;
12572            }
12573            if (i < 0) {
12574                // No existing item in pending changes; need a new one.
12575                final int NA = mAvailProcessChanges.size();
12576                if (NA > 0) {
12577                    item = mAvailProcessChanges.remove(NA-1);
12578                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12579                } else {
12580                    item = new ProcessChangeItem();
12581                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12582                }
12583                item.changes = 0;
12584                item.pid = app.pid;
12585                item.uid = app.info.uid;
12586                if (mPendingProcessChanges.size() == 0) {
12587                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12588                            "*** Enqueueing dispatch processes changed!");
12589                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12590                }
12591                mPendingProcessChanges.add(item);
12592            }
12593            item.changes |= changes;
12594            item.importance = importance;
12595            item.foregroundActivities = foregroundActivities;
12596            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12597                    + Integer.toHexString(System.identityHashCode(item))
12598                    + " " + app.toShortString() + ": changes=" + item.changes
12599                    + " importance=" + item.importance
12600                    + " foreground=" + item.foregroundActivities
12601                    + " type=" + app.adjType + " source=" + app.adjSource
12602                    + " target=" + app.adjTarget);
12603        }
12604
12605        return app.curRawAdj;
12606    }
12607
12608    /**
12609     * Ask a given process to GC right now.
12610     */
12611    final void performAppGcLocked(ProcessRecord app) {
12612        try {
12613            app.lastRequestedGc = SystemClock.uptimeMillis();
12614            if (app.thread != null) {
12615                if (app.reportLowMemory) {
12616                    app.reportLowMemory = false;
12617                    app.thread.scheduleLowMemory();
12618                } else {
12619                    app.thread.processInBackground();
12620                }
12621            }
12622        } catch (Exception e) {
12623            // whatever.
12624        }
12625    }
12626
12627    /**
12628     * Returns true if things are idle enough to perform GCs.
12629     */
12630    private final boolean canGcNowLocked() {
12631        boolean processingBroadcasts = false;
12632        for (BroadcastQueue q : mBroadcastQueues) {
12633            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12634                processingBroadcasts = true;
12635            }
12636        }
12637        return !processingBroadcasts
12638                && (mSleeping || (mMainStack.mResumedActivity != null &&
12639                        mMainStack.mResumedActivity.idle));
12640    }
12641
12642    /**
12643     * Perform GCs on all processes that are waiting for it, but only
12644     * if things are idle.
12645     */
12646    final void performAppGcsLocked() {
12647        final int N = mProcessesToGc.size();
12648        if (N <= 0) {
12649            return;
12650        }
12651        if (canGcNowLocked()) {
12652            while (mProcessesToGc.size() > 0) {
12653                ProcessRecord proc = mProcessesToGc.remove(0);
12654                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12655                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12656                            <= SystemClock.uptimeMillis()) {
12657                        // To avoid spamming the system, we will GC processes one
12658                        // at a time, waiting a few seconds between each.
12659                        performAppGcLocked(proc);
12660                        scheduleAppGcsLocked();
12661                        return;
12662                    } else {
12663                        // It hasn't been long enough since we last GCed this
12664                        // process...  put it in the list to wait for its time.
12665                        addProcessToGcListLocked(proc);
12666                        break;
12667                    }
12668                }
12669            }
12670
12671            scheduleAppGcsLocked();
12672        }
12673    }
12674
12675    /**
12676     * If all looks good, perform GCs on all processes waiting for them.
12677     */
12678    final void performAppGcsIfAppropriateLocked() {
12679        if (canGcNowLocked()) {
12680            performAppGcsLocked();
12681            return;
12682        }
12683        // Still not idle, wait some more.
12684        scheduleAppGcsLocked();
12685    }
12686
12687    /**
12688     * Schedule the execution of all pending app GCs.
12689     */
12690    final void scheduleAppGcsLocked() {
12691        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12692
12693        if (mProcessesToGc.size() > 0) {
12694            // Schedule a GC for the time to the next process.
12695            ProcessRecord proc = mProcessesToGc.get(0);
12696            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12697
12698            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12699            long now = SystemClock.uptimeMillis();
12700            if (when < (now+GC_TIMEOUT)) {
12701                when = now + GC_TIMEOUT;
12702            }
12703            mHandler.sendMessageAtTime(msg, when);
12704        }
12705    }
12706
12707    /**
12708     * Add a process to the array of processes waiting to be GCed.  Keeps the
12709     * list in sorted order by the last GC time.  The process can't already be
12710     * on the list.
12711     */
12712    final void addProcessToGcListLocked(ProcessRecord proc) {
12713        boolean added = false;
12714        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12715            if (mProcessesToGc.get(i).lastRequestedGc <
12716                    proc.lastRequestedGc) {
12717                added = true;
12718                mProcessesToGc.add(i+1, proc);
12719                break;
12720            }
12721        }
12722        if (!added) {
12723            mProcessesToGc.add(0, proc);
12724        }
12725    }
12726
12727    /**
12728     * Set up to ask a process to GC itself.  This will either do it
12729     * immediately, or put it on the list of processes to gc the next
12730     * time things are idle.
12731     */
12732    final void scheduleAppGcLocked(ProcessRecord app) {
12733        long now = SystemClock.uptimeMillis();
12734        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12735            return;
12736        }
12737        if (!mProcessesToGc.contains(app)) {
12738            addProcessToGcListLocked(app);
12739            scheduleAppGcsLocked();
12740        }
12741    }
12742
12743    final void checkExcessivePowerUsageLocked(boolean doKills) {
12744        updateCpuStatsNow();
12745
12746        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12747        boolean doWakeKills = doKills;
12748        boolean doCpuKills = doKills;
12749        if (mLastPowerCheckRealtime == 0) {
12750            doWakeKills = false;
12751        }
12752        if (mLastPowerCheckUptime == 0) {
12753            doCpuKills = false;
12754        }
12755        if (stats.isScreenOn()) {
12756            doWakeKills = false;
12757        }
12758        final long curRealtime = SystemClock.elapsedRealtime();
12759        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12760        final long curUptime = SystemClock.uptimeMillis();
12761        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12762        mLastPowerCheckRealtime = curRealtime;
12763        mLastPowerCheckUptime = curUptime;
12764        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12765            doWakeKills = false;
12766        }
12767        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12768            doCpuKills = false;
12769        }
12770        int i = mLruProcesses.size();
12771        while (i > 0) {
12772            i--;
12773            ProcessRecord app = mLruProcesses.get(i);
12774            if (!app.keeping) {
12775                long wtime;
12776                synchronized (stats) {
12777                    wtime = stats.getProcessWakeTime(app.info.uid,
12778                            app.pid, curRealtime);
12779                }
12780                long wtimeUsed = wtime - app.lastWakeTime;
12781                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12782                if (DEBUG_POWER) {
12783                    StringBuilder sb = new StringBuilder(128);
12784                    sb.append("Wake for ");
12785                    app.toShortString(sb);
12786                    sb.append(": over ");
12787                    TimeUtils.formatDuration(realtimeSince, sb);
12788                    sb.append(" used ");
12789                    TimeUtils.formatDuration(wtimeUsed, sb);
12790                    sb.append(" (");
12791                    sb.append((wtimeUsed*100)/realtimeSince);
12792                    sb.append("%)");
12793                    Slog.i(TAG, sb.toString());
12794                    sb.setLength(0);
12795                    sb.append("CPU for ");
12796                    app.toShortString(sb);
12797                    sb.append(": over ");
12798                    TimeUtils.formatDuration(uptimeSince, sb);
12799                    sb.append(" used ");
12800                    TimeUtils.formatDuration(cputimeUsed, sb);
12801                    sb.append(" (");
12802                    sb.append((cputimeUsed*100)/uptimeSince);
12803                    sb.append("%)");
12804                    Slog.i(TAG, sb.toString());
12805                }
12806                // If a process has held a wake lock for more
12807                // than 50% of the time during this period,
12808                // that sounds bad.  Kill!
12809                if (doWakeKills && realtimeSince > 0
12810                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12811                    synchronized (stats) {
12812                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12813                                realtimeSince, wtimeUsed);
12814                    }
12815                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12816                            + " (pid " + app.pid + "): held " + wtimeUsed
12817                            + " during " + realtimeSince);
12818                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12819                            app.processName, app.setAdj, "excessive wake lock");
12820                    Process.killProcessQuiet(app.pid);
12821                } else if (doCpuKills && uptimeSince > 0
12822                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12823                    synchronized (stats) {
12824                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12825                                uptimeSince, cputimeUsed);
12826                    }
12827                    Slog.w(TAG, "Excessive CPU in " + app.processName
12828                            + " (pid " + app.pid + "): used " + cputimeUsed
12829                            + " during " + uptimeSince);
12830                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12831                            app.processName, app.setAdj, "excessive cpu");
12832                    Process.killProcessQuiet(app.pid);
12833                } else {
12834                    app.lastWakeTime = wtime;
12835                    app.lastCpuTime = app.curCpuTime;
12836                }
12837            }
12838        }
12839    }
12840
12841    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12842            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12843        app.hiddenAdj = hiddenAdj;
12844        app.emptyAdj = emptyAdj;
12845
12846        if (app.thread == null) {
12847            return false;
12848        }
12849
12850        final boolean wasKeeping = app.keeping;
12851
12852        boolean success = true;
12853
12854        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12855
12856        if (app.curRawAdj != app.setRawAdj) {
12857            if (wasKeeping && !app.keeping) {
12858                // This app is no longer something we want to keep.  Note
12859                // its current wake lock time to later know to kill it if
12860                // it is not behaving well.
12861                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12862                synchronized (stats) {
12863                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12864                            app.pid, SystemClock.elapsedRealtime());
12865                }
12866                app.lastCpuTime = app.curCpuTime;
12867            }
12868
12869            app.setRawAdj = app.curRawAdj;
12870        }
12871
12872        if (app.curAdj != app.setAdj) {
12873            if (Process.setOomAdj(app.pid, app.curAdj)) {
12874                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12875                    TAG, "Set " + app.pid + " " + app.processName +
12876                    " adj " + app.curAdj + ": " + app.adjType);
12877                app.setAdj = app.curAdj;
12878            } else {
12879                success = false;
12880                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12881            }
12882        }
12883        if (app.setSchedGroup != app.curSchedGroup) {
12884            app.setSchedGroup = app.curSchedGroup;
12885            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12886                    "Setting process group of " + app.processName
12887                    + " to " + app.curSchedGroup);
12888            if (app.waitingToKill != null &&
12889                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12890                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12891                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12892                        app.processName, app.setAdj, app.waitingToKill);
12893                app.killedBackground = true;
12894                Process.killProcessQuiet(app.pid);
12895                success = false;
12896            } else {
12897                if (true) {
12898                    long oldId = Binder.clearCallingIdentity();
12899                    try {
12900                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12901                    } catch (Exception e) {
12902                        Slog.w(TAG, "Failed setting process group of " + app.pid
12903                                + " to " + app.curSchedGroup);
12904                        e.printStackTrace();
12905                    } finally {
12906                        Binder.restoreCallingIdentity(oldId);
12907                    }
12908                } else {
12909                    if (app.thread != null) {
12910                        try {
12911                            app.thread.setSchedulingGroup(app.curSchedGroup);
12912                        } catch (RemoteException e) {
12913                        }
12914                    }
12915                }
12916            }
12917        }
12918        return success;
12919    }
12920
12921    private final ActivityRecord resumedAppLocked() {
12922        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12923        if (resumedActivity == null || resumedActivity.app == null) {
12924            resumedActivity = mMainStack.mPausingActivity;
12925            if (resumedActivity == null || resumedActivity.app == null) {
12926                resumedActivity = mMainStack.topRunningActivityLocked(null);
12927            }
12928        }
12929        return resumedActivity;
12930    }
12931
12932    final boolean updateOomAdjLocked(ProcessRecord app) {
12933        final ActivityRecord TOP_ACT = resumedAppLocked();
12934        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12935        int curAdj = app.curAdj;
12936        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12937            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12938
12939        mAdjSeq++;
12940
12941        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
12942                TOP_APP, false);
12943        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12944            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12945        if (nowHidden != wasHidden) {
12946            // Changed to/from hidden state, so apps after it in the LRU
12947            // list may also be changed.
12948            updateOomAdjLocked();
12949        }
12950        return success;
12951    }
12952
12953    final void updateOomAdjLocked() {
12954        final ActivityRecord TOP_ACT = resumedAppLocked();
12955        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12956
12957        if (false) {
12958            RuntimeException e = new RuntimeException();
12959            e.fillInStackTrace();
12960            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12961        }
12962
12963        mAdjSeq++;
12964        mNewNumServiceProcs = 0;
12965
12966        // Let's determine how many processes we have running vs.
12967        // how many slots we have for background processes; we may want
12968        // to put multiple processes in a slot of there are enough of
12969        // them.
12970        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
12971                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
12972        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
12973        if (emptyFactor < 1) emptyFactor = 1;
12974        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
12975        if (hiddenFactor < 1) hiddenFactor = 1;
12976        int stepHidden = 0;
12977        int stepEmpty = 0;
12978        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
12979        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
12980        int numHidden = 0;
12981        int numEmpty = 0;
12982        int numTrimming = 0;
12983
12984        mNumNonHiddenProcs = 0;
12985        mNumHiddenProcs = 0;
12986
12987        // First update the OOM adjustment for each of the
12988        // application processes based on their current state.
12989        int i = mLruProcesses.size();
12990        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
12991        int nextHiddenAdj = curHiddenAdj+1;
12992        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
12993        int nextEmptyAdj = curEmptyAdj+2;
12994        while (i > 0) {
12995            i--;
12996            ProcessRecord app = mLruProcesses.get(i);
12997            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
12998            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
12999            if (!app.killedBackground) {
13000                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13001                    // This process was assigned as a hidden process...  step the
13002                    // hidden level.
13003                    mNumHiddenProcs++;
13004                    if (curHiddenAdj != nextHiddenAdj) {
13005                        stepHidden++;
13006                        if (stepHidden >= hiddenFactor) {
13007                            stepHidden = 0;
13008                            curHiddenAdj = nextHiddenAdj;
13009                            nextHiddenAdj += 2;
13010                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13011                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13012                            }
13013                        }
13014                    }
13015                    numHidden++;
13016                    if (numHidden > hiddenProcessLimit) {
13017                        Slog.i(TAG, "No longer want " + app.processName
13018                                + " (pid " + app.pid + "): hidden #" + numHidden);
13019                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13020                                app.processName, app.setAdj, "too many background");
13021                        app.killedBackground = true;
13022                        Process.killProcessQuiet(app.pid);
13023                    }
13024                } else {
13025                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13026                        // This process was assigned as an empty process...  step the
13027                        // empty level.
13028                        if (curEmptyAdj != nextEmptyAdj) {
13029                            stepEmpty++;
13030                            if (stepEmpty >= emptyFactor) {
13031                                stepEmpty = 0;
13032                                curEmptyAdj = nextEmptyAdj;
13033                                nextEmptyAdj += 2;
13034                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13035                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13036                                }
13037                            }
13038                        }
13039                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13040                        mNumNonHiddenProcs++;
13041                    }
13042                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13043                        numEmpty++;
13044                        if (numEmpty > emptyProcessLimit) {
13045                            Slog.i(TAG, "No longer want " + app.processName
13046                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13047                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13048                                    app.processName, app.setAdj, "too many background");
13049                            app.killedBackground = true;
13050                            Process.killProcessQuiet(app.pid);
13051                        }
13052                    }
13053                }
13054                if (app.isolated && app.services.size() <= 0) {
13055                    // If this is an isolated process, and there are no
13056                    // services running in it, then the process is no longer
13057                    // needed.  We agressively kill these because we can by
13058                    // definition not re-use the same process again, and it is
13059                    // good to avoid having whatever code was running in them
13060                    // left sitting around after no longer needed.
13061                    Slog.i(TAG, "Isolated process " + app.processName
13062                            + " (pid " + app.pid + ") no longer needed");
13063                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13064                            app.processName, app.setAdj, "isolated not needed");
13065                    app.killedBackground = true;
13066                    Process.killProcessQuiet(app.pid);
13067                }
13068                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13069                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13070                        && !app.killedBackground) {
13071                    numTrimming++;
13072                }
13073            }
13074        }
13075
13076        mNumServiceProcs = mNewNumServiceProcs;
13077
13078        // Now determine the memory trimming level of background processes.
13079        // Unfortunately we need to start at the back of the list to do this
13080        // properly.  We only do this if the number of background apps we
13081        // are managing to keep around is less than half the maximum we desire;
13082        // if we are keeping a good number around, we'll let them use whatever
13083        // memory they want.
13084        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13085                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13086            final int numHiddenAndEmpty = numHidden + numEmpty;
13087            final int N = mLruProcesses.size();
13088            int factor = numTrimming/3;
13089            int minFactor = 2;
13090            if (mHomeProcess != null) minFactor++;
13091            if (mPreviousProcess != null) minFactor++;
13092            if (factor < minFactor) factor = minFactor;
13093            int step = 0;
13094            int fgTrimLevel;
13095            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13096                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13097            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13098                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13099            } else {
13100                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13101            }
13102            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13103            for (i=0; i<N; i++) {
13104                ProcessRecord app = mLruProcesses.get(i);
13105                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13106                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13107                        && !app.killedBackground) {
13108                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13109                        try {
13110                            app.thread.scheduleTrimMemory(curLevel);
13111                        } catch (RemoteException e) {
13112                        }
13113                        if (false) {
13114                            // For now we won't do this; our memory trimming seems
13115                            // to be good enough at this point that destroying
13116                            // activities causes more harm than good.
13117                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13118                                    && app != mHomeProcess && app != mPreviousProcess) {
13119                                // Need to do this on its own message because the stack may not
13120                                // be in a consistent state at this point.
13121                                // For these apps we will also finish their activities
13122                                // to help them free memory.
13123                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13124                            }
13125                        }
13126                    }
13127                    app.trimMemoryLevel = curLevel;
13128                    step++;
13129                    if (step >= factor) {
13130                        step = 0;
13131                        switch (curLevel) {
13132                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13133                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13134                                break;
13135                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13136                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13137                                break;
13138                        }
13139                    }
13140                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13141                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13142                            && app.thread != null) {
13143                        try {
13144                            app.thread.scheduleTrimMemory(
13145                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13146                        } catch (RemoteException e) {
13147                        }
13148                    }
13149                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13150                } else {
13151                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13152                            && app.pendingUiClean) {
13153                        // If this application is now in the background and it
13154                        // had done UI, then give it the special trim level to
13155                        // have it free UI resources.
13156                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13157                        if (app.trimMemoryLevel < level && app.thread != null) {
13158                            try {
13159                                app.thread.scheduleTrimMemory(level);
13160                            } catch (RemoteException e) {
13161                            }
13162                        }
13163                        app.pendingUiClean = false;
13164                    }
13165                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13166                        try {
13167                            app.thread.scheduleTrimMemory(fgTrimLevel);
13168                        } catch (RemoteException e) {
13169                        }
13170                    }
13171                    app.trimMemoryLevel = fgTrimLevel;
13172                }
13173            }
13174        } else {
13175            final int N = mLruProcesses.size();
13176            for (i=0; i<N; i++) {
13177                ProcessRecord app = mLruProcesses.get(i);
13178                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13179                        && app.pendingUiClean) {
13180                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13181                            && app.thread != null) {
13182                        try {
13183                            app.thread.scheduleTrimMemory(
13184                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13185                        } catch (RemoteException e) {
13186                        }
13187                    }
13188                    app.pendingUiClean = false;
13189                }
13190                app.trimMemoryLevel = 0;
13191            }
13192        }
13193
13194        if (mAlwaysFinishActivities) {
13195            // Need to do this on its own message because the stack may not
13196            // be in a consistent state at this point.
13197            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13198        }
13199    }
13200
13201    final void trimApplications() {
13202        synchronized (this) {
13203            int i;
13204
13205            // First remove any unused application processes whose package
13206            // has been removed.
13207            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13208                final ProcessRecord app = mRemovedProcesses.get(i);
13209                if (app.activities.size() == 0
13210                        && app.curReceiver == null && app.services.size() == 0) {
13211                    Slog.i(
13212                        TAG, "Exiting empty application process "
13213                        + app.processName + " ("
13214                        + (app.thread != null ? app.thread.asBinder() : null)
13215                        + ")\n");
13216                    if (app.pid > 0 && app.pid != MY_PID) {
13217                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13218                                app.processName, app.setAdj, "empty");
13219                        Process.killProcessQuiet(app.pid);
13220                    } else {
13221                        try {
13222                            app.thread.scheduleExit();
13223                        } catch (Exception e) {
13224                            // Ignore exceptions.
13225                        }
13226                    }
13227                    cleanUpApplicationRecordLocked(app, false, true, -1);
13228                    mRemovedProcesses.remove(i);
13229
13230                    if (app.persistent) {
13231                        if (app.persistent) {
13232                            addAppLocked(app.info, false);
13233                        }
13234                    }
13235                }
13236            }
13237
13238            // Now update the oom adj for all processes.
13239            updateOomAdjLocked();
13240        }
13241    }
13242
13243    /** This method sends the specified signal to each of the persistent apps */
13244    public void signalPersistentProcesses(int sig) throws RemoteException {
13245        if (sig != Process.SIGNAL_USR1) {
13246            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13247        }
13248
13249        synchronized (this) {
13250            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13251                    != PackageManager.PERMISSION_GRANTED) {
13252                throw new SecurityException("Requires permission "
13253                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13254            }
13255
13256            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13257                ProcessRecord r = mLruProcesses.get(i);
13258                if (r.thread != null && r.persistent) {
13259                    Process.sendSignal(r.pid, sig);
13260                }
13261            }
13262        }
13263    }
13264
13265    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13266        if (proc == null || proc == mProfileProc) {
13267            proc = mProfileProc;
13268            path = mProfileFile;
13269            profileType = mProfileType;
13270            clearProfilerLocked();
13271        }
13272        if (proc == null) {
13273            return;
13274        }
13275        try {
13276            proc.thread.profilerControl(false, path, null, profileType);
13277        } catch (RemoteException e) {
13278            throw new IllegalStateException("Process disappeared");
13279        }
13280    }
13281
13282    private void clearProfilerLocked() {
13283        if (mProfileFd != null) {
13284            try {
13285                mProfileFd.close();
13286            } catch (IOException e) {
13287            }
13288        }
13289        mProfileApp = null;
13290        mProfileProc = null;
13291        mProfileFile = null;
13292        mProfileType = 0;
13293        mAutoStopProfiler = false;
13294    }
13295
13296    public boolean profileControl(String process, boolean start,
13297            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13298
13299        try {
13300            synchronized (this) {
13301                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13302                // its own permission.
13303                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13304                        != PackageManager.PERMISSION_GRANTED) {
13305                    throw new SecurityException("Requires permission "
13306                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13307                }
13308
13309                if (start && fd == null) {
13310                    throw new IllegalArgumentException("null fd");
13311                }
13312
13313                ProcessRecord proc = null;
13314                if (process != null) {
13315                    try {
13316                        int pid = Integer.parseInt(process);
13317                        synchronized (mPidsSelfLocked) {
13318                            proc = mPidsSelfLocked.get(pid);
13319                        }
13320                    } catch (NumberFormatException e) {
13321                    }
13322
13323                    if (proc == null) {
13324                        HashMap<String, SparseArray<ProcessRecord>> all
13325                                = mProcessNames.getMap();
13326                        SparseArray<ProcessRecord> procs = all.get(process);
13327                        if (procs != null && procs.size() > 0) {
13328                            proc = procs.valueAt(0);
13329                        }
13330                    }
13331                }
13332
13333                if (start && (proc == null || proc.thread == null)) {
13334                    throw new IllegalArgumentException("Unknown process: " + process);
13335                }
13336
13337                if (start) {
13338                    stopProfilerLocked(null, null, 0);
13339                    setProfileApp(proc.info, proc.processName, path, fd, false);
13340                    mProfileProc = proc;
13341                    mProfileType = profileType;
13342                    try {
13343                        fd = fd.dup();
13344                    } catch (IOException e) {
13345                        fd = null;
13346                    }
13347                    proc.thread.profilerControl(start, path, fd, profileType);
13348                    fd = null;
13349                    mProfileFd = null;
13350                } else {
13351                    stopProfilerLocked(proc, path, profileType);
13352                    if (fd != null) {
13353                        try {
13354                            fd.close();
13355                        } catch (IOException e) {
13356                        }
13357                    }
13358                }
13359
13360                return true;
13361            }
13362        } catch (RemoteException e) {
13363            throw new IllegalStateException("Process disappeared");
13364        } finally {
13365            if (fd != null) {
13366                try {
13367                    fd.close();
13368                } catch (IOException e) {
13369                }
13370            }
13371        }
13372    }
13373
13374    public boolean dumpHeap(String process, boolean managed,
13375            String path, ParcelFileDescriptor fd) throws RemoteException {
13376
13377        try {
13378            synchronized (this) {
13379                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13380                // its own permission (same as profileControl).
13381                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13382                        != PackageManager.PERMISSION_GRANTED) {
13383                    throw new SecurityException("Requires permission "
13384                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13385                }
13386
13387                if (fd == null) {
13388                    throw new IllegalArgumentException("null fd");
13389                }
13390
13391                ProcessRecord proc = null;
13392                try {
13393                    int pid = Integer.parseInt(process);
13394                    synchronized (mPidsSelfLocked) {
13395                        proc = mPidsSelfLocked.get(pid);
13396                    }
13397                } catch (NumberFormatException e) {
13398                }
13399
13400                if (proc == null) {
13401                    HashMap<String, SparseArray<ProcessRecord>> all
13402                            = mProcessNames.getMap();
13403                    SparseArray<ProcessRecord> procs = all.get(process);
13404                    if (procs != null && procs.size() > 0) {
13405                        proc = procs.valueAt(0);
13406                    }
13407                }
13408
13409                if (proc == null || proc.thread == null) {
13410                    throw new IllegalArgumentException("Unknown process: " + process);
13411                }
13412
13413                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13414                if (!isDebuggable) {
13415                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13416                        throw new SecurityException("Process not debuggable: " + proc);
13417                    }
13418                }
13419
13420                proc.thread.dumpHeap(managed, path, fd);
13421                fd = null;
13422                return true;
13423            }
13424        } catch (RemoteException e) {
13425            throw new IllegalStateException("Process disappeared");
13426        } finally {
13427            if (fd != null) {
13428                try {
13429                    fd.close();
13430                } catch (IOException e) {
13431                }
13432            }
13433        }
13434    }
13435
13436    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13437    public void monitor() {
13438        synchronized (this) { }
13439    }
13440
13441    void onCoreSettingsChange(Bundle settings) {
13442        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13443            ProcessRecord processRecord = mLruProcesses.get(i);
13444            try {
13445                if (processRecord.thread != null) {
13446                    processRecord.thread.setCoreSettings(settings);
13447                }
13448            } catch (RemoteException re) {
13449                /* ignore */
13450            }
13451        }
13452    }
13453
13454    // Multi-user methods
13455
13456    public boolean switchUser(int userId) {
13457        final int callingUid = Binder.getCallingUid();
13458        if (callingUid != 0 && callingUid != Process.myUid()) {
13459            Slog.e(TAG, "Trying to switch user from unauthorized app");
13460            return false;
13461        }
13462        if (mCurrentUserId == userId)
13463            return true;
13464
13465        synchronized (this) {
13466            // Check if user is already logged in, otherwise check if user exists first before
13467            // adding to the list of logged in users.
13468            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13469                if (!userExists(userId)) {
13470                    return false;
13471                }
13472                mLoggedInUsers.append(userId, userId);
13473            }
13474
13475            mCurrentUserId = userId;
13476            boolean haveActivities = mMainStack.switchUser(userId);
13477            if (!haveActivities) {
13478                startHomeActivityLocked(userId);
13479            }
13480
13481        }
13482
13483        // Inform of user switch
13484        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13485        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
13486        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
13487
13488        return true;
13489    }
13490
13491    @Override
13492    public UserInfo getCurrentUser() throws RemoteException {
13493        final int callingUid = Binder.getCallingUid();
13494        if (callingUid != 0 && callingUid != Process.myUid()) {
13495            Slog.e(TAG, "Trying to get user from unauthorized app");
13496            return null;
13497        }
13498        return getUserManager().getUserInfo(mCurrentUserId);
13499    }
13500
13501    private void onUserRemoved(Intent intent) {
13502        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
13503        if (extraUserId < 1) return;
13504
13505        // Kill all the processes for the user
13506        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13507        synchronized (this) {
13508            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13509            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13510                SparseArray<ProcessRecord> uids = uidMap.getValue();
13511                for (int i = 0; i < uids.size(); i++) {
13512                    if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
13513                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13514                    }
13515                }
13516            }
13517
13518            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13519                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13520                        false, false, true, true, extraUserId);
13521            }
13522        }
13523    }
13524
13525    private boolean userExists(int userId) {
13526        UserInfo user = getUserManager().getUserInfo(userId);
13527        return user != null;
13528    }
13529
13530    UserManager getUserManager() {
13531        if (mUserManager == null) {
13532            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13533        }
13534        return mUserManager;
13535    }
13536
13537    private void checkValidCaller(int uid, int userId) {
13538        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13539
13540        throw new SecurityException("Caller uid=" + uid
13541                + " is not privileged to communicate with user=" + userId);
13542    }
13543
13544    private int applyUserId(int uid, int userId) {
13545        return UserHandle.getUid(userId, uid);
13546    }
13547
13548    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13549        if (info == null) return null;
13550        ApplicationInfo newInfo = new ApplicationInfo(info);
13551        newInfo.uid = applyUserId(info.uid, userId);
13552        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13553                + info.packageName;
13554        return newInfo;
13555    }
13556
13557    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13558        if (aInfo == null
13559                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13560            return aInfo;
13561        }
13562
13563        ActivityInfo info = new ActivityInfo(aInfo);
13564        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13565        return info;
13566    }
13567}
13568