ActivityManagerService.java revision 258848d2ae04f447ff1c18023fa76b139fcc0862
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.pm.UserManagerService;
31import com.android.server.wm.WindowManagerService;
32
33import dalvik.system.Zygote;
34
35import android.app.Activity;
36import android.app.ActivityManager;
37import android.app.ActivityManagerNative;
38import android.app.ActivityOptions;
39import android.app.ActivityThread;
40import android.app.AlertDialog;
41import android.app.AppGlobals;
42import android.app.ApplicationErrorReport;
43import android.app.Dialog;
44import android.app.IActivityController;
45import android.app.IApplicationThread;
46import android.app.IInstrumentationWatcher;
47import android.app.INotificationManager;
48import android.app.IProcessObserver;
49import android.app.IServiceConnection;
50import android.app.IThumbnailReceiver;
51import android.app.Instrumentation;
52import android.app.Notification;
53import android.app.NotificationManager;
54import android.app.PendingIntent;
55import android.app.Service;
56import android.app.backup.IBackupManager;
57import android.content.ActivityNotFoundException;
58import android.content.BroadcastReceiver;
59import android.content.ClipData;
60import android.content.ComponentCallbacks2;
61import android.content.ComponentName;
62import android.content.ContentProvider;
63import android.content.ContentResolver;
64import android.content.Context;
65import android.content.DialogInterface;
66import android.content.IContentProvider;
67import android.content.IIntentReceiver;
68import android.content.IIntentSender;
69import android.content.Intent;
70import android.content.IntentFilter;
71import android.content.IntentSender;
72import android.content.pm.ActivityInfo;
73import android.content.pm.ApplicationInfo;
74import android.content.pm.ConfigurationInfo;
75import android.content.pm.IPackageDataObserver;
76import android.content.pm.IPackageManager;
77import android.content.pm.InstrumentationInfo;
78import android.content.pm.PackageInfo;
79import android.content.pm.PackageManager;
80import android.content.pm.UserInfo;
81import android.content.pm.PackageManager.NameNotFoundException;
82import android.content.pm.PathPermission;
83import android.content.pm.ProviderInfo;
84import android.content.pm.ResolveInfo;
85import android.content.pm.ServiceInfo;
86import android.content.res.CompatibilityInfo;
87import android.content.res.Configuration;
88import android.graphics.Bitmap;
89import android.net.Proxy;
90import android.net.ProxyProperties;
91import android.net.Uri;
92import android.os.Binder;
93import android.os.Build;
94import android.os.Bundle;
95import android.os.Debug;
96import android.os.DropBoxManager;
97import android.os.Environment;
98import android.os.FileObserver;
99import android.os.FileUtils;
100import android.os.Handler;
101import android.os.IBinder;
102import android.os.IPermissionController;
103import android.os.Looper;
104import android.os.Message;
105import android.os.Parcel;
106import android.os.ParcelFileDescriptor;
107import android.os.Process;
108import android.os.RemoteCallbackList;
109import android.os.RemoteException;
110import android.os.ServiceManager;
111import android.os.StrictMode;
112import android.os.SystemClock;
113import android.os.SystemProperties;
114import android.os.UserId;
115import android.os.UserManager;
116import android.provider.Settings;
117import android.text.format.Time;
118import android.util.EventLog;
119import android.util.Log;
120import android.util.Pair;
121import android.util.PrintWriterPrinter;
122import android.util.Slog;
123import android.util.SparseArray;
124import android.util.SparseIntArray;
125import android.util.TimeUtils;
126import android.view.Gravity;
127import android.view.LayoutInflater;
128import android.view.View;
129import android.view.WindowManager;
130import android.view.WindowManagerPolicy;
131
132import java.io.BufferedInputStream;
133import java.io.BufferedOutputStream;
134import java.io.BufferedReader;
135import java.io.DataInputStream;
136import java.io.DataOutputStream;
137import java.io.File;
138import java.io.FileDescriptor;
139import java.io.FileInputStream;
140import java.io.FileNotFoundException;
141import java.io.FileOutputStream;
142import java.io.IOException;
143import java.io.InputStreamReader;
144import java.io.PrintWriter;
145import java.io.StringWriter;
146import java.lang.ref.WeakReference;
147import java.util.ArrayList;
148import java.util.Collection;
149import java.util.Collections;
150import java.util.Comparator;
151import java.util.HashMap;
152import java.util.HashSet;
153import java.util.Iterator;
154import java.util.List;
155import java.util.Locale;
156import java.util.Map;
157import java.util.Map.Entry;
158import java.util.Set;
159import java.util.concurrent.atomic.AtomicBoolean;
160import java.util.concurrent.atomic.AtomicLong;
161
162public final class ActivityManagerService extends ActivityManagerNative
163        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
164    private static final String USER_DATA_DIR = "/data/user/";
165    static final String TAG = "ActivityManager";
166    static final String TAG_MU = "ActivityManagerServiceMU";
167    static final boolean DEBUG = false;
168    static final boolean localLOGV = DEBUG;
169    static final boolean DEBUG_SWITCH = localLOGV || false;
170    static final boolean DEBUG_TASKS = localLOGV || false;
171    static final boolean DEBUG_PAUSE = localLOGV || false;
172    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
173    static final boolean DEBUG_TRANSITION = localLOGV || false;
174    static final boolean DEBUG_BROADCAST = localLOGV || false;
175    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
176    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
177    static final boolean DEBUG_SERVICE = localLOGV || false;
178    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
179    static final boolean DEBUG_VISBILITY = localLOGV || false;
180    static final boolean DEBUG_PROCESSES = localLOGV || false;
181    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
182    static final boolean DEBUG_PROVIDER = localLOGV || false;
183    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
184    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
185    static final boolean DEBUG_RESULTS = localLOGV || false;
186    static final boolean DEBUG_BACKUP = localLOGV || false;
187    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
188    static final boolean DEBUG_POWER = localLOGV || false;
189    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
190    static final boolean DEBUG_MU = localLOGV || false;
191    static final boolean VALIDATE_TOKENS = false;
192    static final boolean SHOW_ACTIVITY_START_TIME = true;
193
194    // Control over CPU and battery monitoring.
195    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
196    static final boolean MONITOR_CPU_USAGE = true;
197    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
198    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
199    static final boolean MONITOR_THREAD_CPU_USAGE = false;
200
201    // The flags that are set for all calls we make to the package manager.
202    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
203
204    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
205
206    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
207
208    // Maximum number of recent tasks that we can remember.
209    static final int MAX_RECENT_TASKS = 20;
210
211    // Amount of time after a call to stopAppSwitches() during which we will
212    // prevent further untrusted switches from happening.
213    static final long APP_SWITCH_DELAY_TIME = 5*1000;
214
215    // How long we wait for a launched process to attach to the activity manager
216    // before we decide it's never going to come up for real.
217    static final int PROC_START_TIMEOUT = 10*1000;
218
219    // How long we wait for a launched process to attach to the activity manager
220    // before we decide it's never going to come up for real, when the process was
221    // started with a wrapper for instrumentation (such as Valgrind) because it
222    // could take much longer than usual.
223    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
224
225    // How long to wait after going idle before forcing apps to GC.
226    static final int GC_TIMEOUT = 5*1000;
227
228    // The minimum amount of time between successive GC requests for a process.
229    static final int GC_MIN_INTERVAL = 60*1000;
230
231    // The rate at which we check for apps using excessive power -- 15 mins.
232    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
233
234    // The minimum sample duration we will allow before deciding we have
235    // enough data on wake locks to start killing things.
236    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
237
238    // The minimum sample duration we will allow before deciding we have
239    // enough data on CPU usage to start killing things.
240    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
241
242    // How long we allow a receiver to run before giving up on it.
243    static final int BROADCAST_FG_TIMEOUT = 10*1000;
244    static final int BROADCAST_BG_TIMEOUT = 60*1000;
245
246    // How long we wait until we timeout on key dispatching.
247    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
248
249    // How long we wait until we timeout on key dispatching during instrumentation.
250    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
251
252    static final int MY_PID = Process.myPid();
253
254    static final String[] EMPTY_STRING_ARRAY = new String[0];
255
256    public ActivityStack mMainStack;
257
258    private final boolean mHeadless;
259
260    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
261    // default actuion automatically.  Important for devices without direct input
262    // devices.
263    private boolean mShowDialogs = true;
264
265    /**
266     * Description of a request to start a new activity, which has been held
267     * due to app switches being disabled.
268     */
269    static class PendingActivityLaunch {
270        ActivityRecord r;
271        ActivityRecord sourceRecord;
272        int startFlags;
273    }
274
275    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
276            = new ArrayList<PendingActivityLaunch>();
277
278
279    BroadcastQueue mFgBroadcastQueue;
280    BroadcastQueue mBgBroadcastQueue;
281    // Convenient for easy iteration over the queues. Foreground is first
282    // so that dispatch of foreground broadcasts gets precedence.
283    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
284
285    BroadcastQueue broadcastQueueForIntent(Intent intent) {
286        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
287        if (DEBUG_BACKGROUND_BROADCAST) {
288            Slog.i(TAG, "Broadcast intent " + intent + " on "
289                    + (isFg ? "foreground" : "background")
290                    + " queue");
291        }
292        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
293    }
294
295    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
296        for (BroadcastQueue queue : mBroadcastQueues) {
297            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
298            if (r != null) {
299                return r;
300            }
301        }
302        return null;
303    }
304
305    /**
306     * Activity we have told the window manager to have key focus.
307     */
308    ActivityRecord mFocusedActivity = null;
309    /**
310     * List of intents that were used to start the most recent tasks.
311     */
312    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
313
314    /**
315     * Process management.
316     */
317    final ProcessList mProcessList = new ProcessList();
318
319    /**
320     * All of the applications we currently have running organized by name.
321     * The keys are strings of the application package name (as
322     * returned by the package manager), and the keys are ApplicationRecord
323     * objects.
324     */
325    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
326
327    /**
328     * The currently running isolated processes.
329     */
330    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
331
332    /**
333     * Counter for assigning isolated process uids, to avoid frequently reusing the
334     * same ones.
335     */
336    int mNextIsolatedProcessUid = 0;
337
338    /**
339     * The currently running heavy-weight process, if any.
340     */
341    ProcessRecord mHeavyWeightProcess = null;
342
343    /**
344     * The last time that various processes have crashed.
345     */
346    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
347
348    /**
349     * Set of applications that we consider to be bad, and will reject
350     * incoming broadcasts from (which the user has no control over).
351     * Processes are added to this set when they have crashed twice within
352     * a minimum amount of time; they are removed from it when they are
353     * later restarted (hopefully due to some user action).  The value is the
354     * time it was added to the list.
355     */
356    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
357
358    /**
359     * All of the processes we currently have running organized by pid.
360     * The keys are the pid running the application.
361     *
362     * <p>NOTE: This object is protected by its own lock, NOT the global
363     * activity manager lock!
364     */
365    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
366
367    /**
368     * All of the processes that have been forced to be foreground.  The key
369     * is the pid of the caller who requested it (we hold a death
370     * link on it).
371     */
372    abstract class ForegroundToken implements IBinder.DeathRecipient {
373        int pid;
374        IBinder token;
375    }
376    final SparseArray<ForegroundToken> mForegroundProcesses
377            = new SparseArray<ForegroundToken>();
378
379    /**
380     * List of records for processes that someone had tried to start before the
381     * system was ready.  We don't start them at that point, but ensure they
382     * are started by the time booting is complete.
383     */
384    final ArrayList<ProcessRecord> mProcessesOnHold
385            = new ArrayList<ProcessRecord>();
386
387    /**
388     * List of persistent applications that are in the process
389     * of being started.
390     */
391    final ArrayList<ProcessRecord> mPersistentStartingProcesses
392            = new ArrayList<ProcessRecord>();
393
394    /**
395     * Processes that are being forcibly torn down.
396     */
397    final ArrayList<ProcessRecord> mRemovedProcesses
398            = new ArrayList<ProcessRecord>();
399
400    /**
401     * List of running applications, sorted by recent usage.
402     * The first entry in the list is the least recently used.
403     * It contains ApplicationRecord objects.  This list does NOT include
404     * any persistent application records (since we never want to exit them).
405     */
406    final ArrayList<ProcessRecord> mLruProcesses
407            = new ArrayList<ProcessRecord>();
408
409    /**
410     * List of processes that should gc as soon as things are idle.
411     */
412    final ArrayList<ProcessRecord> mProcessesToGc
413            = new ArrayList<ProcessRecord>();
414
415    /**
416     * This is the process holding what we currently consider to be
417     * the "home" activity.
418     */
419    ProcessRecord mHomeProcess;
420
421    /**
422     * This is the process holding the activity the user last visited that
423     * is in a different process from the one they are currently in.
424     */
425    ProcessRecord mPreviousProcess;
426
427    /**
428     * The time at which the previous process was last visible.
429     */
430    long mPreviousProcessVisibleTime;
431
432    /**
433     * Packages that the user has asked to have run in screen size
434     * compatibility mode instead of filling the screen.
435     */
436    final CompatModePackages mCompatModePackages;
437
438    /**
439     * Set of PendingResultRecord objects that are currently active.
440     */
441    final HashSet mPendingResultRecords = new HashSet();
442
443    /**
444     * Set of IntentSenderRecord objects that are currently active.
445     */
446    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
447            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
448
449    /**
450     * Fingerprints (hashCode()) of stack traces that we've
451     * already logged DropBox entries for.  Guarded by itself.  If
452     * something (rogue user app) forces this over
453     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
454     */
455    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
456    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
457
458    /**
459     * Strict Mode background batched logging state.
460     *
461     * The string buffer is guarded by itself, and its lock is also
462     * used to determine if another batched write is already
463     * in-flight.
464     */
465    private final StringBuilder mStrictModeBuffer = new StringBuilder();
466
467    /**
468     * Keeps track of all IIntentReceivers that have been registered for
469     * broadcasts.  Hash keys are the receiver IBinder, hash value is
470     * a ReceiverList.
471     */
472    final HashMap mRegisteredReceivers = new HashMap();
473
474    /**
475     * Resolver for broadcast intents to registered receivers.
476     * Holds BroadcastFilter (subclass of IntentFilter).
477     */
478    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
479            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
480        @Override
481        protected boolean allowFilterResult(
482                BroadcastFilter filter, List<BroadcastFilter> dest) {
483            IBinder target = filter.receiverList.receiver.asBinder();
484            for (int i=dest.size()-1; i>=0; i--) {
485                if (dest.get(i).receiverList.receiver.asBinder() == target) {
486                    return false;
487                }
488            }
489            return true;
490        }
491
492        @Override
493        protected BroadcastFilter[] newArray(int size) {
494            return new BroadcastFilter[size];
495        }
496
497        @Override
498        protected String packageForFilter(BroadcastFilter filter) {
499            return filter.packageName;
500        }
501    };
502
503    /**
504     * State of all active sticky broadcasts.  Keys are the action of the
505     * sticky Intent, values are an ArrayList of all broadcasted intents with
506     * that action (which should usually be one).
507     */
508    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
509            new HashMap<String, ArrayList<Intent>>();
510
511    final ActiveServices mServices;
512
513    /**
514     * Backup/restore process management
515     */
516    String mBackupAppName = null;
517    BackupRecord mBackupTarget = null;
518
519    /**
520     * List of PendingThumbnailsRecord objects of clients who are still
521     * waiting to receive all of the thumbnails for a task.
522     */
523    final ArrayList mPendingThumbnails = new ArrayList();
524
525    /**
526     * List of HistoryRecord objects that have been finished and must
527     * still report back to a pending thumbnail receiver.
528     */
529    final ArrayList mCancelledThumbnails = new ArrayList();
530
531    final ProviderMap mProviderMap = new ProviderMap();
532
533    /**
534     * List of content providers who have clients waiting for them.  The
535     * application is currently being launched and the provider will be
536     * removed from this list once it is published.
537     */
538    final ArrayList<ContentProviderRecord> mLaunchingProviders
539            = new ArrayList<ContentProviderRecord>();
540
541    /**
542     * Global set of specific Uri permissions that have been granted.
543     */
544    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
545            = new SparseArray<HashMap<Uri, UriPermission>>();
546
547    CoreSettingsObserver mCoreSettingsObserver;
548
549    /**
550     * Thread-local storage used to carry caller permissions over through
551     * indirect content-provider access.
552     * @see #ActivityManagerService.openContentUri()
553     */
554    private class Identity {
555        public int pid;
556        public int uid;
557
558        Identity(int _pid, int _uid) {
559            pid = _pid;
560            uid = _uid;
561        }
562    }
563
564    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
565
566    /**
567     * All information we have collected about the runtime performance of
568     * any user id that can impact battery performance.
569     */
570    final BatteryStatsService mBatteryStatsService;
571
572    /**
573     * information about component usage
574     */
575    final UsageStatsService mUsageStatsService;
576
577    /**
578     * Current configuration information.  HistoryRecord objects are given
579     * a reference to this object to indicate which configuration they are
580     * currently running in, so this object must be kept immutable.
581     */
582    Configuration mConfiguration = new Configuration();
583
584    /**
585     * Current sequencing integer of the configuration, for skipping old
586     * configurations.
587     */
588    int mConfigurationSeq = 0;
589
590    /**
591     * Hardware-reported OpenGLES version.
592     */
593    final int GL_ES_VERSION;
594
595    /**
596     * List of initialization arguments to pass to all processes when binding applications to them.
597     * For example, references to the commonly used services.
598     */
599    HashMap<String, IBinder> mAppBindArgs;
600
601    /**
602     * Temporary to avoid allocations.  Protected by main lock.
603     */
604    final StringBuilder mStringBuilder = new StringBuilder(256);
605
606    /**
607     * Used to control how we initialize the service.
608     */
609    boolean mStartRunning = false;
610    ComponentName mTopComponent;
611    String mTopAction;
612    String mTopData;
613    boolean mProcessesReady = false;
614    boolean mSystemReady = false;
615    boolean mBooting = false;
616    boolean mWaitingUpdate = false;
617    boolean mDidUpdate = false;
618    boolean mOnBattery = false;
619    boolean mLaunchWarningShown = false;
620
621    Context mContext;
622
623    int mFactoryTest;
624
625    boolean mCheckedForSetup;
626
627    /**
628     * The time at which we will allow normal application switches again,
629     * after a call to {@link #stopAppSwitches()}.
630     */
631    long mAppSwitchesAllowedTime;
632
633    /**
634     * This is set to true after the first switch after mAppSwitchesAllowedTime
635     * is set; any switches after that will clear the time.
636     */
637    boolean mDidAppSwitch;
638
639    /**
640     * Last time (in realtime) at which we checked for power usage.
641     */
642    long mLastPowerCheckRealtime;
643
644    /**
645     * Last time (in uptime) at which we checked for power usage.
646     */
647    long mLastPowerCheckUptime;
648
649    /**
650     * Set while we are wanting to sleep, to prevent any
651     * activities from being started/resumed.
652     */
653    boolean mSleeping = false;
654
655    /**
656     * State of external calls telling us if the device is asleep.
657     */
658    boolean mWentToSleep = false;
659
660    /**
661     * State of external call telling us if the lock screen is shown.
662     */
663    boolean mLockScreenShown = false;
664
665    /**
666     * Set if we are shutting down the system, similar to sleeping.
667     */
668    boolean mShuttingDown = false;
669
670    /**
671     * Task identifier that activities are currently being started
672     * in.  Incremented each time a new task is created.
673     * todo: Replace this with a TokenSpace class that generates non-repeating
674     * integers that won't wrap.
675     */
676    int mCurTask = 1;
677
678    /**
679     * Current sequence id for oom_adj computation traversal.
680     */
681    int mAdjSeq = 0;
682
683    /**
684     * Current sequence id for process LRU updating.
685     */
686    int mLruSeq = 0;
687
688    /**
689     * Keep track of the number of service processes we last found, to
690     * determine on the next iteration which should be B services.
691     */
692    int mNumServiceProcs = 0;
693    int mNewNumServiceProcs = 0;
694
695    /**
696     * System monitoring: number of processes that died since the last
697     * N procs were started.
698     */
699    int[] mProcDeaths = new int[20];
700
701    /**
702     * This is set if we had to do a delayed dexopt of an app before launching
703     * it, to increasing the ANR timeouts in that case.
704     */
705    boolean mDidDexOpt;
706
707    String mDebugApp = null;
708    boolean mWaitForDebugger = false;
709    boolean mDebugTransient = false;
710    String mOrigDebugApp = null;
711    boolean mOrigWaitForDebugger = false;
712    boolean mAlwaysFinishActivities = false;
713    IActivityController mController = null;
714    String mProfileApp = null;
715    ProcessRecord mProfileProc = null;
716    String mProfileFile;
717    ParcelFileDescriptor mProfileFd;
718    int mProfileType = 0;
719    boolean mAutoStopProfiler = false;
720    String mOpenGlTraceApp = null;
721
722    static class ProcessChangeItem {
723        static final int CHANGE_ACTIVITIES = 1<<0;
724        static final int CHANGE_IMPORTANCE= 1<<1;
725        int changes;
726        int uid;
727        int pid;
728        int importance;
729        boolean foregroundActivities;
730    }
731
732    final RemoteCallbackList<IProcessObserver> mProcessObservers
733            = new RemoteCallbackList<IProcessObserver>();
734    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
735
736    final ArrayList<ProcessChangeItem> mPendingProcessChanges
737            = new ArrayList<ProcessChangeItem>();
738    final ArrayList<ProcessChangeItem> mAvailProcessChanges
739            = new ArrayList<ProcessChangeItem>();
740
741    /**
742     * Callback of last caller to {@link #requestPss}.
743     */
744    Runnable mRequestPssCallback;
745
746    /**
747     * Remaining processes for which we are waiting results from the last
748     * call to {@link #requestPss}.
749     */
750    final ArrayList<ProcessRecord> mRequestPssList
751            = new ArrayList<ProcessRecord>();
752
753    /**
754     * Runtime statistics collection thread.  This object's lock is used to
755     * protect all related state.
756     */
757    final Thread mProcessStatsThread;
758
759    /**
760     * Used to collect process stats when showing not responding dialog.
761     * Protected by mProcessStatsThread.
762     */
763    final ProcessStats mProcessStats = new ProcessStats(
764            MONITOR_THREAD_CPU_USAGE);
765    final AtomicLong mLastCpuTime = new AtomicLong(0);
766    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
767
768    long mLastWriteTime = 0;
769
770    /**
771     * Set to true after the system has finished booting.
772     */
773    boolean mBooted = false;
774
775    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
776    int mProcessLimitOverride = -1;
777
778    WindowManagerService mWindowManager;
779
780    static ActivityManagerService mSelf;
781    static ActivityThread mSystemThread;
782
783    private int mCurrentUserId;
784    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
785    private UserManager mUserManager;
786
787    private final class AppDeathRecipient implements IBinder.DeathRecipient {
788        final ProcessRecord mApp;
789        final int mPid;
790        final IApplicationThread mAppThread;
791
792        AppDeathRecipient(ProcessRecord app, int pid,
793                IApplicationThread thread) {
794            if (localLOGV) Slog.v(
795                TAG, "New death recipient " + this
796                + " for thread " + thread.asBinder());
797            mApp = app;
798            mPid = pid;
799            mAppThread = thread;
800        }
801
802        public void binderDied() {
803            if (localLOGV) Slog.v(
804                TAG, "Death received in " + this
805                + " for thread " + mAppThread.asBinder());
806            synchronized(ActivityManagerService.this) {
807                appDiedLocked(mApp, mPid, mAppThread);
808            }
809        }
810    }
811
812    static final int SHOW_ERROR_MSG = 1;
813    static final int SHOW_NOT_RESPONDING_MSG = 2;
814    static final int SHOW_FACTORY_ERROR_MSG = 3;
815    static final int UPDATE_CONFIGURATION_MSG = 4;
816    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
817    static final int WAIT_FOR_DEBUGGER_MSG = 6;
818    static final int SERVICE_TIMEOUT_MSG = 12;
819    static final int UPDATE_TIME_ZONE = 13;
820    static final int SHOW_UID_ERROR_MSG = 14;
821    static final int IM_FEELING_LUCKY_MSG = 15;
822    static final int PROC_START_TIMEOUT_MSG = 20;
823    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
824    static final int KILL_APPLICATION_MSG = 22;
825    static final int FINALIZE_PENDING_INTENT_MSG = 23;
826    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
827    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
828    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
829    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
830    static final int CLEAR_DNS_CACHE = 28;
831    static final int UPDATE_HTTP_PROXY = 29;
832    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
833    static final int DISPATCH_PROCESSES_CHANGED = 31;
834    static final int DISPATCH_PROCESS_DIED = 32;
835    static final int REPORT_MEM_USAGE = 33;
836
837    static final int FIRST_ACTIVITY_STACK_MSG = 100;
838    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
839    static final int FIRST_COMPAT_MODE_MSG = 300;
840
841    AlertDialog mUidAlert;
842    CompatModeDialog mCompatModeDialog;
843    long mLastMemUsageReportTime = 0;
844
845    final Handler mHandler = new Handler() {
846        //public Handler() {
847        //    if (localLOGV) Slog.v(TAG, "Handler started!");
848        //}
849
850        public void handleMessage(Message msg) {
851            switch (msg.what) {
852            case SHOW_ERROR_MSG: {
853                HashMap data = (HashMap) msg.obj;
854                synchronized (ActivityManagerService.this) {
855                    ProcessRecord proc = (ProcessRecord)data.get("app");
856                    if (proc != null && proc.crashDialog != null) {
857                        Slog.e(TAG, "App already has crash dialog: " + proc);
858                        return;
859                    }
860                    AppErrorResult res = (AppErrorResult) data.get("result");
861                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
862                        Dialog d = new AppErrorDialog(mContext, res, proc);
863                        d.show();
864                        proc.crashDialog = d;
865                    } else {
866                        // The device is asleep, so just pretend that the user
867                        // saw a crash dialog and hit "force quit".
868                        res.set(0);
869                    }
870                }
871
872                ensureBootCompleted();
873            } break;
874            case SHOW_NOT_RESPONDING_MSG: {
875                synchronized (ActivityManagerService.this) {
876                    HashMap data = (HashMap) msg.obj;
877                    ProcessRecord proc = (ProcessRecord)data.get("app");
878                    if (proc != null && proc.anrDialog != null) {
879                        Slog.e(TAG, "App already has anr dialog: " + proc);
880                        return;
881                    }
882
883                    Intent intent = new Intent("android.intent.action.ANR");
884                    if (!mProcessesReady) {
885                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
886                                | Intent.FLAG_RECEIVER_FOREGROUND);
887                    }
888                    broadcastIntentLocked(null, null, intent,
889                            null, null, 0, null, null, null,
890                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
891
892                    if (mShowDialogs) {
893                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
894                                mContext, proc, (ActivityRecord)data.get("activity"));
895                        d.show();
896                        proc.anrDialog = d;
897                    } else {
898                        // Just kill the app if there is no dialog to be shown.
899                        killAppAtUsersRequest(proc, null);
900                    }
901                }
902
903                ensureBootCompleted();
904            } break;
905            case SHOW_STRICT_MODE_VIOLATION_MSG: {
906                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
907                synchronized (ActivityManagerService.this) {
908                    ProcessRecord proc = (ProcessRecord) data.get("app");
909                    if (proc == null) {
910                        Slog.e(TAG, "App not found when showing strict mode dialog.");
911                        break;
912                    }
913                    if (proc.crashDialog != null) {
914                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
915                        return;
916                    }
917                    AppErrorResult res = (AppErrorResult) data.get("result");
918                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
919                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
920                        d.show();
921                        proc.crashDialog = d;
922                    } else {
923                        // The device is asleep, so just pretend that the user
924                        // saw a crash dialog and hit "force quit".
925                        res.set(0);
926                    }
927                }
928                ensureBootCompleted();
929            } break;
930            case SHOW_FACTORY_ERROR_MSG: {
931                Dialog d = new FactoryErrorDialog(
932                    mContext, msg.getData().getCharSequence("msg"));
933                d.show();
934                ensureBootCompleted();
935            } break;
936            case UPDATE_CONFIGURATION_MSG: {
937                final ContentResolver resolver = mContext.getContentResolver();
938                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
939            } break;
940            case GC_BACKGROUND_PROCESSES_MSG: {
941                synchronized (ActivityManagerService.this) {
942                    performAppGcsIfAppropriateLocked();
943                }
944            } break;
945            case WAIT_FOR_DEBUGGER_MSG: {
946                synchronized (ActivityManagerService.this) {
947                    ProcessRecord app = (ProcessRecord)msg.obj;
948                    if (msg.arg1 != 0) {
949                        if (!app.waitedForDebugger) {
950                            Dialog d = new AppWaitingForDebuggerDialog(
951                                    ActivityManagerService.this,
952                                    mContext, app);
953                            app.waitDialog = d;
954                            app.waitedForDebugger = true;
955                            d.show();
956                        }
957                    } else {
958                        if (app.waitDialog != null) {
959                            app.waitDialog.dismiss();
960                            app.waitDialog = null;
961                        }
962                    }
963                }
964            } break;
965            case SERVICE_TIMEOUT_MSG: {
966                if (mDidDexOpt) {
967                    mDidDexOpt = false;
968                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
969                    nmsg.obj = msg.obj;
970                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
971                    return;
972                }
973                mServices.serviceTimeout((ProcessRecord)msg.obj);
974            } break;
975            case UPDATE_TIME_ZONE: {
976                synchronized (ActivityManagerService.this) {
977                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
978                        ProcessRecord r = mLruProcesses.get(i);
979                        if (r.thread != null) {
980                            try {
981                                r.thread.updateTimeZone();
982                            } catch (RemoteException ex) {
983                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
984                            }
985                        }
986                    }
987                }
988            } break;
989            case CLEAR_DNS_CACHE: {
990                synchronized (ActivityManagerService.this) {
991                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
992                        ProcessRecord r = mLruProcesses.get(i);
993                        if (r.thread != null) {
994                            try {
995                                r.thread.clearDnsCache();
996                            } catch (RemoteException ex) {
997                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
998                            }
999                        }
1000                    }
1001                }
1002            } break;
1003            case UPDATE_HTTP_PROXY: {
1004                ProxyProperties proxy = (ProxyProperties)msg.obj;
1005                String host = "";
1006                String port = "";
1007                String exclList = "";
1008                if (proxy != null) {
1009                    host = proxy.getHost();
1010                    port = Integer.toString(proxy.getPort());
1011                    exclList = proxy.getExclusionList();
1012                }
1013                synchronized (ActivityManagerService.this) {
1014                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1015                        ProcessRecord r = mLruProcesses.get(i);
1016                        if (r.thread != null) {
1017                            try {
1018                                r.thread.setHttpProxy(host, port, exclList);
1019                            } catch (RemoteException ex) {
1020                                Slog.w(TAG, "Failed to update http proxy for: " +
1021                                        r.info.processName);
1022                            }
1023                        }
1024                    }
1025                }
1026            } break;
1027            case SHOW_UID_ERROR_MSG: {
1028                String title = "System UIDs Inconsistent";
1029                String text = "UIDs on the system are inconsistent, you need to wipe your"
1030                        + " data partition or your device will be unstable.";
1031                Log.e(TAG, title + ": " + text);
1032                if (mShowDialogs) {
1033                    // XXX This is a temporary dialog, no need to localize.
1034                    AlertDialog d = new BaseErrorDialog(mContext);
1035                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1036                    d.setCancelable(false);
1037                    d.setTitle(title);
1038                    d.setMessage(text);
1039                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1040                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1041                    mUidAlert = d;
1042                    d.show();
1043                }
1044            } break;
1045            case IM_FEELING_LUCKY_MSG: {
1046                if (mUidAlert != null) {
1047                    mUidAlert.dismiss();
1048                    mUidAlert = null;
1049                }
1050            } break;
1051            case PROC_START_TIMEOUT_MSG: {
1052                if (mDidDexOpt) {
1053                    mDidDexOpt = false;
1054                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1055                    nmsg.obj = msg.obj;
1056                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1057                    return;
1058                }
1059                ProcessRecord app = (ProcessRecord)msg.obj;
1060                synchronized (ActivityManagerService.this) {
1061                    processStartTimedOutLocked(app);
1062                }
1063            } break;
1064            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1065                synchronized (ActivityManagerService.this) {
1066                    doPendingActivityLaunchesLocked(true);
1067                }
1068            } break;
1069            case KILL_APPLICATION_MSG: {
1070                synchronized (ActivityManagerService.this) {
1071                    int uid = msg.arg1;
1072                    boolean restart = (msg.arg2 == 1);
1073                    String pkg = (String) msg.obj;
1074                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1075                            UserId.getUserId(uid));
1076                }
1077            } break;
1078            case FINALIZE_PENDING_INTENT_MSG: {
1079                ((PendingIntentRecord)msg.obj).completeFinalize();
1080            } break;
1081            case POST_HEAVY_NOTIFICATION_MSG: {
1082                INotificationManager inm = NotificationManager.getService();
1083                if (inm == null) {
1084                    return;
1085                }
1086
1087                ActivityRecord root = (ActivityRecord)msg.obj;
1088                ProcessRecord process = root.app;
1089                if (process == null) {
1090                    return;
1091                }
1092
1093                try {
1094                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1095                    String text = mContext.getString(R.string.heavy_weight_notification,
1096                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1097                    Notification notification = new Notification();
1098                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1099                    notification.when = 0;
1100                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1101                    notification.tickerText = text;
1102                    notification.defaults = 0; // please be quiet
1103                    notification.sound = null;
1104                    notification.vibrate = null;
1105                    notification.setLatestEventInfo(context, text,
1106                            mContext.getText(R.string.heavy_weight_notification_detail),
1107                            PendingIntent.getActivity(mContext, 0, root.intent,
1108                                    PendingIntent.FLAG_CANCEL_CURRENT));
1109
1110                    try {
1111                        int[] outId = new int[1];
1112                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1113                                notification, outId);
1114                    } catch (RuntimeException e) {
1115                        Slog.w(ActivityManagerService.TAG,
1116                                "Error showing notification for heavy-weight app", e);
1117                    } catch (RemoteException e) {
1118                    }
1119                } catch (NameNotFoundException e) {
1120                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1121                }
1122            } break;
1123            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1124                INotificationManager inm = NotificationManager.getService();
1125                if (inm == null) {
1126                    return;
1127                }
1128                try {
1129                    inm.cancelNotification("android",
1130                            R.string.heavy_weight_notification);
1131                } catch (RuntimeException e) {
1132                    Slog.w(ActivityManagerService.TAG,
1133                            "Error canceling notification for service", e);
1134                } catch (RemoteException e) {
1135                }
1136            } break;
1137            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1138                synchronized (ActivityManagerService.this) {
1139                    checkExcessivePowerUsageLocked(true);
1140                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1141                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1142                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1143                }
1144            } break;
1145            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    ActivityRecord ar = (ActivityRecord)msg.obj;
1148                    if (mCompatModeDialog != null) {
1149                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1150                                ar.info.applicationInfo.packageName)) {
1151                            return;
1152                        }
1153                        mCompatModeDialog.dismiss();
1154                        mCompatModeDialog = null;
1155                    }
1156                    if (ar != null && false) {
1157                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1158                                ar.packageName)) {
1159                            int mode = mCompatModePackages.computeCompatModeLocked(
1160                                    ar.info.applicationInfo);
1161                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1162                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1163                                mCompatModeDialog = new CompatModeDialog(
1164                                        ActivityManagerService.this, mContext,
1165                                        ar.info.applicationInfo);
1166                                mCompatModeDialog.show();
1167                            }
1168                        }
1169                    }
1170                }
1171                break;
1172            }
1173            case DISPATCH_PROCESSES_CHANGED: {
1174                dispatchProcessesChanged();
1175                break;
1176            }
1177            case DISPATCH_PROCESS_DIED: {
1178                final int pid = msg.arg1;
1179                final int uid = msg.arg2;
1180                dispatchProcessDied(pid, uid);
1181                break;
1182            }
1183            case REPORT_MEM_USAGE: {
1184                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1185                if (!isDebuggable) {
1186                    return;
1187                }
1188                synchronized (ActivityManagerService.this) {
1189                    long now = SystemClock.uptimeMillis();
1190                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1191                        // Don't report more than every 5 minutes to somewhat
1192                        // avoid spamming.
1193                        return;
1194                    }
1195                    mLastMemUsageReportTime = now;
1196                }
1197                Thread thread = new Thread() {
1198                    @Override public void run() {
1199                        StringBuilder dropBuilder = new StringBuilder(1024);
1200                        StringBuilder logBuilder = new StringBuilder(1024);
1201                        StringWriter oomSw = new StringWriter();
1202                        PrintWriter oomPw = new PrintWriter(oomSw);
1203                        StringWriter catSw = new StringWriter();
1204                        PrintWriter catPw = new PrintWriter(catSw);
1205                        String[] emptyArgs = new String[] { };
1206                        StringBuilder tag = new StringBuilder(128);
1207                        StringBuilder stack = new StringBuilder(128);
1208                        tag.append("Low on memory -- ");
1209                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1210                                tag, stack);
1211                        dropBuilder.append(stack);
1212                        dropBuilder.append('\n');
1213                        dropBuilder.append('\n');
1214                        String oomString = oomSw.toString();
1215                        dropBuilder.append(oomString);
1216                        dropBuilder.append('\n');
1217                        logBuilder.append(oomString);
1218                        try {
1219                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1220                                    "procrank", });
1221                            final InputStreamReader converter = new InputStreamReader(
1222                                    proc.getInputStream());
1223                            BufferedReader in = new BufferedReader(converter);
1224                            String line;
1225                            while (true) {
1226                                line = in.readLine();
1227                                if (line == null) {
1228                                    break;
1229                                }
1230                                if (line.length() > 0) {
1231                                    logBuilder.append(line);
1232                                    logBuilder.append('\n');
1233                                }
1234                                dropBuilder.append(line);
1235                                dropBuilder.append('\n');
1236                            }
1237                            converter.close();
1238                        } catch (IOException e) {
1239                        }
1240                        synchronized (ActivityManagerService.this) {
1241                            catPw.println();
1242                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1243                            catPw.println();
1244                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1245                                    false, false, null);
1246                            catPw.println();
1247                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1248                        }
1249                        dropBuilder.append(catSw.toString());
1250                        addErrorToDropBox("lowmem", null, "system_server", null,
1251                                null, tag.toString(), dropBuilder.toString(), null, null);
1252                        Slog.i(TAG, logBuilder.toString());
1253                        synchronized (ActivityManagerService.this) {
1254                            long now = SystemClock.uptimeMillis();
1255                            if (mLastMemUsageReportTime < now) {
1256                                mLastMemUsageReportTime = now;
1257                            }
1258                        }
1259                    }
1260                };
1261                thread.start();
1262                break;
1263            }
1264            }
1265        }
1266    };
1267
1268    public static void setSystemProcess() {
1269        try {
1270            ActivityManagerService m = mSelf;
1271
1272            ServiceManager.addService("activity", m, true);
1273            ServiceManager.addService("meminfo", new MemBinder(m));
1274            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1275            ServiceManager.addService("dbinfo", new DbBinder(m));
1276            if (MONITOR_CPU_USAGE) {
1277                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1278            }
1279            ServiceManager.addService("permission", new PermissionController(m));
1280
1281            ApplicationInfo info =
1282                mSelf.mContext.getPackageManager().getApplicationInfo(
1283                            "android", STOCK_PM_FLAGS);
1284            mSystemThread.installSystemApplicationInfo(info);
1285
1286            synchronized (mSelf) {
1287                ProcessRecord app = mSelf.newProcessRecordLocked(
1288                        mSystemThread.getApplicationThread(), info,
1289                        info.processName, false);
1290                app.persistent = true;
1291                app.pid = MY_PID;
1292                app.maxAdj = ProcessList.SYSTEM_ADJ;
1293                mSelf.mProcessNames.put(app.processName, app.uid, app);
1294                synchronized (mSelf.mPidsSelfLocked) {
1295                    mSelf.mPidsSelfLocked.put(app.pid, app);
1296                }
1297                mSelf.updateLruProcessLocked(app, true, true);
1298            }
1299        } catch (PackageManager.NameNotFoundException e) {
1300            throw new RuntimeException(
1301                    "Unable to find android system package", e);
1302        }
1303    }
1304
1305    public void setWindowManager(WindowManagerService wm) {
1306        mWindowManager = wm;
1307    }
1308
1309    public static final Context main(int factoryTest) {
1310        AThread thr = new AThread();
1311        thr.start();
1312
1313        synchronized (thr) {
1314            while (thr.mService == null) {
1315                try {
1316                    thr.wait();
1317                } catch (InterruptedException e) {
1318                }
1319            }
1320        }
1321
1322        ActivityManagerService m = thr.mService;
1323        mSelf = m;
1324        ActivityThread at = ActivityThread.systemMain();
1325        mSystemThread = at;
1326        Context context = at.getSystemContext();
1327        context.setTheme(android.R.style.Theme_Holo);
1328        m.mContext = context;
1329        m.mFactoryTest = factoryTest;
1330        m.mMainStack = new ActivityStack(m, context, true);
1331
1332        m.mBatteryStatsService.publish(context);
1333        m.mUsageStatsService.publish(context);
1334
1335        synchronized (thr) {
1336            thr.mReady = true;
1337            thr.notifyAll();
1338        }
1339
1340        m.startRunning(null, null, null, null);
1341
1342        return context;
1343    }
1344
1345    public static ActivityManagerService self() {
1346        return mSelf;
1347    }
1348
1349    static class AThread extends Thread {
1350        ActivityManagerService mService;
1351        boolean mReady = false;
1352
1353        public AThread() {
1354            super("ActivityManager");
1355        }
1356
1357        public void run() {
1358            Looper.prepare();
1359
1360            android.os.Process.setThreadPriority(
1361                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1362            android.os.Process.setCanSelfBackground(false);
1363
1364            ActivityManagerService m = new ActivityManagerService();
1365
1366            synchronized (this) {
1367                mService = m;
1368                notifyAll();
1369            }
1370
1371            synchronized (this) {
1372                while (!mReady) {
1373                    try {
1374                        wait();
1375                    } catch (InterruptedException e) {
1376                    }
1377                }
1378            }
1379
1380            // For debug builds, log event loop stalls to dropbox for analysis.
1381            if (StrictMode.conditionallyEnableDebugLogging()) {
1382                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1383            }
1384
1385            Looper.loop();
1386        }
1387    }
1388
1389    static class MemBinder extends Binder {
1390        ActivityManagerService mActivityManagerService;
1391        MemBinder(ActivityManagerService activityManagerService) {
1392            mActivityManagerService = activityManagerService;
1393        }
1394
1395        @Override
1396        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1397            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1398                    != PackageManager.PERMISSION_GRANTED) {
1399                pw.println("Permission Denial: can't dump meminfo from from pid="
1400                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1401                        + " without permission " + android.Manifest.permission.DUMP);
1402                return;
1403            }
1404
1405            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1406                    false, null, null, null);
1407        }
1408    }
1409
1410    static class GraphicsBinder extends Binder {
1411        ActivityManagerService mActivityManagerService;
1412        GraphicsBinder(ActivityManagerService activityManagerService) {
1413            mActivityManagerService = activityManagerService;
1414        }
1415
1416        @Override
1417        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1418            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1419                    != PackageManager.PERMISSION_GRANTED) {
1420                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1421                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1422                        + " without permission " + android.Manifest.permission.DUMP);
1423                return;
1424            }
1425
1426            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1427        }
1428    }
1429
1430    static class DbBinder extends Binder {
1431        ActivityManagerService mActivityManagerService;
1432        DbBinder(ActivityManagerService activityManagerService) {
1433            mActivityManagerService = activityManagerService;
1434        }
1435
1436        @Override
1437        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1438            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1439                    != PackageManager.PERMISSION_GRANTED) {
1440                pw.println("Permission Denial: can't dump dbinfo from from pid="
1441                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1442                        + " without permission " + android.Manifest.permission.DUMP);
1443                return;
1444            }
1445
1446            mActivityManagerService.dumpDbInfo(fd, pw, args);
1447        }
1448    }
1449
1450    static class CpuBinder extends Binder {
1451        ActivityManagerService mActivityManagerService;
1452        CpuBinder(ActivityManagerService activityManagerService) {
1453            mActivityManagerService = activityManagerService;
1454        }
1455
1456        @Override
1457        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1458            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1459                    != PackageManager.PERMISSION_GRANTED) {
1460                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1461                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1462                        + " without permission " + android.Manifest.permission.DUMP);
1463                return;
1464            }
1465
1466            synchronized (mActivityManagerService.mProcessStatsThread) {
1467                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1468                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1469                        SystemClock.uptimeMillis()));
1470            }
1471        }
1472    }
1473
1474    private ActivityManagerService() {
1475        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1476
1477        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1478        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1479        mBroadcastQueues[0] = mFgBroadcastQueue;
1480        mBroadcastQueues[1] = mBgBroadcastQueue;
1481
1482        mServices = new ActiveServices(this);
1483
1484        File dataDir = Environment.getDataDirectory();
1485        File systemDir = new File(dataDir, "system");
1486        systemDir.mkdirs();
1487        mBatteryStatsService = new BatteryStatsService(new File(
1488                systemDir, "batterystats.bin").toString());
1489        mBatteryStatsService.getActiveStatistics().readLocked();
1490        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1491        mOnBattery = DEBUG_POWER ? true
1492                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1493        mBatteryStatsService.getActiveStatistics().setCallback(this);
1494
1495        mUsageStatsService = new UsageStatsService(new File(
1496                systemDir, "usagestats").toString());
1497        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1498
1499        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1500            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1501
1502        mConfiguration.setToDefaults();
1503        mConfiguration.locale = Locale.getDefault();
1504        mConfigurationSeq = mConfiguration.seq = 1;
1505        mProcessStats.init();
1506
1507        mCompatModePackages = new CompatModePackages(this, systemDir);
1508
1509        // Add ourself to the Watchdog monitors.
1510        Watchdog.getInstance().addMonitor(this);
1511
1512        mProcessStatsThread = new Thread("ProcessStats") {
1513            public void run() {
1514                while (true) {
1515                    try {
1516                        try {
1517                            synchronized(this) {
1518                                final long now = SystemClock.uptimeMillis();
1519                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1520                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1521                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1522                                //        + ", write delay=" + nextWriteDelay);
1523                                if (nextWriteDelay < nextCpuDelay) {
1524                                    nextCpuDelay = nextWriteDelay;
1525                                }
1526                                if (nextCpuDelay > 0) {
1527                                    mProcessStatsMutexFree.set(true);
1528                                    this.wait(nextCpuDelay);
1529                                }
1530                            }
1531                        } catch (InterruptedException e) {
1532                        }
1533                        updateCpuStatsNow();
1534                    } catch (Exception e) {
1535                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1536                    }
1537                }
1538            }
1539        };
1540        mProcessStatsThread.start();
1541    }
1542
1543    @Override
1544    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1545            throws RemoteException {
1546        if (code == SYSPROPS_TRANSACTION) {
1547            // We need to tell all apps about the system property change.
1548            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1549            synchronized(this) {
1550                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1551                    final int NA = apps.size();
1552                    for (int ia=0; ia<NA; ia++) {
1553                        ProcessRecord app = apps.valueAt(ia);
1554                        if (app.thread != null) {
1555                            procs.add(app.thread.asBinder());
1556                        }
1557                    }
1558                }
1559            }
1560
1561            int N = procs.size();
1562            for (int i=0; i<N; i++) {
1563                Parcel data2 = Parcel.obtain();
1564                try {
1565                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1566                } catch (RemoteException e) {
1567                }
1568                data2.recycle();
1569            }
1570        }
1571        try {
1572            return super.onTransact(code, data, reply, flags);
1573        } catch (RuntimeException e) {
1574            // The activity manager only throws security exceptions, so let's
1575            // log all others.
1576            if (!(e instanceof SecurityException)) {
1577                Slog.e(TAG, "Activity Manager Crash", e);
1578            }
1579            throw e;
1580        }
1581    }
1582
1583    void updateCpuStats() {
1584        final long now = SystemClock.uptimeMillis();
1585        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1586            return;
1587        }
1588        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1589            synchronized (mProcessStatsThread) {
1590                mProcessStatsThread.notify();
1591            }
1592        }
1593    }
1594
1595    void updateCpuStatsNow() {
1596        synchronized (mProcessStatsThread) {
1597            mProcessStatsMutexFree.set(false);
1598            final long now = SystemClock.uptimeMillis();
1599            boolean haveNewCpuStats = false;
1600
1601            if (MONITOR_CPU_USAGE &&
1602                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1603                mLastCpuTime.set(now);
1604                haveNewCpuStats = true;
1605                mProcessStats.update();
1606                //Slog.i(TAG, mProcessStats.printCurrentState());
1607                //Slog.i(TAG, "Total CPU usage: "
1608                //        + mProcessStats.getTotalCpuPercent() + "%");
1609
1610                // Slog the cpu usage if the property is set.
1611                if ("true".equals(SystemProperties.get("events.cpu"))) {
1612                    int user = mProcessStats.getLastUserTime();
1613                    int system = mProcessStats.getLastSystemTime();
1614                    int iowait = mProcessStats.getLastIoWaitTime();
1615                    int irq = mProcessStats.getLastIrqTime();
1616                    int softIrq = mProcessStats.getLastSoftIrqTime();
1617                    int idle = mProcessStats.getLastIdleTime();
1618
1619                    int total = user + system + iowait + irq + softIrq + idle;
1620                    if (total == 0) total = 1;
1621
1622                    EventLog.writeEvent(EventLogTags.CPU,
1623                            ((user+system+iowait+irq+softIrq) * 100) / total,
1624                            (user * 100) / total,
1625                            (system * 100) / total,
1626                            (iowait * 100) / total,
1627                            (irq * 100) / total,
1628                            (softIrq * 100) / total);
1629                }
1630            }
1631
1632            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1633            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1634            synchronized(bstats) {
1635                synchronized(mPidsSelfLocked) {
1636                    if (haveNewCpuStats) {
1637                        if (mOnBattery) {
1638                            int perc = bstats.startAddingCpuLocked();
1639                            int totalUTime = 0;
1640                            int totalSTime = 0;
1641                            final int N = mProcessStats.countStats();
1642                            for (int i=0; i<N; i++) {
1643                                ProcessStats.Stats st = mProcessStats.getStats(i);
1644                                if (!st.working) {
1645                                    continue;
1646                                }
1647                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1648                                int otherUTime = (st.rel_utime*perc)/100;
1649                                int otherSTime = (st.rel_stime*perc)/100;
1650                                totalUTime += otherUTime;
1651                                totalSTime += otherSTime;
1652                                if (pr != null) {
1653                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1654                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1655                                            st.rel_stime-otherSTime);
1656                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1657                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1658                                } else {
1659                                    BatteryStatsImpl.Uid.Proc ps =
1660                                            bstats.getProcessStatsLocked(st.name, st.pid);
1661                                    if (ps != null) {
1662                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1663                                                st.rel_stime-otherSTime);
1664                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1665                                    }
1666                                }
1667                            }
1668                            bstats.finishAddingCpuLocked(perc, totalUTime,
1669                                    totalSTime, cpuSpeedTimes);
1670                        }
1671                    }
1672                }
1673
1674                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1675                    mLastWriteTime = now;
1676                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1677                }
1678            }
1679        }
1680    }
1681
1682    @Override
1683    public void batteryNeedsCpuUpdate() {
1684        updateCpuStatsNow();
1685    }
1686
1687    @Override
1688    public void batteryPowerChanged(boolean onBattery) {
1689        // When plugging in, update the CPU stats first before changing
1690        // the plug state.
1691        updateCpuStatsNow();
1692        synchronized (this) {
1693            synchronized(mPidsSelfLocked) {
1694                mOnBattery = DEBUG_POWER ? true : onBattery;
1695            }
1696        }
1697    }
1698
1699    /**
1700     * Initialize the application bind args. These are passed to each
1701     * process when the bindApplication() IPC is sent to the process. They're
1702     * lazily setup to make sure the services are running when they're asked for.
1703     */
1704    private HashMap<String, IBinder> getCommonServicesLocked() {
1705        if (mAppBindArgs == null) {
1706            mAppBindArgs = new HashMap<String, IBinder>();
1707
1708            // Setup the application init args
1709            mAppBindArgs.put("package", ServiceManager.getService("package"));
1710            mAppBindArgs.put("window", ServiceManager.getService("window"));
1711            mAppBindArgs.put(Context.ALARM_SERVICE,
1712                    ServiceManager.getService(Context.ALARM_SERVICE));
1713        }
1714        return mAppBindArgs;
1715    }
1716
1717    final void setFocusedActivityLocked(ActivityRecord r) {
1718        if (mFocusedActivity != r) {
1719            mFocusedActivity = r;
1720            if (r != null) {
1721                mWindowManager.setFocusedApp(r.appToken, true);
1722            }
1723        }
1724    }
1725
1726    private final void updateLruProcessInternalLocked(ProcessRecord app,
1727            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1728        // put it on the LRU to keep track of when it should be exited.
1729        int lrui = mLruProcesses.indexOf(app);
1730        if (lrui >= 0) mLruProcesses.remove(lrui);
1731
1732        int i = mLruProcesses.size()-1;
1733        int skipTop = 0;
1734
1735        app.lruSeq = mLruSeq;
1736
1737        // compute the new weight for this process.
1738        if (updateActivityTime) {
1739            app.lastActivityTime = SystemClock.uptimeMillis();
1740        }
1741        if (app.activities.size() > 0) {
1742            // If this process has activities, we more strongly want to keep
1743            // it around.
1744            app.lruWeight = app.lastActivityTime;
1745        } else if (app.pubProviders.size() > 0) {
1746            // If this process contains content providers, we want to keep
1747            // it a little more strongly.
1748            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1749            // Also don't let it kick out the first few "real" hidden processes.
1750            skipTop = ProcessList.MIN_HIDDEN_APPS;
1751        } else {
1752            // If this process doesn't have activities, we less strongly
1753            // want to keep it around, and generally want to avoid getting
1754            // in front of any very recently used activities.
1755            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1756            // Also don't let it kick out the first few "real" hidden processes.
1757            skipTop = ProcessList.MIN_HIDDEN_APPS;
1758        }
1759
1760        while (i >= 0) {
1761            ProcessRecord p = mLruProcesses.get(i);
1762            // If this app shouldn't be in front of the first N background
1763            // apps, then skip over that many that are currently hidden.
1764            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1765                skipTop--;
1766            }
1767            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1768                mLruProcesses.add(i+1, app);
1769                break;
1770            }
1771            i--;
1772        }
1773        if (i < 0) {
1774            mLruProcesses.add(0, app);
1775        }
1776
1777        // If the app is currently using a content provider or service,
1778        // bump those processes as well.
1779        if (app.connections.size() > 0) {
1780            for (ConnectionRecord cr : app.connections) {
1781                if (cr.binding != null && cr.binding.service != null
1782                        && cr.binding.service.app != null
1783                        && cr.binding.service.app.lruSeq != mLruSeq) {
1784                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1785                            updateActivityTime, i+1);
1786                }
1787            }
1788        }
1789        for (int j=app.conProviders.size()-1; j>=0; j--) {
1790            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1791            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1792                updateLruProcessInternalLocked(cpr.proc, false,
1793                        updateActivityTime, i+1);
1794            }
1795        }
1796
1797        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1798        if (oomAdj) {
1799            updateOomAdjLocked();
1800        }
1801    }
1802
1803    final void updateLruProcessLocked(ProcessRecord app,
1804            boolean oomAdj, boolean updateActivityTime) {
1805        mLruSeq++;
1806        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1807    }
1808
1809    final ProcessRecord getProcessRecordLocked(
1810            String processName, int uid) {
1811        if (uid == Process.SYSTEM_UID) {
1812            // The system gets to run in any process.  If there are multiple
1813            // processes with the same uid, just pick the first (this
1814            // should never happen).
1815            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1816                    processName);
1817            if (procs == null) return null;
1818            final int N = procs.size();
1819            for (int i = 0; i < N; i++) {
1820                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1821            }
1822        }
1823        ProcessRecord proc = mProcessNames.get(processName, uid);
1824        return proc;
1825    }
1826
1827    void ensurePackageDexOpt(String packageName) {
1828        IPackageManager pm = AppGlobals.getPackageManager();
1829        try {
1830            if (pm.performDexOpt(packageName)) {
1831                mDidDexOpt = true;
1832            }
1833        } catch (RemoteException e) {
1834        }
1835    }
1836
1837    boolean isNextTransitionForward() {
1838        int transit = mWindowManager.getPendingAppTransition();
1839        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1840                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1841                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1842    }
1843
1844    final ProcessRecord startProcessLocked(String processName,
1845            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1846            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1847            boolean isolated) {
1848        ProcessRecord app;
1849        if (!isolated) {
1850            app = getProcessRecordLocked(processName, info.uid);
1851        } else {
1852            // If this is an isolated process, it can't re-use an existing process.
1853            app = null;
1854        }
1855        // We don't have to do anything more if:
1856        // (1) There is an existing application record; and
1857        // (2) The caller doesn't think it is dead, OR there is no thread
1858        //     object attached to it so we know it couldn't have crashed; and
1859        // (3) There is a pid assigned to it, so it is either starting or
1860        //     already running.
1861        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1862                + " app=" + app + " knownToBeDead=" + knownToBeDead
1863                + " thread=" + (app != null ? app.thread : null)
1864                + " pid=" + (app != null ? app.pid : -1));
1865        if (app != null && app.pid > 0) {
1866            if (!knownToBeDead || app.thread == null) {
1867                // We already have the app running, or are waiting for it to
1868                // come up (we have a pid but not yet its thread), so keep it.
1869                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1870                // If this is a new package in the process, add the package to the list
1871                app.addPackage(info.packageName);
1872                return app;
1873            } else {
1874                // An application record is attached to a previous process,
1875                // clean it up now.
1876                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1877                handleAppDiedLocked(app, true, true);
1878            }
1879        }
1880
1881        String hostingNameStr = hostingName != null
1882                ? hostingName.flattenToShortString() : null;
1883
1884        if (!isolated) {
1885            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1886                // If we are in the background, then check to see if this process
1887                // is bad.  If so, we will just silently fail.
1888                if (mBadProcesses.get(info.processName, info.uid) != null) {
1889                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1890                            + "/" + info.processName);
1891                    return null;
1892                }
1893            } else {
1894                // When the user is explicitly starting a process, then clear its
1895                // crash count so that we won't make it bad until they see at
1896                // least one crash dialog again, and make the process good again
1897                // if it had been bad.
1898                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1899                        + "/" + info.processName);
1900                mProcessCrashTimes.remove(info.processName, info.uid);
1901                if (mBadProcesses.get(info.processName, info.uid) != null) {
1902                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1903                            info.processName);
1904                    mBadProcesses.remove(info.processName, info.uid);
1905                    if (app != null) {
1906                        app.bad = false;
1907                    }
1908                }
1909            }
1910        }
1911
1912        if (app == null) {
1913            app = newProcessRecordLocked(null, info, processName, isolated);
1914            if (app == null) {
1915                Slog.w(TAG, "Failed making new process record for "
1916                        + processName + "/" + info.uid + " isolated=" + isolated);
1917                return null;
1918            }
1919            mProcessNames.put(processName, app.uid, app);
1920            if (isolated) {
1921                mIsolatedProcesses.put(app.uid, app);
1922            }
1923        } else {
1924            // If this is a new package in the process, add the package to the list
1925            app.addPackage(info.packageName);
1926        }
1927
1928        // If the system is not ready yet, then hold off on starting this
1929        // process until it is.
1930        if (!mProcessesReady
1931                && !isAllowedWhileBooting(info)
1932                && !allowWhileBooting) {
1933            if (!mProcessesOnHold.contains(app)) {
1934                mProcessesOnHold.add(app);
1935            }
1936            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1937            return app;
1938        }
1939
1940        startProcessLocked(app, hostingType, hostingNameStr);
1941        return (app.pid != 0) ? app : null;
1942    }
1943
1944    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1945        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1946    }
1947
1948    private final void startProcessLocked(ProcessRecord app,
1949            String hostingType, String hostingNameStr) {
1950        if (app.pid > 0 && app.pid != MY_PID) {
1951            synchronized (mPidsSelfLocked) {
1952                mPidsSelfLocked.remove(app.pid);
1953                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1954            }
1955            app.pid = 0;
1956        }
1957
1958        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1959                "startProcessLocked removing on hold: " + app);
1960        mProcessesOnHold.remove(app);
1961
1962        updateCpuStats();
1963
1964        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1965        mProcDeaths[0] = 0;
1966
1967        try {
1968            int uid = app.uid;
1969
1970            int[] gids = null;
1971            if (!app.isolated) {
1972                try {
1973                    gids = mContext.getPackageManager().getPackageGids(
1974                            app.info.packageName);
1975                } catch (PackageManager.NameNotFoundException e) {
1976                    Slog.w(TAG, "Unable to retrieve gids", e);
1977                }
1978            }
1979            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1980                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1981                        && mTopComponent != null
1982                        && app.processName.equals(mTopComponent.getPackageName())) {
1983                    uid = 0;
1984                }
1985                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1986                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1987                    uid = 0;
1988                }
1989            }
1990            int debugFlags = 0;
1991            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1992                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1993                // Also turn on CheckJNI for debuggable apps. It's quite
1994                // awkward to turn on otherwise.
1995                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1996            }
1997            // Run the app in safe mode if its manifest requests so or the
1998            // system is booted in safe mode.
1999            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2000                Zygote.systemInSafeMode == true) {
2001                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2002            }
2003            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2004                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2005            }
2006            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2007                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2008            }
2009            if ("1".equals(SystemProperties.get("debug.assert"))) {
2010                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2011            }
2012
2013            // Start the process.  It will either succeed and return a result containing
2014            // the PID of the new process, or else throw a RuntimeException.
2015            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2016                    app.processName, uid, uid, gids, debugFlags,
2017                    app.info.targetSdkVersion, null, null);
2018
2019            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2020            synchronized (bs) {
2021                if (bs.isOnBattery()) {
2022                    app.batteryStats.incStartsLocked();
2023                }
2024            }
2025
2026            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2027                    app.processName, hostingType,
2028                    hostingNameStr != null ? hostingNameStr : "");
2029
2030            if (app.persistent) {
2031                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2032            }
2033
2034            StringBuilder buf = mStringBuilder;
2035            buf.setLength(0);
2036            buf.append("Start proc ");
2037            buf.append(app.processName);
2038            buf.append(" for ");
2039            buf.append(hostingType);
2040            if (hostingNameStr != null) {
2041                buf.append(" ");
2042                buf.append(hostingNameStr);
2043            }
2044            buf.append(": pid=");
2045            buf.append(startResult.pid);
2046            buf.append(" uid=");
2047            buf.append(uid);
2048            buf.append(" gids={");
2049            if (gids != null) {
2050                for (int gi=0; gi<gids.length; gi++) {
2051                    if (gi != 0) buf.append(", ");
2052                    buf.append(gids[gi]);
2053
2054                }
2055            }
2056            buf.append("}");
2057            Slog.i(TAG, buf.toString());
2058            app.pid = startResult.pid;
2059            app.usingWrapper = startResult.usingWrapper;
2060            app.removed = false;
2061            synchronized (mPidsSelfLocked) {
2062                this.mPidsSelfLocked.put(startResult.pid, app);
2063                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2064                msg.obj = app;
2065                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2066                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2067            }
2068        } catch (RuntimeException e) {
2069            // XXX do better error recovery.
2070            app.pid = 0;
2071            Slog.e(TAG, "Failure starting process " + app.processName, e);
2072        }
2073    }
2074
2075    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2076        if (resumed) {
2077            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2078        } else {
2079            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2080        }
2081    }
2082
2083    boolean startHomeActivityLocked(int userId) {
2084        if (mHeadless) {
2085            // Added because none of the other calls to ensureBootCompleted seem to fire
2086            // when running headless.
2087            ensureBootCompleted();
2088            return false;
2089        }
2090
2091        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2092                && mTopAction == null) {
2093            // We are running in factory test mode, but unable to find
2094            // the factory test app, so just sit around displaying the
2095            // error message and don't try to start anything.
2096            return false;
2097        }
2098        Intent intent = new Intent(
2099            mTopAction,
2100            mTopData != null ? Uri.parse(mTopData) : null);
2101        intent.setComponent(mTopComponent);
2102        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2103            intent.addCategory(Intent.CATEGORY_HOME);
2104        }
2105        ActivityInfo aInfo =
2106            intent.resolveActivityInfo(mContext.getPackageManager(),
2107                    STOCK_PM_FLAGS);
2108        if (aInfo != null) {
2109            intent.setComponent(new ComponentName(
2110                    aInfo.applicationInfo.packageName, aInfo.name));
2111            // Don't do this if the home app is currently being
2112            // instrumented.
2113            aInfo = new ActivityInfo(aInfo);
2114            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2115            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2116                    aInfo.applicationInfo.uid);
2117            if (app == null || app.instrumentationClass == null) {
2118                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2119                mMainStack.startActivityLocked(null, intent, null, aInfo,
2120                        null, null, 0, 0, 0, 0, null, false, null);
2121            }
2122        }
2123
2124        return true;
2125    }
2126
2127    /**
2128     * Starts the "new version setup screen" if appropriate.
2129     */
2130    void startSetupActivityLocked() {
2131        // Only do this once per boot.
2132        if (mCheckedForSetup) {
2133            return;
2134        }
2135
2136        // We will show this screen if the current one is a different
2137        // version than the last one shown, and we are not running in
2138        // low-level factory test mode.
2139        final ContentResolver resolver = mContext.getContentResolver();
2140        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2141                Settings.Secure.getInt(resolver,
2142                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2143            mCheckedForSetup = true;
2144
2145            // See if we should be showing the platform update setup UI.
2146            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2147            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2148                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2149
2150            // We don't allow third party apps to replace this.
2151            ResolveInfo ri = null;
2152            for (int i=0; ris != null && i<ris.size(); i++) {
2153                if ((ris.get(i).activityInfo.applicationInfo.flags
2154                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2155                    ri = ris.get(i);
2156                    break;
2157                }
2158            }
2159
2160            if (ri != null) {
2161                String vers = ri.activityInfo.metaData != null
2162                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2163                        : null;
2164                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2165                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2166                            Intent.METADATA_SETUP_VERSION);
2167                }
2168                String lastVers = Settings.Secure.getString(
2169                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2170                if (vers != null && !vers.equals(lastVers)) {
2171                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2172                    intent.setComponent(new ComponentName(
2173                            ri.activityInfo.packageName, ri.activityInfo.name));
2174                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2175                            null, null, 0, 0, 0, 0, null, false, null);
2176                }
2177            }
2178        }
2179    }
2180
2181    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2182        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2183    }
2184
2185    void enforceNotIsolatedCaller(String caller) {
2186        if (UserId.isIsolated(Binder.getCallingUid())) {
2187            throw new SecurityException("Isolated process not allowed to call " + caller);
2188        }
2189    }
2190
2191    public int getFrontActivityScreenCompatMode() {
2192        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2193        synchronized (this) {
2194            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2195        }
2196    }
2197
2198    public void setFrontActivityScreenCompatMode(int mode) {
2199        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2200                "setFrontActivityScreenCompatMode");
2201        synchronized (this) {
2202            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2203        }
2204    }
2205
2206    public int getPackageScreenCompatMode(String packageName) {
2207        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2208        synchronized (this) {
2209            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2210        }
2211    }
2212
2213    public void setPackageScreenCompatMode(String packageName, int mode) {
2214        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2215                "setPackageScreenCompatMode");
2216        synchronized (this) {
2217            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2218        }
2219    }
2220
2221    public boolean getPackageAskScreenCompat(String packageName) {
2222        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2223        synchronized (this) {
2224            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2225        }
2226    }
2227
2228    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2229        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2230                "setPackageAskScreenCompat");
2231        synchronized (this) {
2232            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2233        }
2234    }
2235
2236    void reportResumedActivityLocked(ActivityRecord r) {
2237        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2238        updateUsageStats(r, true);
2239    }
2240
2241    private void dispatchProcessesChanged() {
2242        int N;
2243        synchronized (this) {
2244            N = mPendingProcessChanges.size();
2245            if (mActiveProcessChanges.length < N) {
2246                mActiveProcessChanges = new ProcessChangeItem[N];
2247            }
2248            mPendingProcessChanges.toArray(mActiveProcessChanges);
2249            mAvailProcessChanges.addAll(mPendingProcessChanges);
2250            mPendingProcessChanges.clear();
2251            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2252        }
2253        int i = mProcessObservers.beginBroadcast();
2254        while (i > 0) {
2255            i--;
2256            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2257            if (observer != null) {
2258                try {
2259                    for (int j=0; j<N; j++) {
2260                        ProcessChangeItem item = mActiveProcessChanges[j];
2261                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2262                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2263                                    + item.pid + " uid=" + item.uid + ": "
2264                                    + item.foregroundActivities);
2265                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2266                                    item.foregroundActivities);
2267                        }
2268                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2269                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2270                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2271                            observer.onImportanceChanged(item.pid, item.uid,
2272                                    item.importance);
2273                        }
2274                    }
2275                } catch (RemoteException e) {
2276                }
2277            }
2278        }
2279        mProcessObservers.finishBroadcast();
2280    }
2281
2282    private void dispatchProcessDied(int pid, int uid) {
2283        int i = mProcessObservers.beginBroadcast();
2284        while (i > 0) {
2285            i--;
2286            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2287            if (observer != null) {
2288                try {
2289                    observer.onProcessDied(pid, uid);
2290                } catch (RemoteException e) {
2291                }
2292            }
2293        }
2294        mProcessObservers.finishBroadcast();
2295    }
2296
2297    final void doPendingActivityLaunchesLocked(boolean doResume) {
2298        final int N = mPendingActivityLaunches.size();
2299        if (N <= 0) {
2300            return;
2301        }
2302        for (int i=0; i<N; i++) {
2303            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2304            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2305                    pal.startFlags, doResume && i == (N-1), null);
2306        }
2307        mPendingActivityLaunches.clear();
2308    }
2309
2310    public final int startActivity(IApplicationThread caller,
2311            Intent intent, String resolvedType, IBinder resultTo,
2312            String resultWho, int requestCode, int startFlags,
2313            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2314        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2315                startFlags, profileFile, profileFd, options, UserId.getCallingUserId());
2316    }
2317
2318    public final int startActivityAsUser(IApplicationThread caller,
2319            Intent intent, String resolvedType, IBinder resultTo,
2320            String resultWho, int requestCode, int startFlags,
2321            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2322        enforceNotIsolatedCaller("startActivity");
2323        if (userId != UserId.getCallingUserId()) {
2324            // Requesting a different user, make sure that they have the permission
2325            if (checkComponentPermission(
2326                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2327                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2328                    == PackageManager.PERMISSION_GRANTED) {
2329                // Translate to the current user id, if caller wasn't aware
2330                if (userId == UserId.USER_CURRENT) {
2331                    userId = mCurrentUserId;
2332                }
2333            } else {
2334                String msg = "Permission Denial: "
2335                        + "Request to startActivity as user " + userId
2336                        + " but is calling from user " + UserId.getCallingUserId()
2337                        + "; this requires "
2338                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2339                Slog.w(TAG, msg);
2340                throw new SecurityException(msg);
2341            }
2342        } else {
2343            if (intent.getCategories() != null
2344                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2345                // Requesting home, set the identity to the current user
2346                // HACK!
2347                userId = mCurrentUserId;
2348            } else {
2349                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2350                // the current user's userId
2351                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2352                    userId = 0;
2353                } else {
2354                    userId = Binder.getOrigCallingUser();
2355                }
2356            }
2357        }
2358        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2359                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2360                null, null, options, userId);
2361    }
2362
2363    public final WaitResult startActivityAndWait(IApplicationThread caller,
2364            Intent intent, String resolvedType, IBinder resultTo,
2365            String resultWho, int requestCode, int startFlags, String profileFile,
2366            ParcelFileDescriptor profileFd, Bundle options) {
2367        enforceNotIsolatedCaller("startActivityAndWait");
2368        WaitResult res = new WaitResult();
2369        int userId = Binder.getOrigCallingUser();
2370        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2371                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2372                res, null, options, userId);
2373        return res;
2374    }
2375
2376    public final int startActivityWithConfig(IApplicationThread caller,
2377            Intent intent, String resolvedType, IBinder resultTo,
2378            String resultWho, int requestCode, int startFlags, Configuration config,
2379            Bundle options) {
2380        enforceNotIsolatedCaller("startActivityWithConfig");
2381        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2382                resultTo, resultWho, requestCode, startFlags,
2383                null, null, null, config, options, Binder.getOrigCallingUser());
2384        return ret;
2385    }
2386
2387    public int startActivityIntentSender(IApplicationThread caller,
2388            IntentSender intent, Intent fillInIntent, String resolvedType,
2389            IBinder resultTo, String resultWho, int requestCode,
2390            int flagsMask, int flagsValues, Bundle options) {
2391        enforceNotIsolatedCaller("startActivityIntentSender");
2392        // Refuse possible leaked file descriptors
2393        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2394            throw new IllegalArgumentException("File descriptors passed in Intent");
2395        }
2396
2397        IIntentSender sender = intent.getTarget();
2398        if (!(sender instanceof PendingIntentRecord)) {
2399            throw new IllegalArgumentException("Bad PendingIntent object");
2400        }
2401
2402        PendingIntentRecord pir = (PendingIntentRecord)sender;
2403
2404        synchronized (this) {
2405            // If this is coming from the currently resumed activity, it is
2406            // effectively saying that app switches are allowed at this point.
2407            if (mMainStack.mResumedActivity != null
2408                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2409                            Binder.getCallingUid()) {
2410                mAppSwitchesAllowedTime = 0;
2411            }
2412        }
2413        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2414                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2415        return ret;
2416    }
2417
2418    public boolean startNextMatchingActivity(IBinder callingActivity,
2419            Intent intent, Bundle options) {
2420        // Refuse possible leaked file descriptors
2421        if (intent != null && intent.hasFileDescriptors() == true) {
2422            throw new IllegalArgumentException("File descriptors passed in Intent");
2423        }
2424
2425        synchronized (this) {
2426            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2427            if (r == null) {
2428                ActivityOptions.abort(options);
2429                return false;
2430            }
2431            if (r.app == null || r.app.thread == null) {
2432                // The caller is not running...  d'oh!
2433                ActivityOptions.abort(options);
2434                return false;
2435            }
2436            intent = new Intent(intent);
2437            // The caller is not allowed to change the data.
2438            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2439            // And we are resetting to find the next component...
2440            intent.setComponent(null);
2441
2442            ActivityInfo aInfo = null;
2443            try {
2444                List<ResolveInfo> resolves =
2445                    AppGlobals.getPackageManager().queryIntentActivities(
2446                            intent, r.resolvedType,
2447                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2448                            UserId.getCallingUserId());
2449
2450                // Look for the original activity in the list...
2451                final int N = resolves != null ? resolves.size() : 0;
2452                for (int i=0; i<N; i++) {
2453                    ResolveInfo rInfo = resolves.get(i);
2454                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2455                            && rInfo.activityInfo.name.equals(r.info.name)) {
2456                        // We found the current one...  the next matching is
2457                        // after it.
2458                        i++;
2459                        if (i<N) {
2460                            aInfo = resolves.get(i).activityInfo;
2461                        }
2462                        break;
2463                    }
2464                }
2465            } catch (RemoteException e) {
2466            }
2467
2468            if (aInfo == null) {
2469                // Nobody who is next!
2470                ActivityOptions.abort(options);
2471                return false;
2472            }
2473
2474            intent.setComponent(new ComponentName(
2475                    aInfo.applicationInfo.packageName, aInfo.name));
2476            intent.setFlags(intent.getFlags()&~(
2477                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2478                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2479                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2480                    Intent.FLAG_ACTIVITY_NEW_TASK));
2481
2482            // Okay now we need to start the new activity, replacing the
2483            // currently running activity.  This is a little tricky because
2484            // we want to start the new one as if the current one is finished,
2485            // but not finish the current one first so that there is no flicker.
2486            // And thus...
2487            final boolean wasFinishing = r.finishing;
2488            r.finishing = true;
2489
2490            // Propagate reply information over to the new activity.
2491            final ActivityRecord resultTo = r.resultTo;
2492            final String resultWho = r.resultWho;
2493            final int requestCode = r.requestCode;
2494            r.resultTo = null;
2495            if (resultTo != null) {
2496                resultTo.removeResultsLocked(r, resultWho, requestCode);
2497            }
2498
2499            final long origId = Binder.clearCallingIdentity();
2500            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2501                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2502                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2503                    options, false, null);
2504            Binder.restoreCallingIdentity(origId);
2505
2506            r.finishing = wasFinishing;
2507            if (res != ActivityManager.START_SUCCESS) {
2508                return false;
2509            }
2510            return true;
2511        }
2512    }
2513
2514    public final int startActivityInPackage(int uid,
2515            Intent intent, String resolvedType, IBinder resultTo,
2516            String resultWho, int requestCode, int startFlags, Bundle options) {
2517
2518        // This is so super not safe, that only the system (or okay root)
2519        // can do it.
2520        int userId = Binder.getOrigCallingUser();
2521        final int callingUid = Binder.getCallingUid();
2522        if (callingUid != 0 && callingUid != Process.myUid()) {
2523            throw new SecurityException(
2524                    "startActivityInPackage only available to the system");
2525        }
2526
2527        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2528                resultTo, resultWho, requestCode, startFlags,
2529                null, null, null, null, options, userId);
2530        return ret;
2531    }
2532
2533    public final int startActivities(IApplicationThread caller,
2534            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2535        enforceNotIsolatedCaller("startActivities");
2536        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2537                options, Binder.getOrigCallingUser());
2538        return ret;
2539    }
2540
2541    public final int startActivitiesInPackage(int uid,
2542            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2543            Bundle options) {
2544
2545        // This is so super not safe, that only the system (or okay root)
2546        // can do it.
2547        final int callingUid = Binder.getCallingUid();
2548        if (callingUid != 0 && callingUid != Process.myUid()) {
2549            throw new SecurityException(
2550                    "startActivityInPackage only available to the system");
2551        }
2552        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2553                options, UserId.getUserId(uid));
2554        return ret;
2555    }
2556
2557    final void addRecentTaskLocked(TaskRecord task) {
2558        int N = mRecentTasks.size();
2559        // Quick case: check if the top-most recent task is the same.
2560        if (N > 0 && mRecentTasks.get(0) == task) {
2561            return;
2562        }
2563        // Remove any existing entries that are the same kind of task.
2564        for (int i=0; i<N; i++) {
2565            TaskRecord tr = mRecentTasks.get(i);
2566            if (task.userId == tr.userId
2567                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2568                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2569                mRecentTasks.remove(i);
2570                i--;
2571                N--;
2572                if (task.intent == null) {
2573                    // If the new recent task we are adding is not fully
2574                    // specified, then replace it with the existing recent task.
2575                    task = tr;
2576                }
2577            }
2578        }
2579        if (N >= MAX_RECENT_TASKS) {
2580            mRecentTasks.remove(N-1);
2581        }
2582        mRecentTasks.add(0, task);
2583    }
2584
2585    public void setRequestedOrientation(IBinder token,
2586            int requestedOrientation) {
2587        synchronized (this) {
2588            ActivityRecord r = mMainStack.isInStackLocked(token);
2589            if (r == null) {
2590                return;
2591            }
2592            final long origId = Binder.clearCallingIdentity();
2593            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2594            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2595                    mConfiguration,
2596                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2597            if (config != null) {
2598                r.frozenBeforeDestroy = true;
2599                if (!updateConfigurationLocked(config, r, false, false)) {
2600                    mMainStack.resumeTopActivityLocked(null);
2601                }
2602            }
2603            Binder.restoreCallingIdentity(origId);
2604        }
2605    }
2606
2607    public int getRequestedOrientation(IBinder token) {
2608        synchronized (this) {
2609            ActivityRecord r = mMainStack.isInStackLocked(token);
2610            if (r == null) {
2611                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2612            }
2613            return mWindowManager.getAppOrientation(r.appToken);
2614        }
2615    }
2616
2617    /**
2618     * This is the internal entry point for handling Activity.finish().
2619     *
2620     * @param token The Binder token referencing the Activity we want to finish.
2621     * @param resultCode Result code, if any, from this Activity.
2622     * @param resultData Result data (Intent), if any, from this Activity.
2623     *
2624     * @return Returns true if the activity successfully finished, or false if it is still running.
2625     */
2626    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2627        // Refuse possible leaked file descriptors
2628        if (resultData != null && resultData.hasFileDescriptors() == true) {
2629            throw new IllegalArgumentException("File descriptors passed in Intent");
2630        }
2631
2632        synchronized(this) {
2633            if (mController != null) {
2634                // Find the first activity that is not finishing.
2635                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2636                if (next != null) {
2637                    // ask watcher if this is allowed
2638                    boolean resumeOK = true;
2639                    try {
2640                        resumeOK = mController.activityResuming(next.packageName);
2641                    } catch (RemoteException e) {
2642                        mController = null;
2643                    }
2644
2645                    if (!resumeOK) {
2646                        return false;
2647                    }
2648                }
2649            }
2650            final long origId = Binder.clearCallingIdentity();
2651            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2652                    resultData, "app-request");
2653            Binder.restoreCallingIdentity(origId);
2654            return res;
2655        }
2656    }
2657
2658    public final void finishHeavyWeightApp() {
2659        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2660                != PackageManager.PERMISSION_GRANTED) {
2661            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2662                    + Binder.getCallingPid()
2663                    + ", uid=" + Binder.getCallingUid()
2664                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2665            Slog.w(TAG, msg);
2666            throw new SecurityException(msg);
2667        }
2668
2669        synchronized(this) {
2670            if (mHeavyWeightProcess == null) {
2671                return;
2672            }
2673
2674            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2675                    mHeavyWeightProcess.activities);
2676            for (int i=0; i<activities.size(); i++) {
2677                ActivityRecord r = activities.get(i);
2678                if (!r.finishing) {
2679                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2680                    if (index >= 0) {
2681                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2682                                null, "finish-heavy");
2683                    }
2684                }
2685            }
2686
2687            mHeavyWeightProcess = null;
2688            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2689        }
2690    }
2691
2692    public void crashApplication(int uid, int initialPid, String packageName,
2693            String message) {
2694        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2695                != PackageManager.PERMISSION_GRANTED) {
2696            String msg = "Permission Denial: crashApplication() from pid="
2697                    + Binder.getCallingPid()
2698                    + ", uid=" + Binder.getCallingUid()
2699                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2700            Slog.w(TAG, msg);
2701            throw new SecurityException(msg);
2702        }
2703
2704        synchronized(this) {
2705            ProcessRecord proc = null;
2706
2707            // Figure out which process to kill.  We don't trust that initialPid
2708            // still has any relation to current pids, so must scan through the
2709            // list.
2710            synchronized (mPidsSelfLocked) {
2711                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2712                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2713                    if (p.uid != uid) {
2714                        continue;
2715                    }
2716                    if (p.pid == initialPid) {
2717                        proc = p;
2718                        break;
2719                    }
2720                    for (String str : p.pkgList) {
2721                        if (str.equals(packageName)) {
2722                            proc = p;
2723                        }
2724                    }
2725                }
2726            }
2727
2728            if (proc == null) {
2729                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2730                        + " initialPid=" + initialPid
2731                        + " packageName=" + packageName);
2732                return;
2733            }
2734
2735            if (proc.thread != null) {
2736                if (proc.pid == Process.myPid()) {
2737                    Log.w(TAG, "crashApplication: trying to crash self!");
2738                    return;
2739                }
2740                long ident = Binder.clearCallingIdentity();
2741                try {
2742                    proc.thread.scheduleCrash(message);
2743                } catch (RemoteException e) {
2744                }
2745                Binder.restoreCallingIdentity(ident);
2746            }
2747        }
2748    }
2749
2750    public final void finishSubActivity(IBinder token, String resultWho,
2751            int requestCode) {
2752        synchronized(this) {
2753            final long origId = Binder.clearCallingIdentity();
2754            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2755            Binder.restoreCallingIdentity(origId);
2756        }
2757    }
2758
2759    public boolean finishActivityAffinity(IBinder token) {
2760        synchronized(this) {
2761            final long origId = Binder.clearCallingIdentity();
2762            boolean res = mMainStack.finishActivityAffinityLocked(token);
2763            Binder.restoreCallingIdentity(origId);
2764            return res;
2765        }
2766    }
2767
2768    public boolean willActivityBeVisible(IBinder token) {
2769        synchronized(this) {
2770            int i;
2771            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2772                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2773                if (r.appToken == token) {
2774                    return true;
2775                }
2776                if (r.fullscreen && !r.finishing) {
2777                    return false;
2778                }
2779            }
2780            return true;
2781        }
2782    }
2783
2784    public void overridePendingTransition(IBinder token, String packageName,
2785            int enterAnim, int exitAnim) {
2786        synchronized(this) {
2787            ActivityRecord self = mMainStack.isInStackLocked(token);
2788            if (self == null) {
2789                return;
2790            }
2791
2792            final long origId = Binder.clearCallingIdentity();
2793
2794            if (self.state == ActivityState.RESUMED
2795                    || self.state == ActivityState.PAUSING) {
2796                mWindowManager.overridePendingAppTransition(packageName,
2797                        enterAnim, exitAnim, null);
2798            }
2799
2800            Binder.restoreCallingIdentity(origId);
2801        }
2802    }
2803
2804    /**
2805     * Main function for removing an existing process from the activity manager
2806     * as a result of that process going away.  Clears out all connections
2807     * to the process.
2808     */
2809    private final void handleAppDiedLocked(ProcessRecord app,
2810            boolean restarting, boolean allowRestart) {
2811        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2812        if (!restarting) {
2813            mLruProcesses.remove(app);
2814        }
2815
2816        if (mProfileProc == app) {
2817            clearProfilerLocked();
2818        }
2819
2820        // Just in case...
2821        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2822            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2823            mMainStack.mPausingActivity = null;
2824        }
2825        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2826            mMainStack.mLastPausedActivity = null;
2827        }
2828
2829        // Remove this application's activities from active lists.
2830        mMainStack.removeHistoryRecordsForAppLocked(app);
2831
2832        boolean atTop = true;
2833        boolean hasVisibleActivities = false;
2834
2835        // Clean out the history list.
2836        int i = mMainStack.mHistory.size();
2837        if (localLOGV) Slog.v(
2838            TAG, "Removing app " + app + " from history with " + i + " entries");
2839        while (i > 0) {
2840            i--;
2841            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2842            if (localLOGV) Slog.v(
2843                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2844            if (r.app == app) {
2845                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2846                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2847                        RuntimeException here = new RuntimeException("here");
2848                        here.fillInStackTrace();
2849                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2850                                + ": haveState=" + r.haveState
2851                                + " stateNotNeeded=" + r.stateNotNeeded
2852                                + " finishing=" + r.finishing
2853                                + " state=" + r.state, here);
2854                    }
2855                    if (!r.finishing) {
2856                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2857                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2858                                System.identityHashCode(r),
2859                                r.task.taskId, r.shortComponentName,
2860                                "proc died without state saved");
2861                    }
2862                    mMainStack.removeActivityFromHistoryLocked(r);
2863
2864                } else {
2865                    // We have the current state for this activity, so
2866                    // it can be restarted later when needed.
2867                    if (localLOGV) Slog.v(
2868                        TAG, "Keeping entry, setting app to null");
2869                    if (r.visible) {
2870                        hasVisibleActivities = true;
2871                    }
2872                    r.app = null;
2873                    r.nowVisible = false;
2874                    if (!r.haveState) {
2875                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2876                                "App died, clearing saved state of " + r);
2877                        r.icicle = null;
2878                    }
2879                }
2880
2881                r.stack.cleanUpActivityLocked(r, true, true);
2882            }
2883            atTop = false;
2884        }
2885
2886        app.activities.clear();
2887
2888        if (app.instrumentationClass != null) {
2889            Slog.w(TAG, "Crash of app " + app.processName
2890                  + " running instrumentation " + app.instrumentationClass);
2891            Bundle info = new Bundle();
2892            info.putString("shortMsg", "Process crashed.");
2893            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2894        }
2895
2896        if (!restarting) {
2897            if (!mMainStack.resumeTopActivityLocked(null)) {
2898                // If there was nothing to resume, and we are not already
2899                // restarting this process, but there is a visible activity that
2900                // is hosted by the process...  then make sure all visible
2901                // activities are running, taking care of restarting this
2902                // process.
2903                if (hasVisibleActivities) {
2904                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2905                }
2906            }
2907        }
2908    }
2909
2910    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2911        IBinder threadBinder = thread.asBinder();
2912        // Find the application record.
2913        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2914            ProcessRecord rec = mLruProcesses.get(i);
2915            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2916                return i;
2917            }
2918        }
2919        return -1;
2920    }
2921
2922    final ProcessRecord getRecordForAppLocked(
2923            IApplicationThread thread) {
2924        if (thread == null) {
2925            return null;
2926        }
2927
2928        int appIndex = getLRURecordIndexForAppLocked(thread);
2929        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2930    }
2931
2932    final void appDiedLocked(ProcessRecord app, int pid,
2933            IApplicationThread thread) {
2934
2935        mProcDeaths[0]++;
2936
2937        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2938        synchronized (stats) {
2939            stats.noteProcessDiedLocked(app.info.uid, pid);
2940        }
2941
2942        // Clean up already done if the process has been re-started.
2943        if (app.pid == pid && app.thread != null &&
2944                app.thread.asBinder() == thread.asBinder()) {
2945            if (!app.killedBackground) {
2946                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2947                        + ") has died.");
2948            }
2949            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2950            if (localLOGV) Slog.v(
2951                TAG, "Dying app: " + app + ", pid: " + pid
2952                + ", thread: " + thread.asBinder());
2953            boolean doLowMem = app.instrumentationClass == null;
2954            handleAppDiedLocked(app, false, true);
2955
2956            if (doLowMem) {
2957                // If there are no longer any background processes running,
2958                // and the app that died was not running instrumentation,
2959                // then tell everyone we are now low on memory.
2960                boolean haveBg = false;
2961                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2962                    ProcessRecord rec = mLruProcesses.get(i);
2963                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2964                        haveBg = true;
2965                        break;
2966                    }
2967                }
2968
2969                if (!haveBg) {
2970                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2971                    long now = SystemClock.uptimeMillis();
2972                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2973                        ProcessRecord rec = mLruProcesses.get(i);
2974                        if (rec != app && rec.thread != null &&
2975                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2976                            // The low memory report is overriding any current
2977                            // state for a GC request.  Make sure to do
2978                            // heavy/important/visible/foreground processes first.
2979                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2980                                rec.lastRequestedGc = 0;
2981                            } else {
2982                                rec.lastRequestedGc = rec.lastLowMemory;
2983                            }
2984                            rec.reportLowMemory = true;
2985                            rec.lastLowMemory = now;
2986                            mProcessesToGc.remove(rec);
2987                            addProcessToGcListLocked(rec);
2988                        }
2989                    }
2990                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
2991                    scheduleAppGcsLocked();
2992                }
2993            }
2994        } else if (app.pid != pid) {
2995            // A new process has already been started.
2996            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2997                    + ") has died and restarted (pid " + app.pid + ").");
2998            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2999        } else if (DEBUG_PROCESSES) {
3000            Slog.d(TAG, "Received spurious death notification for thread "
3001                    + thread.asBinder());
3002        }
3003    }
3004
3005    /**
3006     * If a stack trace dump file is configured, dump process stack traces.
3007     * @param clearTraces causes the dump file to be erased prior to the new
3008     *    traces being written, if true; when false, the new traces will be
3009     *    appended to any existing file content.
3010     * @param firstPids of dalvik VM processes to dump stack traces for first
3011     * @param lastPids of dalvik VM processes to dump stack traces for last
3012     * @param nativeProcs optional list of native process names to dump stack crawls
3013     * @return file containing stack traces, or null if no dump file is configured
3014     */
3015    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3016            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3017        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3018        if (tracesPath == null || tracesPath.length() == 0) {
3019            return null;
3020        }
3021
3022        File tracesFile = new File(tracesPath);
3023        try {
3024            File tracesDir = tracesFile.getParentFile();
3025            if (!tracesDir.exists()) tracesFile.mkdirs();
3026            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3027
3028            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3029            tracesFile.createNewFile();
3030            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3031        } catch (IOException e) {
3032            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3033            return null;
3034        }
3035
3036        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3037        return tracesFile;
3038    }
3039
3040    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3041            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3042        // Use a FileObserver to detect when traces finish writing.
3043        // The order of traces is considered important to maintain for legibility.
3044        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3045            public synchronized void onEvent(int event, String path) { notify(); }
3046        };
3047
3048        try {
3049            observer.startWatching();
3050
3051            // First collect all of the stacks of the most important pids.
3052            if (firstPids != null) {
3053                try {
3054                    int num = firstPids.size();
3055                    for (int i = 0; i < num; i++) {
3056                        synchronized (observer) {
3057                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3058                            observer.wait(200);  // Wait for write-close, give up after 200msec
3059                        }
3060                    }
3061                } catch (InterruptedException e) {
3062                    Log.wtf(TAG, e);
3063                }
3064            }
3065
3066            // Next measure CPU usage.
3067            if (processStats != null) {
3068                processStats.init();
3069                System.gc();
3070                processStats.update();
3071                try {
3072                    synchronized (processStats) {
3073                        processStats.wait(500); // measure over 1/2 second.
3074                    }
3075                } catch (InterruptedException e) {
3076                }
3077                processStats.update();
3078
3079                // We'll take the stack crawls of just the top apps using CPU.
3080                final int N = processStats.countWorkingStats();
3081                int numProcs = 0;
3082                for (int i=0; i<N && numProcs<5; i++) {
3083                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3084                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3085                        numProcs++;
3086                        try {
3087                            synchronized (observer) {
3088                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3089                                observer.wait(200);  // Wait for write-close, give up after 200msec
3090                            }
3091                        } catch (InterruptedException e) {
3092                            Log.wtf(TAG, e);
3093                        }
3094
3095                    }
3096                }
3097            }
3098
3099        } finally {
3100            observer.stopWatching();
3101        }
3102
3103        if (nativeProcs != null) {
3104            int[] pids = Process.getPidsForCommands(nativeProcs);
3105            if (pids != null) {
3106                for (int pid : pids) {
3107                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3108                }
3109            }
3110        }
3111    }
3112
3113    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3114        if (true || IS_USER_BUILD) {
3115            return;
3116        }
3117        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3118        if (tracesPath == null || tracesPath.length() == 0) {
3119            return;
3120        }
3121
3122        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3123        StrictMode.allowThreadDiskWrites();
3124        try {
3125            final File tracesFile = new File(tracesPath);
3126            final File tracesDir = tracesFile.getParentFile();
3127            final File tracesTmp = new File(tracesDir, "__tmp__");
3128            try {
3129                if (!tracesDir.exists()) tracesFile.mkdirs();
3130                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3131
3132                if (tracesFile.exists()) {
3133                    tracesTmp.delete();
3134                    tracesFile.renameTo(tracesTmp);
3135                }
3136                StringBuilder sb = new StringBuilder();
3137                Time tobj = new Time();
3138                tobj.set(System.currentTimeMillis());
3139                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3140                sb.append(": ");
3141                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3142                sb.append(" since ");
3143                sb.append(msg);
3144                FileOutputStream fos = new FileOutputStream(tracesFile);
3145                fos.write(sb.toString().getBytes());
3146                if (app == null) {
3147                    fos.write("\n*** No application process!".getBytes());
3148                }
3149                fos.close();
3150                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3151            } catch (IOException e) {
3152                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3153                return;
3154            }
3155
3156            if (app != null) {
3157                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3158                firstPids.add(app.pid);
3159                dumpStackTraces(tracesPath, firstPids, null, null, null);
3160            }
3161
3162            File lastTracesFile = null;
3163            File curTracesFile = null;
3164            for (int i=9; i>=0; i--) {
3165                String name = String.format("slow%02d.txt", i);
3166                curTracesFile = new File(tracesDir, name);
3167                if (curTracesFile.exists()) {
3168                    if (lastTracesFile != null) {
3169                        curTracesFile.renameTo(lastTracesFile);
3170                    } else {
3171                        curTracesFile.delete();
3172                    }
3173                }
3174                lastTracesFile = curTracesFile;
3175            }
3176            tracesFile.renameTo(curTracesFile);
3177            if (tracesTmp.exists()) {
3178                tracesTmp.renameTo(tracesFile);
3179            }
3180        } finally {
3181            StrictMode.setThreadPolicy(oldPolicy);
3182        }
3183    }
3184
3185    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3186            ActivityRecord parent, final String annotation) {
3187        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3188        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3189
3190        if (mController != null) {
3191            try {
3192                // 0 == continue, -1 = kill process immediately
3193                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3194                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3195            } catch (RemoteException e) {
3196                mController = null;
3197            }
3198        }
3199
3200        long anrTime = SystemClock.uptimeMillis();
3201        if (MONITOR_CPU_USAGE) {
3202            updateCpuStatsNow();
3203        }
3204
3205        synchronized (this) {
3206            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3207            if (mShuttingDown) {
3208                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3209                return;
3210            } else if (app.notResponding) {
3211                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3212                return;
3213            } else if (app.crashing) {
3214                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3215                return;
3216            }
3217
3218            // In case we come through here for the same app before completing
3219            // this one, mark as anring now so we will bail out.
3220            app.notResponding = true;
3221
3222            // Log the ANR to the event log.
3223            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3224                    annotation);
3225
3226            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3227            firstPids.add(app.pid);
3228
3229            int parentPid = app.pid;
3230            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3231            if (parentPid != app.pid) firstPids.add(parentPid);
3232
3233            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3234
3235            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3236                ProcessRecord r = mLruProcesses.get(i);
3237                if (r != null && r.thread != null) {
3238                    int pid = r.pid;
3239                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3240                        if (r.persistent) {
3241                            firstPids.add(pid);
3242                        } else {
3243                            lastPids.put(pid, Boolean.TRUE);
3244                        }
3245                    }
3246                }
3247            }
3248        }
3249
3250        // Log the ANR to the main log.
3251        StringBuilder info = new StringBuilder();
3252        info.setLength(0);
3253        info.append("ANR in ").append(app.processName);
3254        if (activity != null && activity.shortComponentName != null) {
3255            info.append(" (").append(activity.shortComponentName).append(")");
3256        }
3257        info.append("\n");
3258        if (annotation != null) {
3259            info.append("Reason: ").append(annotation).append("\n");
3260        }
3261        if (parent != null && parent != activity) {
3262            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3263        }
3264
3265        final ProcessStats processStats = new ProcessStats(true);
3266
3267        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3268
3269        String cpuInfo = null;
3270        if (MONITOR_CPU_USAGE) {
3271            updateCpuStatsNow();
3272            synchronized (mProcessStatsThread) {
3273                cpuInfo = mProcessStats.printCurrentState(anrTime);
3274            }
3275            info.append(processStats.printCurrentLoad());
3276            info.append(cpuInfo);
3277        }
3278
3279        info.append(processStats.printCurrentState(anrTime));
3280
3281        Slog.e(TAG, info.toString());
3282        if (tracesFile == null) {
3283            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3284            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3285        }
3286
3287        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3288                cpuInfo, tracesFile, null);
3289
3290        if (mController != null) {
3291            try {
3292                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3293                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3294                if (res != 0) {
3295                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3296                    return;
3297                }
3298            } catch (RemoteException e) {
3299                mController = null;
3300            }
3301        }
3302
3303        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3304        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3305                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3306
3307        synchronized (this) {
3308            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3309                Slog.w(TAG, "Killing " + app + ": background ANR");
3310                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3311                        app.processName, app.setAdj, "background ANR");
3312                Process.killProcessQuiet(app.pid);
3313                return;
3314            }
3315
3316            // Set the app's notResponding state, and look up the errorReportReceiver
3317            makeAppNotRespondingLocked(app,
3318                    activity != null ? activity.shortComponentName : null,
3319                    annotation != null ? "ANR " + annotation : "ANR",
3320                    info.toString());
3321
3322            // Bring up the infamous App Not Responding dialog
3323            Message msg = Message.obtain();
3324            HashMap map = new HashMap();
3325            msg.what = SHOW_NOT_RESPONDING_MSG;
3326            msg.obj = map;
3327            map.put("app", app);
3328            if (activity != null) {
3329                map.put("activity", activity);
3330            }
3331
3332            mHandler.sendMessage(msg);
3333        }
3334    }
3335
3336    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3337        if (!mLaunchWarningShown) {
3338            mLaunchWarningShown = true;
3339            mHandler.post(new Runnable() {
3340                @Override
3341                public void run() {
3342                    synchronized (ActivityManagerService.this) {
3343                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3344                        d.show();
3345                        mHandler.postDelayed(new Runnable() {
3346                            @Override
3347                            public void run() {
3348                                synchronized (ActivityManagerService.this) {
3349                                    d.dismiss();
3350                                    mLaunchWarningShown = false;
3351                                }
3352                            }
3353                        }, 4000);
3354                    }
3355                }
3356            });
3357        }
3358    }
3359
3360    public boolean clearApplicationUserData(final String packageName,
3361            final IPackageDataObserver observer, final int userId) {
3362        enforceNotIsolatedCaller("clearApplicationUserData");
3363        int uid = Binder.getCallingUid();
3364        int pid = Binder.getCallingPid();
3365        long callingId = Binder.clearCallingIdentity();
3366        try {
3367            IPackageManager pm = AppGlobals.getPackageManager();
3368            int pkgUid = -1;
3369            synchronized(this) {
3370                try {
3371                    pkgUid = pm.getPackageUid(packageName, userId);
3372                } catch (RemoteException e) {
3373                }
3374                if (pkgUid == -1) {
3375                    Slog.w(TAG, "Invalid packageName:" + packageName);
3376                    return false;
3377                }
3378                if (uid == pkgUid || checkComponentPermission(
3379                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3380                        pid, uid, -1, true)
3381                        == PackageManager.PERMISSION_GRANTED) {
3382                    forceStopPackageLocked(packageName, pkgUid);
3383                } else {
3384                    throw new SecurityException(pid+" does not have permission:"+
3385                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3386                                    "for process:"+packageName);
3387                }
3388            }
3389
3390            try {
3391                //clear application user data
3392                pm.clearApplicationUserData(packageName, observer, userId);
3393                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3394                        Uri.fromParts("package", packageName, null));
3395                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3396                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3397                        null, null, 0, null, null, null, false, false, userId);
3398            } catch (RemoteException e) {
3399            }
3400        } finally {
3401            Binder.restoreCallingIdentity(callingId);
3402        }
3403        return true;
3404    }
3405
3406    public void killBackgroundProcesses(final String packageName) {
3407        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3408                != PackageManager.PERMISSION_GRANTED &&
3409                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3410                        != PackageManager.PERMISSION_GRANTED) {
3411            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3412                    + Binder.getCallingPid()
3413                    + ", uid=" + Binder.getCallingUid()
3414                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3415            Slog.w(TAG, msg);
3416            throw new SecurityException(msg);
3417        }
3418
3419        int userId = UserId.getCallingUserId();
3420        long callingId = Binder.clearCallingIdentity();
3421        try {
3422            IPackageManager pm = AppGlobals.getPackageManager();
3423            int pkgUid = -1;
3424            synchronized(this) {
3425                try {
3426                    pkgUid = pm.getPackageUid(packageName, userId);
3427                } catch (RemoteException e) {
3428                }
3429                if (pkgUid == -1) {
3430                    Slog.w(TAG, "Invalid packageName: " + packageName);
3431                    return;
3432                }
3433                killPackageProcessesLocked(packageName, pkgUid,
3434                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3435            }
3436        } finally {
3437            Binder.restoreCallingIdentity(callingId);
3438        }
3439    }
3440
3441    public void killAllBackgroundProcesses() {
3442        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3443                != PackageManager.PERMISSION_GRANTED) {
3444            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3445                    + Binder.getCallingPid()
3446                    + ", uid=" + Binder.getCallingUid()
3447                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3448            Slog.w(TAG, msg);
3449            throw new SecurityException(msg);
3450        }
3451
3452        long callingId = Binder.clearCallingIdentity();
3453        try {
3454            synchronized(this) {
3455                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3456                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3457                    final int NA = apps.size();
3458                    for (int ia=0; ia<NA; ia++) {
3459                        ProcessRecord app = apps.valueAt(ia);
3460                        if (app.persistent) {
3461                            // we don't kill persistent processes
3462                            continue;
3463                        }
3464                        if (app.removed) {
3465                            procs.add(app);
3466                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3467                            app.removed = true;
3468                            procs.add(app);
3469                        }
3470                    }
3471                }
3472
3473                int N = procs.size();
3474                for (int i=0; i<N; i++) {
3475                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3476                }
3477            }
3478        } finally {
3479            Binder.restoreCallingIdentity(callingId);
3480        }
3481    }
3482
3483    public void forceStopPackage(final String packageName) {
3484        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3485                != PackageManager.PERMISSION_GRANTED) {
3486            String msg = "Permission Denial: forceStopPackage() from pid="
3487                    + Binder.getCallingPid()
3488                    + ", uid=" + Binder.getCallingUid()
3489                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3490            Slog.w(TAG, msg);
3491            throw new SecurityException(msg);
3492        }
3493        final int userId = UserId.getCallingUserId();
3494        long callingId = Binder.clearCallingIdentity();
3495        try {
3496            IPackageManager pm = AppGlobals.getPackageManager();
3497            int pkgUid = -1;
3498            synchronized(this) {
3499                try {
3500                    pkgUid = pm.getPackageUid(packageName, userId);
3501                } catch (RemoteException e) {
3502                }
3503                if (pkgUid == -1) {
3504                    Slog.w(TAG, "Invalid packageName: " + packageName);
3505                    return;
3506                }
3507                forceStopPackageLocked(packageName, pkgUid);
3508                try {
3509                    pm.setPackageStoppedState(packageName, true, userId);
3510                } catch (RemoteException e) {
3511                } catch (IllegalArgumentException e) {
3512                    Slog.w(TAG, "Failed trying to unstop package "
3513                            + packageName + ": " + e);
3514                }
3515            }
3516        } finally {
3517            Binder.restoreCallingIdentity(callingId);
3518        }
3519    }
3520
3521    /*
3522     * The pkg name and uid have to be specified.
3523     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3524     */
3525    public void killApplicationWithUid(String pkg, int uid) {
3526        if (pkg == null) {
3527            return;
3528        }
3529        // Make sure the uid is valid.
3530        if (uid < 0) {
3531            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3532            return;
3533        }
3534        int callerUid = Binder.getCallingUid();
3535        // Only the system server can kill an application
3536        if (callerUid == Process.SYSTEM_UID) {
3537            // Post an aysnc message to kill the application
3538            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3539            msg.arg1 = uid;
3540            msg.arg2 = 0;
3541            msg.obj = pkg;
3542            mHandler.sendMessage(msg);
3543        } else {
3544            throw new SecurityException(callerUid + " cannot kill pkg: " +
3545                    pkg);
3546        }
3547    }
3548
3549    public void closeSystemDialogs(String reason) {
3550        enforceNotIsolatedCaller("closeSystemDialogs");
3551
3552        final int uid = Binder.getCallingUid();
3553        final long origId = Binder.clearCallingIdentity();
3554        synchronized (this) {
3555            closeSystemDialogsLocked(uid, reason);
3556        }
3557        Binder.restoreCallingIdentity(origId);
3558    }
3559
3560    void closeSystemDialogsLocked(int callingUid, String reason) {
3561        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3562        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3563        if (reason != null) {
3564            intent.putExtra("reason", reason);
3565        }
3566        mWindowManager.closeSystemDialogs(reason);
3567
3568        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3569            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3570            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3571                r.stack.finishActivityLocked(r, i,
3572                        Activity.RESULT_CANCELED, null, "close-sys");
3573            }
3574        }
3575
3576        broadcastIntentLocked(null, null, intent, null,
3577                null, 0, null, null, null, false, false, -1,
3578                callingUid, 0 /* TODO: Verify */);
3579    }
3580
3581    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3582            throws RemoteException {
3583        enforceNotIsolatedCaller("getProcessMemoryInfo");
3584        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3585        for (int i=pids.length-1; i>=0; i--) {
3586            infos[i] = new Debug.MemoryInfo();
3587            Debug.getMemoryInfo(pids[i], infos[i]);
3588        }
3589        return infos;
3590    }
3591
3592    public long[] getProcessPss(int[] pids) throws RemoteException {
3593        enforceNotIsolatedCaller("getProcessPss");
3594        long[] pss = new long[pids.length];
3595        for (int i=pids.length-1; i>=0; i--) {
3596            pss[i] = Debug.getPss(pids[i]);
3597        }
3598        return pss;
3599    }
3600
3601    public void killApplicationProcess(String processName, int uid) {
3602        if (processName == null) {
3603            return;
3604        }
3605
3606        int callerUid = Binder.getCallingUid();
3607        // Only the system server can kill an application
3608        if (callerUid == Process.SYSTEM_UID) {
3609            synchronized (this) {
3610                ProcessRecord app = getProcessRecordLocked(processName, uid);
3611                if (app != null && app.thread != null) {
3612                    try {
3613                        app.thread.scheduleSuicide();
3614                    } catch (RemoteException e) {
3615                        // If the other end already died, then our work here is done.
3616                    }
3617                } else {
3618                    Slog.w(TAG, "Process/uid not found attempting kill of "
3619                            + processName + " / " + uid);
3620                }
3621            }
3622        } else {
3623            throw new SecurityException(callerUid + " cannot kill app process: " +
3624                    processName);
3625        }
3626    }
3627
3628    private void forceStopPackageLocked(final String packageName, int uid) {
3629        forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
3630        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3631                Uri.fromParts("package", packageName, null));
3632        if (!mProcessesReady) {
3633            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3634        }
3635        intent.putExtra(Intent.EXTRA_UID, uid);
3636        broadcastIntentLocked(null, null, intent,
3637                null, null, 0, null, null, null,
3638                false, false,
3639                MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
3640    }
3641
3642    private final boolean killPackageProcessesLocked(String packageName, int uid,
3643            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3644            boolean evenPersistent, String reason) {
3645        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3646
3647        // Remove all processes this package may have touched: all with the
3648        // same UID (except for the system or root user), and all whose name
3649        // matches the package name.
3650        final String procNamePrefix = packageName + ":";
3651        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3652            final int NA = apps.size();
3653            for (int ia=0; ia<NA; ia++) {
3654                ProcessRecord app = apps.valueAt(ia);
3655                if (app.persistent && !evenPersistent) {
3656                    // we don't kill persistent processes
3657                    continue;
3658                }
3659                if (app.removed) {
3660                    if (doit) {
3661                        procs.add(app);
3662                    }
3663                // If uid is specified and the uid and process name match
3664                // Or, the uid is not specified and the process name matches
3665                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3666                            || ((app.processName.equals(packageName)
3667                                 || app.processName.startsWith(procNamePrefix))
3668                                && uid < 0))) {
3669                    if (app.setAdj >= minOomAdj) {
3670                        if (!doit) {
3671                            return true;
3672                        }
3673                        app.removed = true;
3674                        procs.add(app);
3675                    }
3676                }
3677            }
3678        }
3679
3680        int N = procs.size();
3681        for (int i=0; i<N; i++) {
3682            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3683        }
3684        return N > 0;
3685    }
3686
3687    private final boolean forceStopPackageLocked(String name, int uid,
3688            boolean callerWillRestart, boolean purgeCache, boolean doit,
3689            boolean evenPersistent, int userId) {
3690        int i;
3691        int N;
3692
3693        if (uid < 0) {
3694            try {
3695                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3696            } catch (RemoteException e) {
3697            }
3698        }
3699
3700        if (doit) {
3701            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3702
3703            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3704            while (badApps.hasNext()) {
3705                SparseArray<Long> ba = badApps.next();
3706                if (ba.get(uid) != null) {
3707                    badApps.remove();
3708                }
3709            }
3710        }
3711
3712        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3713                callerWillRestart, false, doit, evenPersistent, "force stop");
3714
3715        TaskRecord lastTask = null;
3716        for (i=0; i<mMainStack.mHistory.size(); i++) {
3717            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3718            final boolean samePackage = r.packageName.equals(name);
3719            if (r.userId == userId
3720                    && (samePackage || r.task == lastTask)
3721                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3722                if (!doit) {
3723                    if (r.finishing) {
3724                        // If this activity is just finishing, then it is not
3725                        // interesting as far as something to stop.
3726                        continue;
3727                    }
3728                    return true;
3729                }
3730                didSomething = true;
3731                Slog.i(TAG, "  Force finishing activity " + r);
3732                if (samePackage) {
3733                    if (r.app != null) {
3734                        r.app.removed = true;
3735                    }
3736                    r.app = null;
3737                }
3738                lastTask = r.task;
3739                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3740                        null, "force-stop", true)) {
3741                    i--;
3742                }
3743            }
3744        }
3745
3746        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3747            if (!doit) {
3748                return true;
3749            }
3750            didSomething = true;
3751        }
3752
3753        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3754        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3755            if (provider.info.packageName.equals(name)
3756                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3757                if (!doit) {
3758                    return true;
3759                }
3760                didSomething = true;
3761                providers.add(provider);
3762            }
3763        }
3764
3765        N = providers.size();
3766        for (i=0; i<N; i++) {
3767            removeDyingProviderLocked(null, providers.get(i), true);
3768        }
3769
3770        if (doit) {
3771            if (purgeCache) {
3772                AttributeCache ac = AttributeCache.instance();
3773                if (ac != null) {
3774                    ac.removePackage(name);
3775                }
3776            }
3777            if (mBooted) {
3778                mMainStack.resumeTopActivityLocked(null);
3779                mMainStack.scheduleIdleLocked();
3780            }
3781        }
3782
3783        return didSomething;
3784    }
3785
3786    private final boolean removeProcessLocked(ProcessRecord app,
3787            boolean callerWillRestart, boolean allowRestart, String reason) {
3788        final String name = app.processName;
3789        final int uid = app.uid;
3790        if (DEBUG_PROCESSES) Slog.d(
3791            TAG, "Force removing proc " + app.toShortString() + " (" + name
3792            + "/" + uid + ")");
3793
3794        mProcessNames.remove(name, uid);
3795        mIsolatedProcesses.remove(app.uid);
3796        if (mHeavyWeightProcess == app) {
3797            mHeavyWeightProcess = null;
3798            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3799        }
3800        boolean needRestart = false;
3801        if (app.pid > 0 && app.pid != MY_PID) {
3802            int pid = app.pid;
3803            synchronized (mPidsSelfLocked) {
3804                mPidsSelfLocked.remove(pid);
3805                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3806            }
3807            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3808            handleAppDiedLocked(app, true, allowRestart);
3809            mLruProcesses.remove(app);
3810            Process.killProcessQuiet(pid);
3811
3812            if (app.persistent && !app.isolated) {
3813                if (!callerWillRestart) {
3814                    addAppLocked(app.info, false);
3815                } else {
3816                    needRestart = true;
3817                }
3818            }
3819        } else {
3820            mRemovedProcesses.add(app);
3821        }
3822
3823        return needRestart;
3824    }
3825
3826    private final void processStartTimedOutLocked(ProcessRecord app) {
3827        final int pid = app.pid;
3828        boolean gone = false;
3829        synchronized (mPidsSelfLocked) {
3830            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3831            if (knownApp != null && knownApp.thread == null) {
3832                mPidsSelfLocked.remove(pid);
3833                gone = true;
3834            }
3835        }
3836
3837        if (gone) {
3838            Slog.w(TAG, "Process " + app + " failed to attach");
3839            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3840                    app.processName);
3841            mProcessNames.remove(app.processName, app.uid);
3842            mIsolatedProcesses.remove(app.uid);
3843            if (mHeavyWeightProcess == app) {
3844                mHeavyWeightProcess = null;
3845                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3846            }
3847            // Take care of any launching providers waiting for this process.
3848            checkAppInLaunchingProvidersLocked(app, true);
3849            // Take care of any services that are waiting for the process.
3850            mServices.processStartTimedOutLocked(app);
3851            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3852                    app.processName, app.setAdj, "start timeout");
3853            Process.killProcessQuiet(pid);
3854            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3855                Slog.w(TAG, "Unattached app died before backup, skipping");
3856                try {
3857                    IBackupManager bm = IBackupManager.Stub.asInterface(
3858                            ServiceManager.getService(Context.BACKUP_SERVICE));
3859                    bm.agentDisconnected(app.info.packageName);
3860                } catch (RemoteException e) {
3861                    // Can't happen; the backup manager is local
3862                }
3863            }
3864            if (isPendingBroadcastProcessLocked(pid)) {
3865                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3866                skipPendingBroadcastLocked(pid);
3867            }
3868        } else {
3869            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3870        }
3871    }
3872
3873    private final boolean attachApplicationLocked(IApplicationThread thread,
3874            int pid) {
3875
3876        // Find the application record that is being attached...  either via
3877        // the pid if we are running in multiple processes, or just pull the
3878        // next app record if we are emulating process with anonymous threads.
3879        ProcessRecord app;
3880        if (pid != MY_PID && pid >= 0) {
3881            synchronized (mPidsSelfLocked) {
3882                app = mPidsSelfLocked.get(pid);
3883            }
3884        } else {
3885            app = null;
3886        }
3887
3888        if (app == null) {
3889            Slog.w(TAG, "No pending application record for pid " + pid
3890                    + " (IApplicationThread " + thread + "); dropping process");
3891            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3892            if (pid > 0 && pid != MY_PID) {
3893                Process.killProcessQuiet(pid);
3894            } else {
3895                try {
3896                    thread.scheduleExit();
3897                } catch (Exception e) {
3898                    // Ignore exceptions.
3899                }
3900            }
3901            return false;
3902        }
3903
3904        // If this application record is still attached to a previous
3905        // process, clean it up now.
3906        if (app.thread != null) {
3907            handleAppDiedLocked(app, true, true);
3908        }
3909
3910        // Tell the process all about itself.
3911
3912        if (localLOGV) Slog.v(
3913                TAG, "Binding process pid " + pid + " to record " + app);
3914
3915        String processName = app.processName;
3916        try {
3917            AppDeathRecipient adr = new AppDeathRecipient(
3918                    app, pid, thread);
3919            thread.asBinder().linkToDeath(adr, 0);
3920            app.deathRecipient = adr;
3921        } catch (RemoteException e) {
3922            app.resetPackageList();
3923            startProcessLocked(app, "link fail", processName);
3924            return false;
3925        }
3926
3927        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3928
3929        app.thread = thread;
3930        app.curAdj = app.setAdj = -100;
3931        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3932        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3933        app.forcingToForeground = null;
3934        app.foregroundServices = false;
3935        app.hasShownUi = false;
3936        app.debugging = false;
3937
3938        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3939
3940        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3941        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3942
3943        if (!normalMode) {
3944            Slog.i(TAG, "Launching preboot mode app: " + app);
3945        }
3946
3947        if (localLOGV) Slog.v(
3948            TAG, "New app record " + app
3949            + " thread=" + thread.asBinder() + " pid=" + pid);
3950        try {
3951            int testMode = IApplicationThread.DEBUG_OFF;
3952            if (mDebugApp != null && mDebugApp.equals(processName)) {
3953                testMode = mWaitForDebugger
3954                    ? IApplicationThread.DEBUG_WAIT
3955                    : IApplicationThread.DEBUG_ON;
3956                app.debugging = true;
3957                if (mDebugTransient) {
3958                    mDebugApp = mOrigDebugApp;
3959                    mWaitForDebugger = mOrigWaitForDebugger;
3960                }
3961            }
3962            String profileFile = app.instrumentationProfileFile;
3963            ParcelFileDescriptor profileFd = null;
3964            boolean profileAutoStop = false;
3965            if (mProfileApp != null && mProfileApp.equals(processName)) {
3966                mProfileProc = app;
3967                profileFile = mProfileFile;
3968                profileFd = mProfileFd;
3969                profileAutoStop = mAutoStopProfiler;
3970            }
3971            boolean enableOpenGlTrace = false;
3972            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3973                enableOpenGlTrace = true;
3974                mOpenGlTraceApp = null;
3975            }
3976
3977            // If the app is being launched for restore or full backup, set it up specially
3978            boolean isRestrictedBackupMode = false;
3979            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3980                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3981                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3982                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3983            }
3984
3985            ensurePackageDexOpt(app.instrumentationInfo != null
3986                    ? app.instrumentationInfo.packageName
3987                    : app.info.packageName);
3988            if (app.instrumentationClass != null) {
3989                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3990            }
3991            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3992                    + processName + " with config " + mConfiguration);
3993            ApplicationInfo appInfo = app.instrumentationInfo != null
3994                    ? app.instrumentationInfo : app.info;
3995            app.compat = compatibilityInfoForPackageLocked(appInfo);
3996            if (profileFd != null) {
3997                profileFd = profileFd.dup();
3998            }
3999            thread.bindApplication(processName, appInfo, providers,
4000                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4001                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4002                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4003                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4004                    mCoreSettingsObserver.getCoreSettingsLocked());
4005            updateLruProcessLocked(app, false, true);
4006            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4007        } catch (Exception e) {
4008            // todo: Yikes!  What should we do?  For now we will try to
4009            // start another process, but that could easily get us in
4010            // an infinite loop of restarting processes...
4011            Slog.w(TAG, "Exception thrown during bind!", e);
4012
4013            app.resetPackageList();
4014            app.unlinkDeathRecipient();
4015            startProcessLocked(app, "bind fail", processName);
4016            return false;
4017        }
4018
4019        // Remove this record from the list of starting applications.
4020        mPersistentStartingProcesses.remove(app);
4021        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4022                "Attach application locked removing on hold: " + app);
4023        mProcessesOnHold.remove(app);
4024
4025        boolean badApp = false;
4026        boolean didSomething = false;
4027
4028        // See if the top visible activity is waiting to run in this process...
4029        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4030        if (hr != null && normalMode) {
4031            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4032                    && processName.equals(hr.processName)) {
4033                try {
4034                    if (mHeadless) {
4035                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4036                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4037                        didSomething = true;
4038                    }
4039                } catch (Exception e) {
4040                    Slog.w(TAG, "Exception in new application when starting activity "
4041                          + hr.intent.getComponent().flattenToShortString(), e);
4042                    badApp = true;
4043                }
4044            } else {
4045                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4046            }
4047        }
4048
4049        // Find any services that should be running in this process...
4050        if (!badApp) {
4051            try {
4052                didSomething |= mServices.attachApplicationLocked(app, processName);
4053            } catch (Exception e) {
4054                badApp = true;
4055            }
4056        }
4057
4058        // Check if a next-broadcast receiver is in this process...
4059        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4060            try {
4061                didSomething = sendPendingBroadcastsLocked(app);
4062            } catch (Exception e) {
4063                // If the app died trying to launch the receiver we declare it 'bad'
4064                badApp = true;
4065            }
4066        }
4067
4068        // Check whether the next backup agent is in this process...
4069        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4070            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4071            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4072            try {
4073                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4074                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4075                        mBackupTarget.backupMode);
4076            } catch (Exception e) {
4077                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4078                e.printStackTrace();
4079            }
4080        }
4081
4082        if (badApp) {
4083            // todo: Also need to kill application to deal with all
4084            // kinds of exceptions.
4085            handleAppDiedLocked(app, false, true);
4086            return false;
4087        }
4088
4089        if (!didSomething) {
4090            updateOomAdjLocked();
4091        }
4092
4093        return true;
4094    }
4095
4096    public final void attachApplication(IApplicationThread thread) {
4097        synchronized (this) {
4098            int callingPid = Binder.getCallingPid();
4099            final long origId = Binder.clearCallingIdentity();
4100            attachApplicationLocked(thread, callingPid);
4101            Binder.restoreCallingIdentity(origId);
4102        }
4103    }
4104
4105    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4106        final long origId = Binder.clearCallingIdentity();
4107        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4108        if (stopProfiling) {
4109            synchronized (this) {
4110                if (mProfileProc == r.app) {
4111                    if (mProfileFd != null) {
4112                        try {
4113                            mProfileFd.close();
4114                        } catch (IOException e) {
4115                        }
4116                        clearProfilerLocked();
4117                    }
4118                }
4119            }
4120        }
4121        Binder.restoreCallingIdentity(origId);
4122    }
4123
4124    void enableScreenAfterBoot() {
4125        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4126                SystemClock.uptimeMillis());
4127        mWindowManager.enableScreenAfterBoot();
4128
4129        synchronized (this) {
4130            updateEventDispatchingLocked();
4131        }
4132    }
4133
4134    public void showBootMessage(final CharSequence msg, final boolean always) {
4135        enforceNotIsolatedCaller("showBootMessage");
4136        mWindowManager.showBootMessage(msg, always);
4137    }
4138
4139    public void dismissKeyguardOnNextActivity() {
4140        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4141        final long token = Binder.clearCallingIdentity();
4142        try {
4143            synchronized (this) {
4144                if (mLockScreenShown) {
4145                    mLockScreenShown = false;
4146                    comeOutOfSleepIfNeededLocked();
4147                }
4148                mMainStack.dismissKeyguardOnNextActivityLocked();
4149            }
4150        } finally {
4151            Binder.restoreCallingIdentity(token);
4152        }
4153    }
4154
4155    final void finishBooting() {
4156        IntentFilter pkgFilter = new IntentFilter();
4157        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4158        pkgFilter.addDataScheme("package");
4159        mContext.registerReceiver(new BroadcastReceiver() {
4160            @Override
4161            public void onReceive(Context context, Intent intent) {
4162                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4163                if (pkgs != null) {
4164                    for (String pkg : pkgs) {
4165                        synchronized (ActivityManagerService.this) {
4166                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4167                                setResultCode(Activity.RESULT_OK);
4168                                return;
4169                            }
4170                        }
4171                    }
4172                }
4173            }
4174        }, pkgFilter);
4175
4176        IntentFilter userFilter = new IntentFilter();
4177        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4178        mContext.registerReceiver(new BroadcastReceiver() {
4179            @Override
4180            public void onReceive(Context context, Intent intent) {
4181                onUserRemoved(intent);
4182            }
4183        }, userFilter);
4184
4185        synchronized (this) {
4186            // Ensure that any processes we had put on hold are now started
4187            // up.
4188            final int NP = mProcessesOnHold.size();
4189            if (NP > 0) {
4190                ArrayList<ProcessRecord> procs =
4191                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4192                for (int ip=0; ip<NP; ip++) {
4193                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4194                            + procs.get(ip));
4195                    startProcessLocked(procs.get(ip), "on-hold", null);
4196                }
4197            }
4198
4199            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4200                // Start looking for apps that are abusing wake locks.
4201                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4202                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4203                // Tell anyone interested that we are done booting!
4204                SystemProperties.set("sys.boot_completed", "1");
4205                SystemProperties.set("dev.bootcomplete", "1");
4206                List<UserInfo> users = getUserManager().getUsers();
4207                for (UserInfo user : users) {
4208                    broadcastIntentLocked(null, null,
4209                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4210                            null, null, 0, null, null,
4211                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4212                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4213                }
4214            }
4215        }
4216    }
4217
4218    final void ensureBootCompleted() {
4219        boolean booting;
4220        boolean enableScreen;
4221        synchronized (this) {
4222            booting = mBooting;
4223            mBooting = false;
4224            enableScreen = !mBooted;
4225            mBooted = true;
4226        }
4227
4228        if (booting) {
4229            finishBooting();
4230        }
4231
4232        if (enableScreen) {
4233            enableScreenAfterBoot();
4234        }
4235    }
4236
4237    public final void activityPaused(IBinder token) {
4238        final long origId = Binder.clearCallingIdentity();
4239        mMainStack.activityPaused(token, false);
4240        Binder.restoreCallingIdentity(origId);
4241    }
4242
4243    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4244            CharSequence description) {
4245        if (localLOGV) Slog.v(
4246            TAG, "Activity stopped: token=" + token);
4247
4248        // Refuse possible leaked file descriptors
4249        if (icicle != null && icicle.hasFileDescriptors()) {
4250            throw new IllegalArgumentException("File descriptors passed in Bundle");
4251        }
4252
4253        ActivityRecord r = null;
4254
4255        final long origId = Binder.clearCallingIdentity();
4256
4257        synchronized (this) {
4258            r = mMainStack.isInStackLocked(token);
4259            if (r != null) {
4260                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4261            }
4262        }
4263
4264        if (r != null) {
4265            sendPendingThumbnail(r, null, null, null, false);
4266        }
4267
4268        trimApplications();
4269
4270        Binder.restoreCallingIdentity(origId);
4271    }
4272
4273    public final void activityDestroyed(IBinder token) {
4274        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4275        mMainStack.activityDestroyed(token);
4276    }
4277
4278    public String getCallingPackage(IBinder token) {
4279        synchronized (this) {
4280            ActivityRecord r = getCallingRecordLocked(token);
4281            return r != null && r.app != null ? r.info.packageName : null;
4282        }
4283    }
4284
4285    public ComponentName getCallingActivity(IBinder token) {
4286        synchronized (this) {
4287            ActivityRecord r = getCallingRecordLocked(token);
4288            return r != null ? r.intent.getComponent() : null;
4289        }
4290    }
4291
4292    private ActivityRecord getCallingRecordLocked(IBinder token) {
4293        ActivityRecord r = mMainStack.isInStackLocked(token);
4294        if (r == null) {
4295            return null;
4296        }
4297        return r.resultTo;
4298    }
4299
4300    public ComponentName getActivityClassForToken(IBinder token) {
4301        synchronized(this) {
4302            ActivityRecord r = mMainStack.isInStackLocked(token);
4303            if (r == null) {
4304                return null;
4305            }
4306            return r.intent.getComponent();
4307        }
4308    }
4309
4310    public String getPackageForToken(IBinder token) {
4311        synchronized(this) {
4312            ActivityRecord r = mMainStack.isInStackLocked(token);
4313            if (r == null) {
4314                return null;
4315            }
4316            return r.packageName;
4317        }
4318    }
4319
4320    public IIntentSender getIntentSender(int type,
4321            String packageName, IBinder token, String resultWho,
4322            int requestCode, Intent[] intents, String[] resolvedTypes,
4323            int flags, Bundle options) {
4324        enforceNotIsolatedCaller("getIntentSender");
4325        // Refuse possible leaked file descriptors
4326        if (intents != null) {
4327            if (intents.length < 1) {
4328                throw new IllegalArgumentException("Intents array length must be >= 1");
4329            }
4330            for (int i=0; i<intents.length; i++) {
4331                Intent intent = intents[i];
4332                if (intent != null) {
4333                    if (intent.hasFileDescriptors()) {
4334                        throw new IllegalArgumentException("File descriptors passed in Intent");
4335                    }
4336                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4337                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4338                        throw new IllegalArgumentException(
4339                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4340                    }
4341                    intents[i] = new Intent(intent);
4342                }
4343            }
4344            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4345                throw new IllegalArgumentException(
4346                        "Intent array length does not match resolvedTypes length");
4347            }
4348        }
4349        if (options != null) {
4350            if (options.hasFileDescriptors()) {
4351                throw new IllegalArgumentException("File descriptors passed in options");
4352            }
4353        }
4354
4355        synchronized(this) {
4356            int callingUid = Binder.getCallingUid();
4357            try {
4358                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4359                    int uid = AppGlobals.getPackageManager()
4360                            .getPackageUid(packageName, UserId.getUserId(callingUid));
4361                    if (!UserId.isSameApp(callingUid, uid)) {
4362                        String msg = "Permission Denial: getIntentSender() from pid="
4363                            + Binder.getCallingPid()
4364                            + ", uid=" + Binder.getCallingUid()
4365                            + ", (need uid=" + uid + ")"
4366                            + " is not allowed to send as package " + packageName;
4367                        Slog.w(TAG, msg);
4368                        throw new SecurityException(msg);
4369                    }
4370                }
4371
4372                if (DEBUG_MU)
4373                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4374                            + Binder.getOrigCallingUid());
4375                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4376                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4377
4378            } catch (RemoteException e) {
4379                throw new SecurityException(e);
4380            }
4381        }
4382    }
4383
4384    IIntentSender getIntentSenderLocked(int type,
4385            String packageName, int callingUid, IBinder token, String resultWho,
4386            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4387            Bundle options) {
4388        if (DEBUG_MU)
4389            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4390        ActivityRecord activity = null;
4391        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4392            activity = mMainStack.isInStackLocked(token);
4393            if (activity == null) {
4394                return null;
4395            }
4396            if (activity.finishing) {
4397                return null;
4398            }
4399        }
4400
4401        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4402        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4403        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4404        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4405                |PendingIntent.FLAG_UPDATE_CURRENT);
4406
4407        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4408                type, packageName, activity, resultWho,
4409                requestCode, intents, resolvedTypes, flags, options);
4410        WeakReference<PendingIntentRecord> ref;
4411        ref = mIntentSenderRecords.get(key);
4412        PendingIntentRecord rec = ref != null ? ref.get() : null;
4413        if (rec != null) {
4414            if (!cancelCurrent) {
4415                if (updateCurrent) {
4416                    if (rec.key.requestIntent != null) {
4417                        rec.key.requestIntent.replaceExtras(intents != null ?
4418                                intents[intents.length - 1] : null);
4419                    }
4420                    if (intents != null) {
4421                        intents[intents.length-1] = rec.key.requestIntent;
4422                        rec.key.allIntents = intents;
4423                        rec.key.allResolvedTypes = resolvedTypes;
4424                    } else {
4425                        rec.key.allIntents = null;
4426                        rec.key.allResolvedTypes = null;
4427                    }
4428                }
4429                return rec;
4430            }
4431            rec.canceled = true;
4432            mIntentSenderRecords.remove(key);
4433        }
4434        if (noCreate) {
4435            return rec;
4436        }
4437        rec = new PendingIntentRecord(this, key, callingUid);
4438        mIntentSenderRecords.put(key, rec.ref);
4439        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4440            if (activity.pendingResults == null) {
4441                activity.pendingResults
4442                        = new HashSet<WeakReference<PendingIntentRecord>>();
4443            }
4444            activity.pendingResults.add(rec.ref);
4445        }
4446        return rec;
4447    }
4448
4449    public void cancelIntentSender(IIntentSender sender) {
4450        if (!(sender instanceof PendingIntentRecord)) {
4451            return;
4452        }
4453        synchronized(this) {
4454            PendingIntentRecord rec = (PendingIntentRecord)sender;
4455            try {
4456                int uid = AppGlobals.getPackageManager()
4457                        .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
4458                if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
4459                    String msg = "Permission Denial: cancelIntentSender() from pid="
4460                        + Binder.getCallingPid()
4461                        + ", uid=" + Binder.getCallingUid()
4462                        + " is not allowed to cancel packges "
4463                        + rec.key.packageName;
4464                    Slog.w(TAG, msg);
4465                    throw new SecurityException(msg);
4466                }
4467            } catch (RemoteException e) {
4468                throw new SecurityException(e);
4469            }
4470            cancelIntentSenderLocked(rec, true);
4471        }
4472    }
4473
4474    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4475        rec.canceled = true;
4476        mIntentSenderRecords.remove(rec.key);
4477        if (cleanActivity && rec.key.activity != null) {
4478            rec.key.activity.pendingResults.remove(rec.ref);
4479        }
4480    }
4481
4482    public String getPackageForIntentSender(IIntentSender pendingResult) {
4483        if (!(pendingResult instanceof PendingIntentRecord)) {
4484            return null;
4485        }
4486        try {
4487            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4488            return res.key.packageName;
4489        } catch (ClassCastException e) {
4490        }
4491        return null;
4492    }
4493
4494    public int getUidForIntentSender(IIntentSender sender) {
4495        if (sender instanceof PendingIntentRecord) {
4496            try {
4497                PendingIntentRecord res = (PendingIntentRecord)sender;
4498                return res.uid;
4499            } catch (ClassCastException e) {
4500            }
4501        }
4502        return -1;
4503    }
4504
4505    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4506        if (!(pendingResult instanceof PendingIntentRecord)) {
4507            return false;
4508        }
4509        try {
4510            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4511            if (res.key.allIntents == null) {
4512                return false;
4513            }
4514            for (int i=0; i<res.key.allIntents.length; i++) {
4515                Intent intent = res.key.allIntents[i];
4516                if (intent.getPackage() != null && intent.getComponent() != null) {
4517                    return false;
4518                }
4519            }
4520            return true;
4521        } catch (ClassCastException e) {
4522        }
4523        return false;
4524    }
4525
4526    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4527        if (!(pendingResult instanceof PendingIntentRecord)) {
4528            return false;
4529        }
4530        try {
4531            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4532            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4533                return true;
4534            }
4535            return false;
4536        } catch (ClassCastException e) {
4537        }
4538        return false;
4539    }
4540
4541    public void setProcessLimit(int max) {
4542        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4543                "setProcessLimit()");
4544        synchronized (this) {
4545            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4546            mProcessLimitOverride = max;
4547        }
4548        trimApplications();
4549    }
4550
4551    public int getProcessLimit() {
4552        synchronized (this) {
4553            return mProcessLimitOverride;
4554        }
4555    }
4556
4557    void foregroundTokenDied(ForegroundToken token) {
4558        synchronized (ActivityManagerService.this) {
4559            synchronized (mPidsSelfLocked) {
4560                ForegroundToken cur
4561                    = mForegroundProcesses.get(token.pid);
4562                if (cur != token) {
4563                    return;
4564                }
4565                mForegroundProcesses.remove(token.pid);
4566                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4567                if (pr == null) {
4568                    return;
4569                }
4570                pr.forcingToForeground = null;
4571                pr.foregroundServices = false;
4572            }
4573            updateOomAdjLocked();
4574        }
4575    }
4576
4577    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4578        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4579                "setProcessForeground()");
4580        synchronized(this) {
4581            boolean changed = false;
4582
4583            synchronized (mPidsSelfLocked) {
4584                ProcessRecord pr = mPidsSelfLocked.get(pid);
4585                if (pr == null && isForeground) {
4586                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4587                    return;
4588                }
4589                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4590                if (oldToken != null) {
4591                    oldToken.token.unlinkToDeath(oldToken, 0);
4592                    mForegroundProcesses.remove(pid);
4593                    if (pr != null) {
4594                        pr.forcingToForeground = null;
4595                    }
4596                    changed = true;
4597                }
4598                if (isForeground && token != null) {
4599                    ForegroundToken newToken = new ForegroundToken() {
4600                        public void binderDied() {
4601                            foregroundTokenDied(this);
4602                        }
4603                    };
4604                    newToken.pid = pid;
4605                    newToken.token = token;
4606                    try {
4607                        token.linkToDeath(newToken, 0);
4608                        mForegroundProcesses.put(pid, newToken);
4609                        pr.forcingToForeground = token;
4610                        changed = true;
4611                    } catch (RemoteException e) {
4612                        // If the process died while doing this, we will later
4613                        // do the cleanup with the process death link.
4614                    }
4615                }
4616            }
4617
4618            if (changed) {
4619                updateOomAdjLocked();
4620            }
4621        }
4622    }
4623
4624    // =========================================================
4625    // PERMISSIONS
4626    // =========================================================
4627
4628    static class PermissionController extends IPermissionController.Stub {
4629        ActivityManagerService mActivityManagerService;
4630        PermissionController(ActivityManagerService activityManagerService) {
4631            mActivityManagerService = activityManagerService;
4632        }
4633
4634        public boolean checkPermission(String permission, int pid, int uid) {
4635            return mActivityManagerService.checkPermission(permission, pid,
4636                    uid) == PackageManager.PERMISSION_GRANTED;
4637        }
4638    }
4639
4640    /**
4641     * This can be called with or without the global lock held.
4642     */
4643    int checkComponentPermission(String permission, int pid, int uid,
4644            int owningUid, boolean exported) {
4645        // We might be performing an operation on behalf of an indirect binder
4646        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4647        // client identity accordingly before proceeding.
4648        Identity tlsIdentity = sCallerIdentity.get();
4649        if (tlsIdentity != null) {
4650            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4651                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4652            uid = tlsIdentity.uid;
4653            pid = tlsIdentity.pid;
4654        }
4655
4656        if (pid == MY_PID) {
4657            return PackageManager.PERMISSION_GRANTED;
4658        }
4659
4660        return ActivityManager.checkComponentPermission(permission, uid,
4661                owningUid, exported);
4662    }
4663
4664    /**
4665     * As the only public entry point for permissions checking, this method
4666     * can enforce the semantic that requesting a check on a null global
4667     * permission is automatically denied.  (Internally a null permission
4668     * string is used when calling {@link #checkComponentPermission} in cases
4669     * when only uid-based security is needed.)
4670     *
4671     * This can be called with or without the global lock held.
4672     */
4673    public int checkPermission(String permission, int pid, int uid) {
4674        if (permission == null) {
4675            return PackageManager.PERMISSION_DENIED;
4676        }
4677        return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
4678    }
4679
4680    /**
4681     * Binder IPC calls go through the public entry point.
4682     * This can be called with or without the global lock held.
4683     */
4684    int checkCallingPermission(String permission) {
4685        return checkPermission(permission,
4686                Binder.getCallingPid(),
4687                UserId.getAppId(Binder.getCallingUid()));
4688    }
4689
4690    /**
4691     * This can be called with or without the global lock held.
4692     */
4693    void enforceCallingPermission(String permission, String func) {
4694        if (checkCallingPermission(permission)
4695                == PackageManager.PERMISSION_GRANTED) {
4696            return;
4697        }
4698
4699        String msg = "Permission Denial: " + func + " from pid="
4700                + Binder.getCallingPid()
4701                + ", uid=" + Binder.getCallingUid()
4702                + " requires " + permission;
4703        Slog.w(TAG, msg);
4704        throw new SecurityException(msg);
4705    }
4706
4707    /**
4708     * Determine if UID is holding permissions required to access {@link Uri} in
4709     * the given {@link ProviderInfo}. Final permission checking is always done
4710     * in {@link ContentProvider}.
4711     */
4712    private final boolean checkHoldingPermissionsLocked(
4713            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4714        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4715                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4716
4717        if (pi.applicationInfo.uid == uid) {
4718            return true;
4719        } else if (!pi.exported) {
4720            return false;
4721        }
4722
4723        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4724        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4725        try {
4726            // check if target holds top-level <provider> permissions
4727            if (!readMet && pi.readPermission != null
4728                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4729                readMet = true;
4730            }
4731            if (!writeMet && pi.writePermission != null
4732                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4733                writeMet = true;
4734            }
4735
4736            // track if unprotected read/write is allowed; any denied
4737            // <path-permission> below removes this ability
4738            boolean allowDefaultRead = pi.readPermission == null;
4739            boolean allowDefaultWrite = pi.writePermission == null;
4740
4741            // check if target holds any <path-permission> that match uri
4742            final PathPermission[] pps = pi.pathPermissions;
4743            if (pps != null) {
4744                final String path = uri.getPath();
4745                int i = pps.length;
4746                while (i > 0 && (!readMet || !writeMet)) {
4747                    i--;
4748                    PathPermission pp = pps[i];
4749                    if (pp.match(path)) {
4750                        if (!readMet) {
4751                            final String pprperm = pp.getReadPermission();
4752                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4753                                    + pprperm + " for " + pp.getPath()
4754                                    + ": match=" + pp.match(path)
4755                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4756                            if (pprperm != null) {
4757                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4758                                    readMet = true;
4759                                } else {
4760                                    allowDefaultRead = false;
4761                                }
4762                            }
4763                        }
4764                        if (!writeMet) {
4765                            final String ppwperm = pp.getWritePermission();
4766                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4767                                    + ppwperm + " for " + pp.getPath()
4768                                    + ": match=" + pp.match(path)
4769                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4770                            if (ppwperm != null) {
4771                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4772                                    writeMet = true;
4773                                } else {
4774                                    allowDefaultWrite = false;
4775                                }
4776                            }
4777                        }
4778                    }
4779                }
4780            }
4781
4782            // grant unprotected <provider> read/write, if not blocked by
4783            // <path-permission> above
4784            if (allowDefaultRead) readMet = true;
4785            if (allowDefaultWrite) writeMet = true;
4786
4787        } catch (RemoteException e) {
4788            return false;
4789        }
4790
4791        return readMet && writeMet;
4792    }
4793
4794    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4795            int modeFlags) {
4796        // Root gets to do everything.
4797        if (uid == 0) {
4798            return true;
4799        }
4800        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4801        if (perms == null) return false;
4802        UriPermission perm = perms.get(uri);
4803        if (perm == null) return false;
4804        return (modeFlags&perm.modeFlags) == modeFlags;
4805    }
4806
4807    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4808        enforceNotIsolatedCaller("checkUriPermission");
4809
4810        // Another redirected-binder-call permissions check as in
4811        // {@link checkComponentPermission}.
4812        Identity tlsIdentity = sCallerIdentity.get();
4813        if (tlsIdentity != null) {
4814            uid = tlsIdentity.uid;
4815            pid = tlsIdentity.pid;
4816        }
4817
4818        uid = UserId.getAppId(uid);
4819        // Our own process gets to do everything.
4820        if (pid == MY_PID) {
4821            return PackageManager.PERMISSION_GRANTED;
4822        }
4823        synchronized(this) {
4824            return checkUriPermissionLocked(uri, uid, modeFlags)
4825                    ? PackageManager.PERMISSION_GRANTED
4826                    : PackageManager.PERMISSION_DENIED;
4827        }
4828    }
4829
4830    /**
4831     * Check if the targetPkg can be granted permission to access uri by
4832     * the callingUid using the given modeFlags.  Throws a security exception
4833     * if callingUid is not allowed to do this.  Returns the uid of the target
4834     * if the URI permission grant should be performed; returns -1 if it is not
4835     * needed (for example targetPkg already has permission to access the URI).
4836     * If you already know the uid of the target, you can supply it in
4837     * lastTargetUid else set that to -1.
4838     */
4839    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4840            Uri uri, int modeFlags, int lastTargetUid) {
4841        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4842                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4843        if (modeFlags == 0) {
4844            return -1;
4845        }
4846
4847        if (targetPkg != null) {
4848            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4849                    "Checking grant " + targetPkg + " permission to " + uri);
4850        }
4851
4852        final IPackageManager pm = AppGlobals.getPackageManager();
4853
4854        // If this is not a content: uri, we can't do anything with it.
4855        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4856            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4857                    "Can't grant URI permission for non-content URI: " + uri);
4858            return -1;
4859        }
4860
4861        String name = uri.getAuthority();
4862        ProviderInfo pi = null;
4863        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4864                UserId.getUserId(callingUid));
4865        if (cpr != null) {
4866            pi = cpr.info;
4867        } else {
4868            try {
4869                pi = pm.resolveContentProvider(name,
4870                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
4871            } catch (RemoteException ex) {
4872            }
4873        }
4874        if (pi == null) {
4875            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4876            return -1;
4877        }
4878
4879        int targetUid = lastTargetUid;
4880        if (targetUid < 0 && targetPkg != null) {
4881            try {
4882                targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
4883                if (targetUid < 0) {
4884                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4885                            "Can't grant URI permission no uid for: " + targetPkg);
4886                    return -1;
4887                }
4888            } catch (RemoteException ex) {
4889                return -1;
4890            }
4891        }
4892
4893        if (targetUid >= 0) {
4894            // First...  does the target actually need this permission?
4895            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4896                // No need to grant the target this permission.
4897                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4898                        "Target " + targetPkg + " already has full permission to " + uri);
4899                return -1;
4900            }
4901        } else {
4902            // First...  there is no target package, so can anyone access it?
4903            boolean allowed = pi.exported;
4904            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4905                if (pi.readPermission != null) {
4906                    allowed = false;
4907                }
4908            }
4909            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4910                if (pi.writePermission != null) {
4911                    allowed = false;
4912                }
4913            }
4914            if (allowed) {
4915                return -1;
4916            }
4917        }
4918
4919        // Second...  is the provider allowing granting of URI permissions?
4920        if (!pi.grantUriPermissions) {
4921            throw new SecurityException("Provider " + pi.packageName
4922                    + "/" + pi.name
4923                    + " does not allow granting of Uri permissions (uri "
4924                    + uri + ")");
4925        }
4926        if (pi.uriPermissionPatterns != null) {
4927            final int N = pi.uriPermissionPatterns.length;
4928            boolean allowed = false;
4929            for (int i=0; i<N; i++) {
4930                if (pi.uriPermissionPatterns[i] != null
4931                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4932                    allowed = true;
4933                    break;
4934                }
4935            }
4936            if (!allowed) {
4937                throw new SecurityException("Provider " + pi.packageName
4938                        + "/" + pi.name
4939                        + " does not allow granting of permission to path of Uri "
4940                        + uri);
4941            }
4942        }
4943
4944        // Third...  does the caller itself have permission to access
4945        // this uri?
4946        if (callingUid != Process.myUid()) {
4947            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4948                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4949                    throw new SecurityException("Uid " + callingUid
4950                            + " does not have permission to uri " + uri);
4951                }
4952            }
4953        }
4954
4955        return targetUid;
4956    }
4957
4958    public int checkGrantUriPermission(int callingUid, String targetPkg,
4959            Uri uri, int modeFlags) {
4960        enforceNotIsolatedCaller("checkGrantUriPermission");
4961        synchronized(this) {
4962            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4963        }
4964    }
4965
4966    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4967            Uri uri, int modeFlags, UriPermissionOwner owner) {
4968        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4969                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4970        if (modeFlags == 0) {
4971            return;
4972        }
4973
4974        // So here we are: the caller has the assumed permission
4975        // to the uri, and the target doesn't.  Let's now give this to
4976        // the target.
4977
4978        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4979                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4980
4981        HashMap<Uri, UriPermission> targetUris
4982                = mGrantedUriPermissions.get(targetUid);
4983        if (targetUris == null) {
4984            targetUris = new HashMap<Uri, UriPermission>();
4985            mGrantedUriPermissions.put(targetUid, targetUris);
4986        }
4987
4988        UriPermission perm = targetUris.get(uri);
4989        if (perm == null) {
4990            perm = new UriPermission(targetUid, uri);
4991            targetUris.put(uri, perm);
4992        }
4993
4994        perm.modeFlags |= modeFlags;
4995        if (owner == null) {
4996            perm.globalModeFlags |= modeFlags;
4997        } else {
4998            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4999                 perm.readOwners.add(owner);
5000                 owner.addReadPermission(perm);
5001            }
5002            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5003                 perm.writeOwners.add(owner);
5004                 owner.addWritePermission(perm);
5005            }
5006        }
5007    }
5008
5009    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5010            int modeFlags, UriPermissionOwner owner) {
5011        if (targetPkg == null) {
5012            throw new NullPointerException("targetPkg");
5013        }
5014
5015        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5016        if (targetUid < 0) {
5017            return;
5018        }
5019
5020        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5021    }
5022
5023    static class NeededUriGrants extends ArrayList<Uri> {
5024        final String targetPkg;
5025        final int targetUid;
5026        final int flags;
5027
5028        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5029            targetPkg = _targetPkg;
5030            targetUid = _targetUid;
5031            flags = _flags;
5032        }
5033    }
5034
5035    /**
5036     * Like checkGrantUriPermissionLocked, but takes an Intent.
5037     */
5038    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5039            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5040        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5041                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5042                + " clip=" + (intent != null ? intent.getClipData() : null)
5043                + " from " + intent + "; flags=0x"
5044                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5045
5046        if (targetPkg == null) {
5047            throw new NullPointerException("targetPkg");
5048        }
5049
5050        if (intent == null) {
5051            return null;
5052        }
5053        Uri data = intent.getData();
5054        ClipData clip = intent.getClipData();
5055        if (data == null && clip == null) {
5056            return null;
5057        }
5058        if (data != null) {
5059            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5060                mode, needed != null ? needed.targetUid : -1);
5061            if (target > 0) {
5062                if (needed == null) {
5063                    needed = new NeededUriGrants(targetPkg, target, mode);
5064                }
5065                needed.add(data);
5066            }
5067        }
5068        if (clip != null) {
5069            for (int i=0; i<clip.getItemCount(); i++) {
5070                Uri uri = clip.getItemAt(i).getUri();
5071                if (uri != null) {
5072                    int target = -1;
5073                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5074                            mode, needed != null ? needed.targetUid : -1);
5075                    if (target > 0) {
5076                        if (needed == null) {
5077                            needed = new NeededUriGrants(targetPkg, target, mode);
5078                        }
5079                        needed.add(uri);
5080                    }
5081                } else {
5082                    Intent clipIntent = clip.getItemAt(i).getIntent();
5083                    if (clipIntent != null) {
5084                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5085                                callingUid, targetPkg, clipIntent, mode, needed);
5086                        if (newNeeded != null) {
5087                            needed = newNeeded;
5088                        }
5089                    }
5090                }
5091            }
5092        }
5093
5094        return needed;
5095    }
5096
5097    /**
5098     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5099     */
5100    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5101            UriPermissionOwner owner) {
5102        if (needed != null) {
5103            for (int i=0; i<needed.size(); i++) {
5104                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5105                        needed.get(i), needed.flags, owner);
5106            }
5107        }
5108    }
5109
5110    void grantUriPermissionFromIntentLocked(int callingUid,
5111            String targetPkg, Intent intent, UriPermissionOwner owner) {
5112        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5113                intent, intent != null ? intent.getFlags() : 0, null);
5114        if (needed == null) {
5115            return;
5116        }
5117
5118        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5119    }
5120
5121    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5122            Uri uri, int modeFlags) {
5123        enforceNotIsolatedCaller("grantUriPermission");
5124        synchronized(this) {
5125            final ProcessRecord r = getRecordForAppLocked(caller);
5126            if (r == null) {
5127                throw new SecurityException("Unable to find app for caller "
5128                        + caller
5129                        + " when granting permission to uri " + uri);
5130            }
5131            if (targetPkg == null) {
5132                throw new IllegalArgumentException("null target");
5133            }
5134            if (uri == null) {
5135                throw new IllegalArgumentException("null uri");
5136            }
5137
5138            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5139                    null);
5140        }
5141    }
5142
5143    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5144        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5145                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5146            HashMap<Uri, UriPermission> perms
5147                    = mGrantedUriPermissions.get(perm.uid);
5148            if (perms != null) {
5149                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5150                        "Removing " + perm.uid + " permission to " + perm.uri);
5151                perms.remove(perm.uri);
5152                if (perms.size() == 0) {
5153                    mGrantedUriPermissions.remove(perm.uid);
5154                }
5155            }
5156        }
5157    }
5158
5159    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5160            int modeFlags) {
5161        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5162                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5163        if (modeFlags == 0) {
5164            return;
5165        }
5166
5167        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5168                "Revoking all granted permissions to " + uri);
5169
5170        final IPackageManager pm = AppGlobals.getPackageManager();
5171
5172        final String authority = uri.getAuthority();
5173        ProviderInfo pi = null;
5174        int userId = UserId.getUserId(callingUid);
5175        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5176        if (cpr != null) {
5177            pi = cpr.info;
5178        } else {
5179            try {
5180                pi = pm.resolveContentProvider(authority,
5181                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5182            } catch (RemoteException ex) {
5183            }
5184        }
5185        if (pi == null) {
5186            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5187            return;
5188        }
5189
5190        // Does the caller have this permission on the URI?
5191        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5192            // Right now, if you are not the original owner of the permission,
5193            // you are not allowed to revoke it.
5194            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5195                throw new SecurityException("Uid " + callingUid
5196                        + " does not have permission to uri " + uri);
5197            //}
5198        }
5199
5200        // Go through all of the permissions and remove any that match.
5201        final List<String> SEGMENTS = uri.getPathSegments();
5202        if (SEGMENTS != null) {
5203            final int NS = SEGMENTS.size();
5204            int N = mGrantedUriPermissions.size();
5205            for (int i=0; i<N; i++) {
5206                HashMap<Uri, UriPermission> perms
5207                        = mGrantedUriPermissions.valueAt(i);
5208                Iterator<UriPermission> it = perms.values().iterator();
5209            toploop:
5210                while (it.hasNext()) {
5211                    UriPermission perm = it.next();
5212                    Uri targetUri = perm.uri;
5213                    if (!authority.equals(targetUri.getAuthority())) {
5214                        continue;
5215                    }
5216                    List<String> targetSegments = targetUri.getPathSegments();
5217                    if (targetSegments == null) {
5218                        continue;
5219                    }
5220                    if (targetSegments.size() < NS) {
5221                        continue;
5222                    }
5223                    for (int j=0; j<NS; j++) {
5224                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5225                            continue toploop;
5226                        }
5227                    }
5228                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5229                            "Revoking " + perm.uid + " permission to " + perm.uri);
5230                    perm.clearModes(modeFlags);
5231                    if (perm.modeFlags == 0) {
5232                        it.remove();
5233                    }
5234                }
5235                if (perms.size() == 0) {
5236                    mGrantedUriPermissions.remove(
5237                            mGrantedUriPermissions.keyAt(i));
5238                    N--;
5239                    i--;
5240                }
5241            }
5242        }
5243    }
5244
5245    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5246            int modeFlags) {
5247        enforceNotIsolatedCaller("revokeUriPermission");
5248        synchronized(this) {
5249            final ProcessRecord r = getRecordForAppLocked(caller);
5250            if (r == null) {
5251                throw new SecurityException("Unable to find app for caller "
5252                        + caller
5253                        + " when revoking permission to uri " + uri);
5254            }
5255            if (uri == null) {
5256                Slog.w(TAG, "revokeUriPermission: null uri");
5257                return;
5258            }
5259
5260            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5261                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5262            if (modeFlags == 0) {
5263                return;
5264            }
5265
5266            final IPackageManager pm = AppGlobals.getPackageManager();
5267
5268            final String authority = uri.getAuthority();
5269            ProviderInfo pi = null;
5270            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5271            if (cpr != null) {
5272                pi = cpr.info;
5273            } else {
5274                try {
5275                    pi = pm.resolveContentProvider(authority,
5276                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5277                } catch (RemoteException ex) {
5278                }
5279            }
5280            if (pi == null) {
5281                Slog.w(TAG, "No content provider found for permission revoke: "
5282                        + uri.toSafeString());
5283                return;
5284            }
5285
5286            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5287        }
5288    }
5289
5290    @Override
5291    public IBinder newUriPermissionOwner(String name) {
5292        enforceNotIsolatedCaller("newUriPermissionOwner");
5293        synchronized(this) {
5294            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5295            return owner.getExternalTokenLocked();
5296        }
5297    }
5298
5299    @Override
5300    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5301            Uri uri, int modeFlags) {
5302        synchronized(this) {
5303            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5304            if (owner == null) {
5305                throw new IllegalArgumentException("Unknown owner: " + token);
5306            }
5307            if (fromUid != Binder.getCallingUid()) {
5308                if (Binder.getCallingUid() != Process.myUid()) {
5309                    // Only system code can grant URI permissions on behalf
5310                    // of other users.
5311                    throw new SecurityException("nice try");
5312                }
5313            }
5314            if (targetPkg == null) {
5315                throw new IllegalArgumentException("null target");
5316            }
5317            if (uri == null) {
5318                throw new IllegalArgumentException("null uri");
5319            }
5320
5321            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5322        }
5323    }
5324
5325    @Override
5326    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5327        synchronized(this) {
5328            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5329            if (owner == null) {
5330                throw new IllegalArgumentException("Unknown owner: " + token);
5331            }
5332
5333            if (uri == null) {
5334                owner.removeUriPermissionsLocked(mode);
5335            } else {
5336                owner.removeUriPermissionLocked(uri, mode);
5337            }
5338        }
5339    }
5340
5341    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5342        synchronized (this) {
5343            ProcessRecord app =
5344                who != null ? getRecordForAppLocked(who) : null;
5345            if (app == null) return;
5346
5347            Message msg = Message.obtain();
5348            msg.what = WAIT_FOR_DEBUGGER_MSG;
5349            msg.obj = app;
5350            msg.arg1 = waiting ? 1 : 0;
5351            mHandler.sendMessage(msg);
5352        }
5353    }
5354
5355    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5356        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5357        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5358        outInfo.availMem = Process.getFreeMemory();
5359        outInfo.totalMem = Process.getTotalMemory();
5360        outInfo.threshold = homeAppMem;
5361        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5362        outInfo.hiddenAppThreshold = hiddenAppMem;
5363        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5364                ProcessList.SERVICE_ADJ);
5365        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5366                ProcessList.VISIBLE_APP_ADJ);
5367        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5368                ProcessList.FOREGROUND_APP_ADJ);
5369    }
5370
5371    // =========================================================
5372    // TASK MANAGEMENT
5373    // =========================================================
5374
5375    public List getTasks(int maxNum, int flags,
5376                         IThumbnailReceiver receiver) {
5377        ArrayList list = new ArrayList();
5378
5379        PendingThumbnailsRecord pending = null;
5380        IApplicationThread topThumbnail = null;
5381        ActivityRecord topRecord = null;
5382
5383        synchronized(this) {
5384            if (localLOGV) Slog.v(
5385                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5386                + ", receiver=" + receiver);
5387
5388            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5389                    != PackageManager.PERMISSION_GRANTED) {
5390                if (receiver != null) {
5391                    // If the caller wants to wait for pending thumbnails,
5392                    // it ain't gonna get them.
5393                    try {
5394                        receiver.finished();
5395                    } catch (RemoteException ex) {
5396                    }
5397                }
5398                String msg = "Permission Denial: getTasks() from pid="
5399                        + Binder.getCallingPid()
5400                        + ", uid=" + Binder.getCallingUid()
5401                        + " requires " + android.Manifest.permission.GET_TASKS;
5402                Slog.w(TAG, msg);
5403                throw new SecurityException(msg);
5404            }
5405
5406            int pos = mMainStack.mHistory.size()-1;
5407            ActivityRecord next =
5408                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5409            ActivityRecord top = null;
5410            TaskRecord curTask = null;
5411            int numActivities = 0;
5412            int numRunning = 0;
5413            while (pos >= 0 && maxNum > 0) {
5414                final ActivityRecord r = next;
5415                pos--;
5416                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5417
5418                // Initialize state for next task if needed.
5419                if (top == null ||
5420                        (top.state == ActivityState.INITIALIZING
5421                            && top.task == r.task)) {
5422                    top = r;
5423                    curTask = r.task;
5424                    numActivities = numRunning = 0;
5425                }
5426
5427                // Add 'r' into the current task.
5428                numActivities++;
5429                if (r.app != null && r.app.thread != null) {
5430                    numRunning++;
5431                }
5432
5433                if (localLOGV) Slog.v(
5434                    TAG, r.intent.getComponent().flattenToShortString()
5435                    + ": task=" + r.task);
5436
5437                // If the next one is a different task, generate a new
5438                // TaskInfo entry for what we have.
5439                if (next == null || next.task != curTask) {
5440                    ActivityManager.RunningTaskInfo ci
5441                            = new ActivityManager.RunningTaskInfo();
5442                    ci.id = curTask.taskId;
5443                    ci.baseActivity = r.intent.getComponent();
5444                    ci.topActivity = top.intent.getComponent();
5445                    if (top.thumbHolder != null) {
5446                        ci.description = top.thumbHolder.lastDescription;
5447                    }
5448                    ci.numActivities = numActivities;
5449                    ci.numRunning = numRunning;
5450                    //System.out.println(
5451                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5452                    if (ci.thumbnail == null && receiver != null) {
5453                        if (localLOGV) Slog.v(
5454                            TAG, "State=" + top.state + "Idle=" + top.idle
5455                            + " app=" + top.app
5456                            + " thr=" + (top.app != null ? top.app.thread : null));
5457                        if (top.state == ActivityState.RESUMED
5458                                || top.state == ActivityState.PAUSING) {
5459                            if (top.idle && top.app != null
5460                                && top.app.thread != null) {
5461                                topRecord = top;
5462                                topThumbnail = top.app.thread;
5463                            } else {
5464                                top.thumbnailNeeded = true;
5465                            }
5466                        }
5467                        if (pending == null) {
5468                            pending = new PendingThumbnailsRecord(receiver);
5469                        }
5470                        pending.pendingRecords.add(top);
5471                    }
5472                    list.add(ci);
5473                    maxNum--;
5474                    top = null;
5475                }
5476            }
5477
5478            if (pending != null) {
5479                mPendingThumbnails.add(pending);
5480            }
5481        }
5482
5483        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5484
5485        if (topThumbnail != null) {
5486            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5487            try {
5488                topThumbnail.requestThumbnail(topRecord.appToken);
5489            } catch (Exception e) {
5490                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5491                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5492            }
5493        }
5494
5495        if (pending == null && receiver != null) {
5496            // In this case all thumbnails were available and the client
5497            // is being asked to be told when the remaining ones come in...
5498            // which is unusually, since the top-most currently running
5499            // activity should never have a canned thumbnail!  Oh well.
5500            try {
5501                receiver.finished();
5502            } catch (RemoteException ex) {
5503            }
5504        }
5505
5506        return list;
5507    }
5508
5509    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5510            int flags, int userId) {
5511        final int callingUid = Binder.getCallingUid();
5512        if (userId != UserId.getCallingUserId()) {
5513            // Check if the caller is holding permissions for cross-user requests.
5514            if (checkComponentPermission(
5515                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5516                    Binder.getCallingPid(), callingUid, -1, true)
5517                    != PackageManager.PERMISSION_GRANTED) {
5518                String msg = "Permission Denial: "
5519                        + "Request to get recent tasks for user " + userId
5520                        + " but is calling from user " + UserId.getUserId(callingUid)
5521                        + "; this requires "
5522                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5523                Slog.w(TAG, msg);
5524                throw new SecurityException(msg);
5525            } else {
5526                if (userId == UserId.USER_CURRENT) {
5527                    userId = mCurrentUserId;
5528                }
5529            }
5530        }
5531
5532        synchronized (this) {
5533            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5534                    "getRecentTasks()");
5535            final boolean detailed = checkCallingPermission(
5536                    android.Manifest.permission.GET_DETAILED_TASKS)
5537                    == PackageManager.PERMISSION_GRANTED;
5538
5539            IPackageManager pm = AppGlobals.getPackageManager();
5540
5541            final int N = mRecentTasks.size();
5542            ArrayList<ActivityManager.RecentTaskInfo> res
5543                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5544                            maxNum < N ? maxNum : N);
5545            for (int i=0; i<N && maxNum > 0; i++) {
5546                TaskRecord tr = mRecentTasks.get(i);
5547                // Only add calling user's recent tasks
5548                if (tr.userId != userId) continue;
5549                // Return the entry if desired by the caller.  We always return
5550                // the first entry, because callers always expect this to be the
5551                // foreground app.  We may filter others if the caller has
5552                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5553                // we should exclude the entry.
5554
5555                if (i == 0
5556                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5557                        || (tr.intent == null)
5558                        || ((tr.intent.getFlags()
5559                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5560                    ActivityManager.RecentTaskInfo rti
5561                            = new ActivityManager.RecentTaskInfo();
5562                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5563                    rti.persistentId = tr.taskId;
5564                    rti.baseIntent = new Intent(
5565                            tr.intent != null ? tr.intent : tr.affinityIntent);
5566                    if (!detailed) {
5567                        rti.baseIntent.replaceExtras((Bundle)null);
5568                    }
5569                    rti.origActivity = tr.origActivity;
5570                    rti.description = tr.lastDescription;
5571
5572                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5573                        // Check whether this activity is currently available.
5574                        try {
5575                            if (rti.origActivity != null) {
5576                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5577                                        == null) {
5578                                    continue;
5579                                }
5580                            } else if (rti.baseIntent != null) {
5581                                if (pm.queryIntentActivities(rti.baseIntent,
5582                                        null, 0, userId) == null) {
5583                                    continue;
5584                                }
5585                            }
5586                        } catch (RemoteException e) {
5587                            // Will never happen.
5588                        }
5589                    }
5590
5591                    res.add(rti);
5592                    maxNum--;
5593                }
5594            }
5595            return res;
5596        }
5597    }
5598
5599    private TaskRecord taskForIdLocked(int id) {
5600        final int N = mRecentTasks.size();
5601        for (int i=0; i<N; i++) {
5602            TaskRecord tr = mRecentTasks.get(i);
5603            if (tr.taskId == id) {
5604                return tr;
5605            }
5606        }
5607        return null;
5608    }
5609
5610    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5611        synchronized (this) {
5612            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5613                    "getTaskThumbnails()");
5614            TaskRecord tr = taskForIdLocked(id);
5615            if (tr != null) {
5616                return mMainStack.getTaskThumbnailsLocked(tr);
5617            }
5618        }
5619        return null;
5620    }
5621
5622    public boolean removeSubTask(int taskId, int subTaskIndex) {
5623        synchronized (this) {
5624            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5625                    "removeSubTask()");
5626            long ident = Binder.clearCallingIdentity();
5627            try {
5628                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5629                        true) != null;
5630            } finally {
5631                Binder.restoreCallingIdentity(ident);
5632            }
5633        }
5634    }
5635
5636    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5637        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5638        Intent baseIntent = new Intent(
5639                tr.intent != null ? tr.intent : tr.affinityIntent);
5640        ComponentName component = baseIntent.getComponent();
5641        if (component == null) {
5642            Slog.w(TAG, "Now component for base intent of task: " + tr);
5643            return;
5644        }
5645
5646        // Find any running services associated with this app.
5647        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5648
5649        if (killProcesses) {
5650            // Find any running processes associated with this app.
5651            final String pkg = component.getPackageName();
5652            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5653            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5654            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5655                for (int i=0; i<uids.size(); i++) {
5656                    ProcessRecord proc = uids.valueAt(i);
5657                    if (proc.userId != tr.userId) {
5658                        continue;
5659                    }
5660                    if (!proc.pkgList.contains(pkg)) {
5661                        continue;
5662                    }
5663                    procs.add(proc);
5664                }
5665            }
5666
5667            // Kill the running processes.
5668            for (int i=0; i<procs.size(); i++) {
5669                ProcessRecord pr = procs.get(i);
5670                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5671                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5672                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5673                            pr.processName, pr.setAdj, "remove task");
5674                    pr.killedBackground = true;
5675                    Process.killProcessQuiet(pr.pid);
5676                } else {
5677                    pr.waitingToKill = "remove task";
5678                }
5679            }
5680        }
5681    }
5682
5683    public boolean removeTask(int taskId, int flags) {
5684        synchronized (this) {
5685            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5686                    "removeTask()");
5687            long ident = Binder.clearCallingIdentity();
5688            try {
5689                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5690                        false);
5691                if (r != null) {
5692                    mRecentTasks.remove(r.task);
5693                    cleanUpRemovedTaskLocked(r.task, flags);
5694                    return true;
5695                } else {
5696                    TaskRecord tr = null;
5697                    int i=0;
5698                    while (i < mRecentTasks.size()) {
5699                        TaskRecord t = mRecentTasks.get(i);
5700                        if (t.taskId == taskId) {
5701                            tr = t;
5702                            break;
5703                        }
5704                        i++;
5705                    }
5706                    if (tr != null) {
5707                        if (tr.numActivities <= 0) {
5708                            // Caller is just removing a recent task that is
5709                            // not actively running.  That is easy!
5710                            mRecentTasks.remove(i);
5711                            cleanUpRemovedTaskLocked(tr, flags);
5712                            return true;
5713                        } else {
5714                            Slog.w(TAG, "removeTask: task " + taskId
5715                                    + " does not have activities to remove, "
5716                                    + " but numActivities=" + tr.numActivities
5717                                    + ": " + tr);
5718                        }
5719                    }
5720                }
5721            } finally {
5722                Binder.restoreCallingIdentity(ident);
5723            }
5724        }
5725        return false;
5726    }
5727
5728    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5729        int j;
5730        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5731        TaskRecord jt = startTask;
5732
5733        // First look backwards
5734        for (j=startIndex-1; j>=0; j--) {
5735            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5736            if (r.task != jt) {
5737                jt = r.task;
5738                if (affinity.equals(jt.affinity)) {
5739                    return j;
5740                }
5741            }
5742        }
5743
5744        // Now look forwards
5745        final int N = mMainStack.mHistory.size();
5746        jt = startTask;
5747        for (j=startIndex+1; j<N; j++) {
5748            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5749            if (r.task != jt) {
5750                if (affinity.equals(jt.affinity)) {
5751                    return j;
5752                }
5753                jt = r.task;
5754            }
5755        }
5756
5757        // Might it be at the top?
5758        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5759            return N-1;
5760        }
5761
5762        return -1;
5763    }
5764
5765    /**
5766     * TODO: Add mController hook
5767     */
5768    public void moveTaskToFront(int task, int flags, Bundle options) {
5769        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5770                "moveTaskToFront()");
5771
5772        synchronized(this) {
5773            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5774                    Binder.getCallingUid(), "Task to front")) {
5775                ActivityOptions.abort(options);
5776                return;
5777            }
5778            final long origId = Binder.clearCallingIdentity();
5779            try {
5780                TaskRecord tr = taskForIdLocked(task);
5781                if (tr != null) {
5782                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5783                        mMainStack.mUserLeaving = true;
5784                    }
5785                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5786                        // Caller wants the home activity moved with it.  To accomplish this,
5787                        // we'll just move the home task to the top first.
5788                        mMainStack.moveHomeToFrontLocked();
5789                    }
5790                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5791                    return;
5792                }
5793                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5794                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5795                    if (hr.task.taskId == task) {
5796                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5797                            mMainStack.mUserLeaving = true;
5798                        }
5799                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5800                            // Caller wants the home activity moved with it.  To accomplish this,
5801                            // we'll just move the home task to the top first.
5802                            mMainStack.moveHomeToFrontLocked();
5803                        }
5804                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5805                        return;
5806                    }
5807                }
5808            } finally {
5809                Binder.restoreCallingIdentity(origId);
5810            }
5811            ActivityOptions.abort(options);
5812        }
5813    }
5814
5815    public void moveTaskToBack(int task) {
5816        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5817                "moveTaskToBack()");
5818
5819        synchronized(this) {
5820            if (mMainStack.mResumedActivity != null
5821                    && mMainStack.mResumedActivity.task.taskId == task) {
5822                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5823                        Binder.getCallingUid(), "Task to back")) {
5824                    return;
5825                }
5826            }
5827            final long origId = Binder.clearCallingIdentity();
5828            mMainStack.moveTaskToBackLocked(task, null);
5829            Binder.restoreCallingIdentity(origId);
5830        }
5831    }
5832
5833    /**
5834     * Moves an activity, and all of the other activities within the same task, to the bottom
5835     * of the history stack.  The activity's order within the task is unchanged.
5836     *
5837     * @param token A reference to the activity we wish to move
5838     * @param nonRoot If false then this only works if the activity is the root
5839     *                of a task; if true it will work for any activity in a task.
5840     * @return Returns true if the move completed, false if not.
5841     */
5842    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5843        enforceNotIsolatedCaller("moveActivityTaskToBack");
5844        synchronized(this) {
5845            final long origId = Binder.clearCallingIdentity();
5846            int taskId = getTaskForActivityLocked(token, !nonRoot);
5847            if (taskId >= 0) {
5848                return mMainStack.moveTaskToBackLocked(taskId, null);
5849            }
5850            Binder.restoreCallingIdentity(origId);
5851        }
5852        return false;
5853    }
5854
5855    public void moveTaskBackwards(int task) {
5856        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5857                "moveTaskBackwards()");
5858
5859        synchronized(this) {
5860            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5861                    Binder.getCallingUid(), "Task backwards")) {
5862                return;
5863            }
5864            final long origId = Binder.clearCallingIdentity();
5865            moveTaskBackwardsLocked(task);
5866            Binder.restoreCallingIdentity(origId);
5867        }
5868    }
5869
5870    private final void moveTaskBackwardsLocked(int task) {
5871        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5872    }
5873
5874    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5875        synchronized(this) {
5876            return getTaskForActivityLocked(token, onlyRoot);
5877        }
5878    }
5879
5880    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5881        final int N = mMainStack.mHistory.size();
5882        TaskRecord lastTask = null;
5883        for (int i=0; i<N; i++) {
5884            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5885            if (r.appToken == token) {
5886                if (!onlyRoot || lastTask != r.task) {
5887                    return r.task.taskId;
5888                }
5889                return -1;
5890            }
5891            lastTask = r.task;
5892        }
5893
5894        return -1;
5895    }
5896
5897    // =========================================================
5898    // THUMBNAILS
5899    // =========================================================
5900
5901    public void reportThumbnail(IBinder token,
5902            Bitmap thumbnail, CharSequence description) {
5903        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5904        final long origId = Binder.clearCallingIdentity();
5905        sendPendingThumbnail(null, token, thumbnail, description, true);
5906        Binder.restoreCallingIdentity(origId);
5907    }
5908
5909    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5910            Bitmap thumbnail, CharSequence description, boolean always) {
5911        TaskRecord task = null;
5912        ArrayList receivers = null;
5913
5914        //System.out.println("Send pending thumbnail: " + r);
5915
5916        synchronized(this) {
5917            if (r == null) {
5918                r = mMainStack.isInStackLocked(token);
5919                if (r == null) {
5920                    return;
5921                }
5922            }
5923            if (thumbnail == null && r.thumbHolder != null) {
5924                thumbnail = r.thumbHolder.lastThumbnail;
5925                description = r.thumbHolder.lastDescription;
5926            }
5927            if (thumbnail == null && !always) {
5928                // If there is no thumbnail, and this entry is not actually
5929                // going away, then abort for now and pick up the next
5930                // thumbnail we get.
5931                return;
5932            }
5933            task = r.task;
5934
5935            int N = mPendingThumbnails.size();
5936            int i=0;
5937            while (i<N) {
5938                PendingThumbnailsRecord pr =
5939                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5940                //System.out.println("Looking in " + pr.pendingRecords);
5941                if (pr.pendingRecords.remove(r)) {
5942                    if (receivers == null) {
5943                        receivers = new ArrayList();
5944                    }
5945                    receivers.add(pr);
5946                    if (pr.pendingRecords.size() == 0) {
5947                        pr.finished = true;
5948                        mPendingThumbnails.remove(i);
5949                        N--;
5950                        continue;
5951                    }
5952                }
5953                i++;
5954            }
5955        }
5956
5957        if (receivers != null) {
5958            final int N = receivers.size();
5959            for (int i=0; i<N; i++) {
5960                try {
5961                    PendingThumbnailsRecord pr =
5962                        (PendingThumbnailsRecord)receivers.get(i);
5963                    pr.receiver.newThumbnail(
5964                        task != null ? task.taskId : -1, thumbnail, description);
5965                    if (pr.finished) {
5966                        pr.receiver.finished();
5967                    }
5968                } catch (Exception e) {
5969                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5970                }
5971            }
5972        }
5973    }
5974
5975    // =========================================================
5976    // CONTENT PROVIDERS
5977    // =========================================================
5978
5979    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5980        List<ProviderInfo> providers = null;
5981        try {
5982            providers = AppGlobals.getPackageManager().
5983                queryContentProviders(app.processName, app.uid,
5984                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5985        } catch (RemoteException ex) {
5986        }
5987        if (DEBUG_MU)
5988            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
5989        int userId = app.userId;
5990        if (providers != null) {
5991            int N = providers.size();
5992            for (int i=0; i<N; i++) {
5993                ProviderInfo cpi =
5994                    (ProviderInfo)providers.get(i);
5995                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
5996                        cpi.name, cpi.flags);
5997                if (singleton && UserId.getUserId(app.uid) != 0) {
5998                    // This is a singleton provider, but a user besides the
5999                    // default user is asking to initialize a process it runs
6000                    // in...  well, no, it doesn't actually run in this process,
6001                    // it runs in the process of the default user.  Get rid of it.
6002                    providers.remove(i);
6003                    N--;
6004                    continue;
6005                }
6006
6007                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6008                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6009                if (cpr == null) {
6010                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6011                    mProviderMap.putProviderByClass(comp, cpr);
6012                }
6013                if (DEBUG_MU)
6014                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6015                app.pubProviders.put(cpi.name, cpr);
6016                app.addPackage(cpi.applicationInfo.packageName);
6017                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6018            }
6019        }
6020        return providers;
6021    }
6022
6023    /**
6024     * Check if {@link ProcessRecord} has a possible chance at accessing the
6025     * given {@link ProviderInfo}. Final permission checking is always done
6026     * in {@link ContentProvider}.
6027     */
6028    private final String checkContentProviderPermissionLocked(
6029            ProviderInfo cpi, ProcessRecord r) {
6030        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6031        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6032        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6033                cpi.applicationInfo.uid, cpi.exported)
6034                == PackageManager.PERMISSION_GRANTED) {
6035            return null;
6036        }
6037        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6038                cpi.applicationInfo.uid, cpi.exported)
6039                == PackageManager.PERMISSION_GRANTED) {
6040            return null;
6041        }
6042
6043        PathPermission[] pps = cpi.pathPermissions;
6044        if (pps != null) {
6045            int i = pps.length;
6046            while (i > 0) {
6047                i--;
6048                PathPermission pp = pps[i];
6049                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6050                        cpi.applicationInfo.uid, cpi.exported)
6051                        == PackageManager.PERMISSION_GRANTED) {
6052                    return null;
6053                }
6054                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6055                        cpi.applicationInfo.uid, cpi.exported)
6056                        == PackageManager.PERMISSION_GRANTED) {
6057                    return null;
6058                }
6059            }
6060        }
6061
6062        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6063        if (perms != null) {
6064            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6065                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6066                    return null;
6067                }
6068            }
6069        }
6070
6071        String msg;
6072        if (!cpi.exported) {
6073            msg = "Permission Denial: opening provider " + cpi.name
6074                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6075                    + ", uid=" + callingUid + ") that is not exported from uid "
6076                    + cpi.applicationInfo.uid;
6077        } else {
6078            msg = "Permission Denial: opening provider " + cpi.name
6079                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6080                    + ", uid=" + callingUid + ") requires "
6081                    + cpi.readPermission + " or " + cpi.writePermission;
6082        }
6083        Slog.w(TAG, msg);
6084        return msg;
6085    }
6086
6087    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6088            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6089        if (r != null) {
6090            for (int i=0; i<r.conProviders.size(); i++) {
6091                ContentProviderConnection conn = r.conProviders.get(i);
6092                if (conn.provider == cpr) {
6093                    if (DEBUG_PROVIDER) Slog.v(TAG,
6094                            "Adding provider requested by "
6095                            + r.processName + " from process "
6096                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6097                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6098                    if (stable) {
6099                        conn.stableCount++;
6100                        conn.numStableIncs++;
6101                    } else {
6102                        conn.unstableCount++;
6103                        conn.numUnstableIncs++;
6104                    }
6105                    return conn;
6106                }
6107            }
6108            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6109            if (stable) {
6110                conn.stableCount = 1;
6111                conn.numStableIncs = 1;
6112            } else {
6113                conn.unstableCount = 1;
6114                conn.numUnstableIncs = 1;
6115            }
6116            cpr.connections.add(conn);
6117            r.conProviders.add(conn);
6118            return conn;
6119        }
6120        cpr.addExternalProcessHandleLocked(externalProcessToken);
6121        return null;
6122    }
6123
6124    boolean decProviderCountLocked(ContentProviderConnection conn,
6125            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6126        if (conn != null) {
6127            cpr = conn.provider;
6128            if (DEBUG_PROVIDER) Slog.v(TAG,
6129                    "Removing provider requested by "
6130                    + conn.client.processName + " from process "
6131                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6132                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6133            if (stable) {
6134                conn.stableCount--;
6135            } else {
6136                conn.unstableCount--;
6137            }
6138            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6139                cpr.connections.remove(conn);
6140                conn.client.conProviders.remove(conn);
6141                return true;
6142            }
6143            return false;
6144        }
6145        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6146        return false;
6147    }
6148
6149    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6150            String name, IBinder token, boolean stable) {
6151        ContentProviderRecord cpr;
6152        ContentProviderConnection conn = null;
6153        ProviderInfo cpi = null;
6154
6155        synchronized(this) {
6156            ProcessRecord r = null;
6157            if (caller != null) {
6158                r = getRecordForAppLocked(caller);
6159                if (r == null) {
6160                    throw new SecurityException(
6161                            "Unable to find app for caller " + caller
6162                          + " (pid=" + Binder.getCallingPid()
6163                          + ") when getting content provider " + name);
6164                }
6165            }
6166
6167            // First check if this content provider has been published...
6168            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6169            cpr = mProviderMap.getProviderByName(name, userId);
6170            boolean providerRunning = cpr != null;
6171            if (providerRunning) {
6172                cpi = cpr.info;
6173                String msg;
6174                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6175                    throw new SecurityException(msg);
6176                }
6177
6178                if (r != null && cpr.canRunHere(r)) {
6179                    // This provider has been published or is in the process
6180                    // of being published...  but it is also allowed to run
6181                    // in the caller's process, so don't make a connection
6182                    // and just let the caller instantiate its own instance.
6183                    ContentProviderHolder holder = cpr.newHolder(null);
6184                    // don't give caller the provider object, it needs
6185                    // to make its own.
6186                    holder.provider = null;
6187                    return holder;
6188                }
6189
6190                final long origId = Binder.clearCallingIdentity();
6191
6192                // In this case the provider instance already exists, so we can
6193                // return it right away.
6194                conn = incProviderCountLocked(r, cpr, token, stable);
6195                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6196                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6197                        // If this is a perceptible app accessing the provider,
6198                        // make sure to count it as being accessed and thus
6199                        // back up on the LRU list.  This is good because
6200                        // content providers are often expensive to start.
6201                        updateLruProcessLocked(cpr.proc, false, true);
6202                    }
6203                }
6204
6205                if (cpr.proc != null) {
6206                    if (false) {
6207                        if (cpr.name.flattenToShortString().equals(
6208                                "com.android.providers.calendar/.CalendarProvider2")) {
6209                            Slog.v(TAG, "****************** KILLING "
6210                                + cpr.name.flattenToShortString());
6211                            Process.killProcess(cpr.proc.pid);
6212                        }
6213                    }
6214                    boolean success = updateOomAdjLocked(cpr.proc);
6215                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6216                    // NOTE: there is still a race here where a signal could be
6217                    // pending on the process even though we managed to update its
6218                    // adj level.  Not sure what to do about this, but at least
6219                    // the race is now smaller.
6220                    if (!success) {
6221                        // Uh oh...  it looks like the provider's process
6222                        // has been killed on us.  We need to wait for a new
6223                        // process to be started, and make sure its death
6224                        // doesn't kill our process.
6225                        Slog.i(TAG,
6226                                "Existing provider " + cpr.name.flattenToShortString()
6227                                + " is crashing; detaching " + r);
6228                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6229                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6230                        if (!lastRef) {
6231                            // This wasn't the last ref our process had on
6232                            // the provider...  we have now been killed, bail.
6233                            return null;
6234                        }
6235                        providerRunning = false;
6236                        conn = null;
6237                    }
6238                }
6239
6240                Binder.restoreCallingIdentity(origId);
6241            }
6242
6243            boolean singleton;
6244            if (!providerRunning) {
6245                try {
6246                    cpi = AppGlobals.getPackageManager().
6247                        resolveContentProvider(name,
6248                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6249                } catch (RemoteException ex) {
6250                }
6251                if (cpi == null) {
6252                    return null;
6253                }
6254                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6255                        cpi.name, cpi.flags);
6256                if (singleton) {
6257                    userId = 0;
6258                }
6259                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6260
6261                String msg;
6262                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6263                    throw new SecurityException(msg);
6264                }
6265
6266                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6267                        && !cpi.processName.equals("system")) {
6268                    // If this content provider does not run in the system
6269                    // process, and the system is not yet ready to run other
6270                    // processes, then fail fast instead of hanging.
6271                    throw new IllegalArgumentException(
6272                            "Attempt to launch content provider before system ready");
6273                }
6274
6275                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6276                cpr = mProviderMap.getProviderByClass(comp, userId);
6277                final boolean firstClass = cpr == null;
6278                if (firstClass) {
6279                    try {
6280                        ApplicationInfo ai =
6281                            AppGlobals.getPackageManager().
6282                                getApplicationInfo(
6283                                        cpi.applicationInfo.packageName,
6284                                        STOCK_PM_FLAGS, userId);
6285                        if (ai == null) {
6286                            Slog.w(TAG, "No package info for content provider "
6287                                    + cpi.name);
6288                            return null;
6289                        }
6290                        ai = getAppInfoForUser(ai, userId);
6291                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6292                    } catch (RemoteException ex) {
6293                        // pm is in same process, this will never happen.
6294                    }
6295                }
6296
6297                if (r != null && cpr.canRunHere(r)) {
6298                    // If this is a multiprocess provider, then just return its
6299                    // info and allow the caller to instantiate it.  Only do
6300                    // this if the provider is the same user as the caller's
6301                    // process, or can run as root (so can be in any process).
6302                    return cpr.newHolder(null);
6303                }
6304
6305                if (DEBUG_PROVIDER) {
6306                    RuntimeException e = new RuntimeException("here");
6307                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6308                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6309                }
6310
6311                // This is single process, and our app is now connecting to it.
6312                // See if we are already in the process of launching this
6313                // provider.
6314                final int N = mLaunchingProviders.size();
6315                int i;
6316                for (i=0; i<N; i++) {
6317                    if (mLaunchingProviders.get(i) == cpr) {
6318                        break;
6319                    }
6320                }
6321
6322                // If the provider is not already being launched, then get it
6323                // started.
6324                if (i >= N) {
6325                    final long origId = Binder.clearCallingIdentity();
6326
6327                    try {
6328                        // Content provider is now in use, its package can't be stopped.
6329                        try {
6330                            AppGlobals.getPackageManager().setPackageStoppedState(
6331                                    cpr.appInfo.packageName, false, userId);
6332                        } catch (RemoteException e) {
6333                        } catch (IllegalArgumentException e) {
6334                            Slog.w(TAG, "Failed trying to unstop package "
6335                                    + cpr.appInfo.packageName + ": " + e);
6336                        }
6337
6338                        ProcessRecord proc = startProcessLocked(cpi.processName,
6339                                cpr.appInfo, false, 0, "content provider",
6340                                new ComponentName(cpi.applicationInfo.packageName,
6341                                        cpi.name), false, false);
6342                        if (proc == null) {
6343                            Slog.w(TAG, "Unable to launch app "
6344                                    + cpi.applicationInfo.packageName + "/"
6345                                    + cpi.applicationInfo.uid + " for provider "
6346                                    + name + ": process is bad");
6347                            return null;
6348                        }
6349                        cpr.launchingApp = proc;
6350                        mLaunchingProviders.add(cpr);
6351                    } finally {
6352                        Binder.restoreCallingIdentity(origId);
6353                    }
6354                }
6355
6356                // Make sure the provider is published (the same provider class
6357                // may be published under multiple names).
6358                if (firstClass) {
6359                    mProviderMap.putProviderByClass(comp, cpr);
6360                }
6361
6362                mProviderMap.putProviderByName(name, cpr);
6363                conn = incProviderCountLocked(r, cpr, token, stable);
6364                if (conn != null) {
6365                    conn.waiting = true;
6366                }
6367            }
6368        }
6369
6370        // Wait for the provider to be published...
6371        synchronized (cpr) {
6372            while (cpr.provider == null) {
6373                if (cpr.launchingApp == null) {
6374                    Slog.w(TAG, "Unable to launch app "
6375                            + cpi.applicationInfo.packageName + "/"
6376                            + cpi.applicationInfo.uid + " for provider "
6377                            + name + ": launching app became null");
6378                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6379                            cpi.applicationInfo.packageName,
6380                            cpi.applicationInfo.uid, name);
6381                    return null;
6382                }
6383                try {
6384                    if (DEBUG_MU) {
6385                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6386                                + cpr.launchingApp);
6387                    }
6388                    if (conn != null) {
6389                        conn.waiting = true;
6390                    }
6391                    cpr.wait();
6392                } catch (InterruptedException ex) {
6393                } finally {
6394                    if (conn != null) {
6395                        conn.waiting = false;
6396                    }
6397                }
6398            }
6399        }
6400        return cpr != null ? cpr.newHolder(conn) : null;
6401    }
6402
6403    public final ContentProviderHolder getContentProvider(
6404            IApplicationThread caller, String name, boolean stable) {
6405        enforceNotIsolatedCaller("getContentProvider");
6406        if (caller == null) {
6407            String msg = "null IApplicationThread when getting content provider "
6408                    + name;
6409            Slog.w(TAG, msg);
6410            throw new SecurityException(msg);
6411        }
6412
6413        return getContentProviderImpl(caller, name, null, stable);
6414    }
6415
6416    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6417        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6418            "Do not have permission in call getContentProviderExternal()");
6419        return getContentProviderExternalUnchecked(name, token);
6420    }
6421
6422    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6423        return getContentProviderImpl(null, name, token, true);
6424    }
6425
6426    /**
6427     * Drop a content provider from a ProcessRecord's bookkeeping
6428     * @param cpr
6429     */
6430    public void removeContentProvider(IBinder connection, boolean stable) {
6431        enforceNotIsolatedCaller("removeContentProvider");
6432        synchronized (this) {
6433            ContentProviderConnection conn;
6434            try {
6435                conn = (ContentProviderConnection)connection;
6436            } catch (ClassCastException e) {
6437                String msg ="removeContentProvider: " + connection
6438                        + " not a ContentProviderConnection";
6439                Slog.w(TAG, msg);
6440                throw new IllegalArgumentException(msg);
6441            }
6442            if (conn == null) {
6443                throw new NullPointerException("connection is null");
6444            }
6445            if (decProviderCountLocked(conn, null, null, stable)) {
6446                updateOomAdjLocked();
6447            }
6448        }
6449    }
6450
6451    public void removeContentProviderExternal(String name, IBinder token) {
6452        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6453            "Do not have permission in call removeContentProviderExternal()");
6454        removeContentProviderExternalUnchecked(name, token);
6455    }
6456
6457    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6458        synchronized (this) {
6459            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6460                    Binder.getOrigCallingUser());
6461            if(cpr == null) {
6462                //remove from mProvidersByClass
6463                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6464                return;
6465            }
6466
6467            //update content provider record entry info
6468            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6469            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6470                    Binder.getOrigCallingUser());
6471            if (localCpr.hasExternalProcessHandles()) {
6472                if (localCpr.removeExternalProcessHandleLocked(token)) {
6473                    updateOomAdjLocked();
6474                } else {
6475                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6476                            + " with no external reference for token: "
6477                            + token + ".");
6478                }
6479            } else {
6480                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6481                        + " with no external references.");
6482            }
6483        }
6484    }
6485
6486    public final void publishContentProviders(IApplicationThread caller,
6487            List<ContentProviderHolder> providers) {
6488        if (providers == null) {
6489            return;
6490        }
6491
6492        enforceNotIsolatedCaller("publishContentProviders");
6493        synchronized (this) {
6494            final ProcessRecord r = getRecordForAppLocked(caller);
6495            if (DEBUG_MU)
6496                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6497            if (r == null) {
6498                throw new SecurityException(
6499                        "Unable to find app for caller " + caller
6500                      + " (pid=" + Binder.getCallingPid()
6501                      + ") when publishing content providers");
6502            }
6503
6504            final long origId = Binder.clearCallingIdentity();
6505
6506            final int N = providers.size();
6507            for (int i=0; i<N; i++) {
6508                ContentProviderHolder src = providers.get(i);
6509                if (src == null || src.info == null || src.provider == null) {
6510                    continue;
6511                }
6512                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6513                if (DEBUG_MU)
6514                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6515                if (dst != null) {
6516                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6517                    mProviderMap.putProviderByClass(comp, dst);
6518                    String names[] = dst.info.authority.split(";");
6519                    for (int j = 0; j < names.length; j++) {
6520                        mProviderMap.putProviderByName(names[j], dst);
6521                    }
6522
6523                    int NL = mLaunchingProviders.size();
6524                    int j;
6525                    for (j=0; j<NL; j++) {
6526                        if (mLaunchingProviders.get(j) == dst) {
6527                            mLaunchingProviders.remove(j);
6528                            j--;
6529                            NL--;
6530                        }
6531                    }
6532                    synchronized (dst) {
6533                        dst.provider = src.provider;
6534                        dst.proc = r;
6535                        dst.notifyAll();
6536                    }
6537                    updateOomAdjLocked(r);
6538                }
6539            }
6540
6541            Binder.restoreCallingIdentity(origId);
6542        }
6543    }
6544
6545    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6546        ContentProviderConnection conn;
6547        try {
6548            conn = (ContentProviderConnection)connection;
6549        } catch (ClassCastException e) {
6550            String msg ="refContentProvider: " + connection
6551                    + " not a ContentProviderConnection";
6552            Slog.w(TAG, msg);
6553            throw new IllegalArgumentException(msg);
6554        }
6555        if (conn == null) {
6556            throw new NullPointerException("connection is null");
6557        }
6558
6559        synchronized (this) {
6560            if (stable > 0) {
6561                conn.numStableIncs += stable;
6562            }
6563            stable = conn.stableCount + stable;
6564            if (stable < 0) {
6565                throw new IllegalStateException("stableCount < 0: " + stable);
6566            }
6567
6568            if (unstable > 0) {
6569                conn.numUnstableIncs += unstable;
6570            }
6571            unstable = conn.unstableCount + unstable;
6572            if (unstable < 0) {
6573                throw new IllegalStateException("unstableCount < 0: " + unstable);
6574            }
6575
6576            if ((stable+unstable) <= 0) {
6577                throw new IllegalStateException("ref counts can't go to zero here: stable="
6578                        + stable + " unstable=" + unstable);
6579            }
6580            conn.stableCount = stable;
6581            conn.unstableCount = unstable;
6582            return !conn.dead;
6583        }
6584    }
6585
6586    public void unstableProviderDied(IBinder connection) {
6587        ContentProviderConnection conn;
6588        try {
6589            conn = (ContentProviderConnection)connection;
6590        } catch (ClassCastException e) {
6591            String msg ="refContentProvider: " + connection
6592                    + " not a ContentProviderConnection";
6593            Slog.w(TAG, msg);
6594            throw new IllegalArgumentException(msg);
6595        }
6596        if (conn == null) {
6597            throw new NullPointerException("connection is null");
6598        }
6599
6600        // Safely retrieve the content provider associated with the connection.
6601        IContentProvider provider;
6602        synchronized (this) {
6603            provider = conn.provider.provider;
6604        }
6605
6606        if (provider == null) {
6607            // Um, yeah, we're way ahead of you.
6608            return;
6609        }
6610
6611        // Make sure the caller is being honest with us.
6612        if (provider.asBinder().pingBinder()) {
6613            // Er, no, still looks good to us.
6614            synchronized (this) {
6615                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6616                        + " says " + conn + " died, but we don't agree");
6617                return;
6618            }
6619        }
6620
6621        // Well look at that!  It's dead!
6622        synchronized (this) {
6623            if (conn.provider.provider != provider) {
6624                // But something changed...  good enough.
6625                return;
6626            }
6627
6628            ProcessRecord proc = conn.provider.proc;
6629            if (proc == null || proc.thread == null) {
6630                // Seems like the process is already cleaned up.
6631                return;
6632            }
6633
6634            // As far as we're concerned, this is just like receiving a
6635            // death notification...  just a bit prematurely.
6636            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6637                    + ") early provider death");
6638            final long ident = Binder.clearCallingIdentity();
6639            try {
6640                appDiedLocked(proc, proc.pid, proc.thread);
6641            } finally {
6642                Binder.restoreCallingIdentity(ident);
6643            }
6644        }
6645    }
6646
6647    public static final void installSystemProviders() {
6648        List<ProviderInfo> providers;
6649        synchronized (mSelf) {
6650            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6651            providers = mSelf.generateApplicationProvidersLocked(app);
6652            if (providers != null) {
6653                for (int i=providers.size()-1; i>=0; i--) {
6654                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6655                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6656                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6657                                + ": not system .apk");
6658                        providers.remove(i);
6659                    }
6660                }
6661            }
6662        }
6663        if (providers != null) {
6664            mSystemThread.installSystemProviders(providers);
6665        }
6666
6667        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6668
6669        mSelf.mUsageStatsService.monitorPackages();
6670    }
6671
6672    /**
6673     * Allows app to retrieve the MIME type of a URI without having permission
6674     * to access its content provider.
6675     *
6676     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6677     *
6678     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6679     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6680     */
6681    public String getProviderMimeType(Uri uri) {
6682        enforceNotIsolatedCaller("getProviderMimeType");
6683        final String name = uri.getAuthority();
6684        final long ident = Binder.clearCallingIdentity();
6685        ContentProviderHolder holder = null;
6686
6687        try {
6688            holder = getContentProviderExternalUnchecked(name, null);
6689            if (holder != null) {
6690                return holder.provider.getType(uri);
6691            }
6692        } catch (RemoteException e) {
6693            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6694            return null;
6695        } finally {
6696            if (holder != null) {
6697                removeContentProviderExternalUnchecked(name, null);
6698            }
6699            Binder.restoreCallingIdentity(ident);
6700        }
6701
6702        return null;
6703    }
6704
6705    // =========================================================
6706    // GLOBAL MANAGEMENT
6707    // =========================================================
6708
6709    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6710            ApplicationInfo info, String customProcess, boolean isolated) {
6711        String proc = customProcess != null ? customProcess : info.processName;
6712        BatteryStatsImpl.Uid.Proc ps = null;
6713        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6714        int uid = info.uid;
6715        if (isolated) {
6716            int userId = UserId.getUserId(uid);
6717            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6718            uid = 0;
6719            while (true) {
6720                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6721                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6722                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6723                }
6724                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6725                mNextIsolatedProcessUid++;
6726                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6727                    // No process for this uid, use it.
6728                    break;
6729                }
6730                stepsLeft--;
6731                if (stepsLeft <= 0) {
6732                    return null;
6733                }
6734            }
6735        }
6736        synchronized (stats) {
6737            ps = stats.getProcessStatsLocked(info.uid, proc);
6738        }
6739        return new ProcessRecord(ps, thread, info, proc, uid);
6740    }
6741
6742    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6743        ProcessRecord app;
6744        if (!isolated) {
6745            app = getProcessRecordLocked(info.processName, info.uid);
6746        } else {
6747            app = null;
6748        }
6749
6750        if (app == null) {
6751            app = newProcessRecordLocked(null, info, null, isolated);
6752            mProcessNames.put(info.processName, app.uid, app);
6753            if (isolated) {
6754                mIsolatedProcesses.put(app.uid, app);
6755            }
6756            updateLruProcessLocked(app, true, true);
6757        }
6758
6759        // This package really, really can not be stopped.
6760        try {
6761            AppGlobals.getPackageManager().setPackageStoppedState(
6762                    info.packageName, false, UserId.getUserId(app.uid));
6763        } catch (RemoteException e) {
6764        } catch (IllegalArgumentException e) {
6765            Slog.w(TAG, "Failed trying to unstop package "
6766                    + info.packageName + ": " + e);
6767        }
6768
6769        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6770                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6771            app.persistent = true;
6772            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6773        }
6774        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6775            mPersistentStartingProcesses.add(app);
6776            startProcessLocked(app, "added application", app.processName);
6777        }
6778
6779        return app;
6780    }
6781
6782    public void unhandledBack() {
6783        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6784                "unhandledBack()");
6785
6786        synchronized(this) {
6787            int count = mMainStack.mHistory.size();
6788            if (DEBUG_SWITCH) Slog.d(
6789                TAG, "Performing unhandledBack(): stack size = " + count);
6790            if (count > 1) {
6791                final long origId = Binder.clearCallingIdentity();
6792                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6793                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6794                Binder.restoreCallingIdentity(origId);
6795            }
6796        }
6797    }
6798
6799    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6800        enforceNotIsolatedCaller("openContentUri");
6801        String name = uri.getAuthority();
6802        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6803        ParcelFileDescriptor pfd = null;
6804        if (cph != null) {
6805            // We record the binder invoker's uid in thread-local storage before
6806            // going to the content provider to open the file.  Later, in the code
6807            // that handles all permissions checks, we look for this uid and use
6808            // that rather than the Activity Manager's own uid.  The effect is that
6809            // we do the check against the caller's permissions even though it looks
6810            // to the content provider like the Activity Manager itself is making
6811            // the request.
6812            sCallerIdentity.set(new Identity(
6813                    Binder.getCallingPid(), Binder.getCallingUid()));
6814            try {
6815                pfd = cph.provider.openFile(uri, "r");
6816            } catch (FileNotFoundException e) {
6817                // do nothing; pfd will be returned null
6818            } finally {
6819                // Ensure that whatever happens, we clean up the identity state
6820                sCallerIdentity.remove();
6821            }
6822
6823            // We've got the fd now, so we're done with the provider.
6824            removeContentProviderExternalUnchecked(name, null);
6825        } else {
6826            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6827        }
6828        return pfd;
6829    }
6830
6831    // Actually is sleeping or shutting down or whatever else in the future
6832    // is an inactive state.
6833    public boolean isSleeping() {
6834        return mSleeping || mShuttingDown;
6835    }
6836
6837    public void goingToSleep() {
6838        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6839                != PackageManager.PERMISSION_GRANTED) {
6840            throw new SecurityException("Requires permission "
6841                    + android.Manifest.permission.DEVICE_POWER);
6842        }
6843
6844        synchronized(this) {
6845            mWentToSleep = true;
6846            updateEventDispatchingLocked();
6847
6848            if (!mSleeping) {
6849                mSleeping = true;
6850                mMainStack.stopIfSleepingLocked();
6851
6852                // Initialize the wake times of all processes.
6853                checkExcessivePowerUsageLocked(false);
6854                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6855                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6856                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6857            }
6858        }
6859    }
6860
6861    public boolean shutdown(int timeout) {
6862        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6863                != PackageManager.PERMISSION_GRANTED) {
6864            throw new SecurityException("Requires permission "
6865                    + android.Manifest.permission.SHUTDOWN);
6866        }
6867
6868        boolean timedout = false;
6869
6870        synchronized(this) {
6871            mShuttingDown = true;
6872            updateEventDispatchingLocked();
6873
6874            if (mMainStack.mResumedActivity != null) {
6875                mMainStack.stopIfSleepingLocked();
6876                final long endTime = System.currentTimeMillis() + timeout;
6877                while (mMainStack.mResumedActivity != null
6878                        || mMainStack.mPausingActivity != null) {
6879                    long delay = endTime - System.currentTimeMillis();
6880                    if (delay <= 0) {
6881                        Slog.w(TAG, "Activity manager shutdown timed out");
6882                        timedout = true;
6883                        break;
6884                    }
6885                    try {
6886                        this.wait();
6887                    } catch (InterruptedException e) {
6888                    }
6889                }
6890            }
6891        }
6892
6893        mUsageStatsService.shutdown();
6894        mBatteryStatsService.shutdown();
6895
6896        return timedout;
6897    }
6898
6899    public final void activitySlept(IBinder token) {
6900        if (localLOGV) Slog.v(
6901            TAG, "Activity slept: token=" + token);
6902
6903        ActivityRecord r = null;
6904
6905        final long origId = Binder.clearCallingIdentity();
6906
6907        synchronized (this) {
6908            r = mMainStack.isInStackLocked(token);
6909            if (r != null) {
6910                mMainStack.activitySleptLocked(r);
6911            }
6912        }
6913
6914        Binder.restoreCallingIdentity(origId);
6915    }
6916
6917    private void comeOutOfSleepIfNeededLocked() {
6918        if (!mWentToSleep && !mLockScreenShown) {
6919            if (mSleeping) {
6920                mSleeping = false;
6921                mMainStack.awakeFromSleepingLocked();
6922                mMainStack.resumeTopActivityLocked(null);
6923            }
6924        }
6925    }
6926
6927    public void wakingUp() {
6928        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6929                != PackageManager.PERMISSION_GRANTED) {
6930            throw new SecurityException("Requires permission "
6931                    + android.Manifest.permission.DEVICE_POWER);
6932        }
6933
6934        synchronized(this) {
6935            mWentToSleep = false;
6936            updateEventDispatchingLocked();
6937            comeOutOfSleepIfNeededLocked();
6938        }
6939    }
6940
6941    private void updateEventDispatchingLocked() {
6942        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6943    }
6944
6945    public void setLockScreenShown(boolean shown) {
6946        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6947                != PackageManager.PERMISSION_GRANTED) {
6948            throw new SecurityException("Requires permission "
6949                    + android.Manifest.permission.DEVICE_POWER);
6950        }
6951
6952        synchronized(this) {
6953            mLockScreenShown = shown;
6954            comeOutOfSleepIfNeededLocked();
6955        }
6956    }
6957
6958    public void stopAppSwitches() {
6959        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6960                != PackageManager.PERMISSION_GRANTED) {
6961            throw new SecurityException("Requires permission "
6962                    + android.Manifest.permission.STOP_APP_SWITCHES);
6963        }
6964
6965        synchronized(this) {
6966            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6967                    + APP_SWITCH_DELAY_TIME;
6968            mDidAppSwitch = false;
6969            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6970            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6971            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6972        }
6973    }
6974
6975    public void resumeAppSwitches() {
6976        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6977                != PackageManager.PERMISSION_GRANTED) {
6978            throw new SecurityException("Requires permission "
6979                    + android.Manifest.permission.STOP_APP_SWITCHES);
6980        }
6981
6982        synchronized(this) {
6983            // Note that we don't execute any pending app switches... we will
6984            // let those wait until either the timeout, or the next start
6985            // activity request.
6986            mAppSwitchesAllowedTime = 0;
6987        }
6988    }
6989
6990    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6991            String name) {
6992        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6993            return true;
6994        }
6995
6996        final int perm = checkComponentPermission(
6997                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
6998                callingUid, -1, true);
6999        if (perm == PackageManager.PERMISSION_GRANTED) {
7000            return true;
7001        }
7002
7003        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7004        return false;
7005    }
7006
7007    public void setDebugApp(String packageName, boolean waitForDebugger,
7008            boolean persistent) {
7009        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7010                "setDebugApp()");
7011
7012        // Note that this is not really thread safe if there are multiple
7013        // callers into it at the same time, but that's not a situation we
7014        // care about.
7015        if (persistent) {
7016            final ContentResolver resolver = mContext.getContentResolver();
7017            Settings.System.putString(
7018                resolver, Settings.System.DEBUG_APP,
7019                packageName);
7020            Settings.System.putInt(
7021                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7022                waitForDebugger ? 1 : 0);
7023        }
7024
7025        synchronized (this) {
7026            if (!persistent) {
7027                mOrigDebugApp = mDebugApp;
7028                mOrigWaitForDebugger = mWaitForDebugger;
7029            }
7030            mDebugApp = packageName;
7031            mWaitForDebugger = waitForDebugger;
7032            mDebugTransient = !persistent;
7033            if (packageName != null) {
7034                final long origId = Binder.clearCallingIdentity();
7035                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7036                Binder.restoreCallingIdentity(origId);
7037            }
7038        }
7039    }
7040
7041    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7042        synchronized (this) {
7043            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7044            if (!isDebuggable) {
7045                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7046                    throw new SecurityException("Process not debuggable: " + app.packageName);
7047                }
7048            }
7049
7050            mOpenGlTraceApp = processName;
7051        }
7052    }
7053
7054    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7055            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7056        synchronized (this) {
7057            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7058            if (!isDebuggable) {
7059                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7060                    throw new SecurityException("Process not debuggable: " + app.packageName);
7061                }
7062            }
7063            mProfileApp = processName;
7064            mProfileFile = profileFile;
7065            if (mProfileFd != null) {
7066                try {
7067                    mProfileFd.close();
7068                } catch (IOException e) {
7069                }
7070                mProfileFd = null;
7071            }
7072            mProfileFd = profileFd;
7073            mProfileType = 0;
7074            mAutoStopProfiler = autoStopProfiler;
7075        }
7076    }
7077
7078    public void setAlwaysFinish(boolean enabled) {
7079        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7080                "setAlwaysFinish()");
7081
7082        Settings.System.putInt(
7083                mContext.getContentResolver(),
7084                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7085
7086        synchronized (this) {
7087            mAlwaysFinishActivities = enabled;
7088        }
7089    }
7090
7091    public void setActivityController(IActivityController controller) {
7092        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7093                "setActivityController()");
7094        synchronized (this) {
7095            mController = controller;
7096        }
7097    }
7098
7099    public boolean isUserAMonkey() {
7100        // For now the fact that there is a controller implies
7101        // we have a monkey.
7102        synchronized (this) {
7103            return mController != null;
7104        }
7105    }
7106
7107    public void registerProcessObserver(IProcessObserver observer) {
7108        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7109                "registerProcessObserver()");
7110        synchronized (this) {
7111            mProcessObservers.register(observer);
7112        }
7113    }
7114
7115    public void unregisterProcessObserver(IProcessObserver observer) {
7116        synchronized (this) {
7117            mProcessObservers.unregister(observer);
7118        }
7119    }
7120
7121    public void setImmersive(IBinder token, boolean immersive) {
7122        synchronized(this) {
7123            ActivityRecord r = mMainStack.isInStackLocked(token);
7124            if (r == null) {
7125                throw new IllegalArgumentException();
7126            }
7127            r.immersive = immersive;
7128        }
7129    }
7130
7131    public boolean isImmersive(IBinder token) {
7132        synchronized (this) {
7133            ActivityRecord r = mMainStack.isInStackLocked(token);
7134            if (r == null) {
7135                throw new IllegalArgumentException();
7136            }
7137            return r.immersive;
7138        }
7139    }
7140
7141    public boolean isTopActivityImmersive() {
7142        enforceNotIsolatedCaller("startActivity");
7143        synchronized (this) {
7144            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7145            return (r != null) ? r.immersive : false;
7146        }
7147    }
7148
7149    public final void enterSafeMode() {
7150        synchronized(this) {
7151            // It only makes sense to do this before the system is ready
7152            // and started launching other packages.
7153            if (!mSystemReady) {
7154                try {
7155                    AppGlobals.getPackageManager().enterSafeMode();
7156                } catch (RemoteException e) {
7157                }
7158            }
7159        }
7160    }
7161
7162    public final void showSafeModeOverlay() {
7163        View v = LayoutInflater.from(mContext).inflate(
7164                com.android.internal.R.layout.safe_mode, null);
7165        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7166        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7167        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7168        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7169        lp.gravity = Gravity.BOTTOM | Gravity.START;
7170        lp.format = v.getBackground().getOpacity();
7171        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7172                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7173        ((WindowManager)mContext.getSystemService(
7174                Context.WINDOW_SERVICE)).addView(v, lp);
7175    }
7176
7177    public void noteWakeupAlarm(IIntentSender sender) {
7178        if (!(sender instanceof PendingIntentRecord)) {
7179            return;
7180        }
7181        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7182        synchronized (stats) {
7183            if (mBatteryStatsService.isOnBattery()) {
7184                mBatteryStatsService.enforceCallingPermission();
7185                PendingIntentRecord rec = (PendingIntentRecord)sender;
7186                int MY_UID = Binder.getCallingUid();
7187                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7188                BatteryStatsImpl.Uid.Pkg pkg =
7189                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7190                pkg.incWakeupsLocked();
7191            }
7192        }
7193    }
7194
7195    public boolean killPids(int[] pids, String pReason, boolean secure) {
7196        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7197            throw new SecurityException("killPids only available to the system");
7198        }
7199        String reason = (pReason == null) ? "Unknown" : pReason;
7200        // XXX Note: don't acquire main activity lock here, because the window
7201        // manager calls in with its locks held.
7202
7203        boolean killed = false;
7204        synchronized (mPidsSelfLocked) {
7205            int[] types = new int[pids.length];
7206            int worstType = 0;
7207            for (int i=0; i<pids.length; i++) {
7208                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7209                if (proc != null) {
7210                    int type = proc.setAdj;
7211                    types[i] = type;
7212                    if (type > worstType) {
7213                        worstType = type;
7214                    }
7215                }
7216            }
7217
7218            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7219            // then constrain it so we will kill all hidden procs.
7220            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7221                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7222                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7223            }
7224
7225            // If this is not a secure call, don't let it kill processes that
7226            // are important.
7227            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7228                worstType = ProcessList.SERVICE_ADJ;
7229            }
7230
7231            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7232            for (int i=0; i<pids.length; i++) {
7233                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7234                if (proc == null) {
7235                    continue;
7236                }
7237                int adj = proc.setAdj;
7238                if (adj >= worstType && !proc.killedBackground) {
7239                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7240                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7241                            proc.processName, adj, reason);
7242                    killed = true;
7243                    proc.killedBackground = true;
7244                    Process.killProcessQuiet(pids[i]);
7245                }
7246            }
7247        }
7248        return killed;
7249    }
7250
7251    @Override
7252    public boolean killProcessesBelowForeground(String reason) {
7253        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7254            throw new SecurityException("killProcessesBelowForeground() only available to system");
7255        }
7256
7257        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7258    }
7259
7260    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7261        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7262            throw new SecurityException("killProcessesBelowAdj() only available to system");
7263        }
7264
7265        boolean killed = false;
7266        synchronized (mPidsSelfLocked) {
7267            final int size = mPidsSelfLocked.size();
7268            for (int i = 0; i < size; i++) {
7269                final int pid = mPidsSelfLocked.keyAt(i);
7270                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7271                if (proc == null) continue;
7272
7273                final int adj = proc.setAdj;
7274                if (adj > belowAdj && !proc.killedBackground) {
7275                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7276                    EventLog.writeEvent(
7277                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7278                    killed = true;
7279                    proc.killedBackground = true;
7280                    Process.killProcessQuiet(pid);
7281                }
7282            }
7283        }
7284        return killed;
7285    }
7286
7287    public final void startRunning(String pkg, String cls, String action,
7288            String data) {
7289        synchronized(this) {
7290            if (mStartRunning) {
7291                return;
7292            }
7293            mStartRunning = true;
7294            mTopComponent = pkg != null && cls != null
7295                    ? new ComponentName(pkg, cls) : null;
7296            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7297            mTopData = data;
7298            if (!mSystemReady) {
7299                return;
7300            }
7301        }
7302
7303        systemReady(null);
7304    }
7305
7306    private void retrieveSettings() {
7307        final ContentResolver resolver = mContext.getContentResolver();
7308        String debugApp = Settings.System.getString(
7309            resolver, Settings.System.DEBUG_APP);
7310        boolean waitForDebugger = Settings.System.getInt(
7311            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7312        boolean alwaysFinishActivities = Settings.System.getInt(
7313            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7314
7315        Configuration configuration = new Configuration();
7316        Settings.System.getConfiguration(resolver, configuration);
7317
7318        synchronized (this) {
7319            mDebugApp = mOrigDebugApp = debugApp;
7320            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7321            mAlwaysFinishActivities = alwaysFinishActivities;
7322            // This happens before any activities are started, so we can
7323            // change mConfiguration in-place.
7324            updateConfigurationLocked(configuration, null, false, true);
7325            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7326        }
7327    }
7328
7329    public boolean testIsSystemReady() {
7330        // no need to synchronize(this) just to read & return the value
7331        return mSystemReady;
7332    }
7333
7334    private static File getCalledPreBootReceiversFile() {
7335        File dataDir = Environment.getDataDirectory();
7336        File systemDir = new File(dataDir, "system");
7337        File fname = new File(systemDir, "called_pre_boots.dat");
7338        return fname;
7339    }
7340
7341    static final int LAST_DONE_VERSION = 10000;
7342
7343    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7344        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7345        File file = getCalledPreBootReceiversFile();
7346        FileInputStream fis = null;
7347        try {
7348            fis = new FileInputStream(file);
7349            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7350            int fvers = dis.readInt();
7351            if (fvers == LAST_DONE_VERSION) {
7352                String vers = dis.readUTF();
7353                String codename = dis.readUTF();
7354                String build = dis.readUTF();
7355                if (android.os.Build.VERSION.RELEASE.equals(vers)
7356                        && android.os.Build.VERSION.CODENAME.equals(codename)
7357                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7358                    int num = dis.readInt();
7359                    while (num > 0) {
7360                        num--;
7361                        String pkg = dis.readUTF();
7362                        String cls = dis.readUTF();
7363                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7364                    }
7365                }
7366            }
7367        } catch (FileNotFoundException e) {
7368        } catch (IOException e) {
7369            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7370        } finally {
7371            if (fis != null) {
7372                try {
7373                    fis.close();
7374                } catch (IOException e) {
7375                }
7376            }
7377        }
7378        return lastDoneReceivers;
7379    }
7380
7381    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7382        File file = getCalledPreBootReceiversFile();
7383        FileOutputStream fos = null;
7384        DataOutputStream dos = null;
7385        try {
7386            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7387            fos = new FileOutputStream(file);
7388            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7389            dos.writeInt(LAST_DONE_VERSION);
7390            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7391            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7392            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7393            dos.writeInt(list.size());
7394            for (int i=0; i<list.size(); i++) {
7395                dos.writeUTF(list.get(i).getPackageName());
7396                dos.writeUTF(list.get(i).getClassName());
7397            }
7398        } catch (IOException e) {
7399            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7400            file.delete();
7401        } finally {
7402            FileUtils.sync(fos);
7403            if (dos != null) {
7404                try {
7405                    dos.close();
7406                } catch (IOException e) {
7407                    // TODO Auto-generated catch block
7408                    e.printStackTrace();
7409                }
7410            }
7411        }
7412    }
7413
7414    public void systemReady(final Runnable goingCallback) {
7415        synchronized(this) {
7416            if (mSystemReady) {
7417                if (goingCallback != null) goingCallback.run();
7418                return;
7419            }
7420
7421            // Check to see if there are any update receivers to run.
7422            if (!mDidUpdate) {
7423                if (mWaitingUpdate) {
7424                    return;
7425                }
7426                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7427                List<ResolveInfo> ris = null;
7428                try {
7429                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7430                            intent, null, 0, 0);
7431                } catch (RemoteException e) {
7432                }
7433                if (ris != null) {
7434                    for (int i=ris.size()-1; i>=0; i--) {
7435                        if ((ris.get(i).activityInfo.applicationInfo.flags
7436                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7437                            ris.remove(i);
7438                        }
7439                    }
7440                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7441
7442                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7443
7444                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7445                    for (int i=0; i<ris.size(); i++) {
7446                        ActivityInfo ai = ris.get(i).activityInfo;
7447                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7448                        if (lastDoneReceivers.contains(comp)) {
7449                            ris.remove(i);
7450                            i--;
7451                        }
7452                    }
7453
7454                    for (int i=0; i<ris.size(); i++) {
7455                        ActivityInfo ai = ris.get(i).activityInfo;
7456                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7457                        doneReceivers.add(comp);
7458                        intent.setComponent(comp);
7459                        IIntentReceiver finisher = null;
7460                        if (i == ris.size()-1) {
7461                            finisher = new IIntentReceiver.Stub() {
7462                                public void performReceive(Intent intent, int resultCode,
7463                                        String data, Bundle extras, boolean ordered,
7464                                        boolean sticky) {
7465                                    // The raw IIntentReceiver interface is called
7466                                    // with the AM lock held, so redispatch to
7467                                    // execute our code without the lock.
7468                                    mHandler.post(new Runnable() {
7469                                        public void run() {
7470                                            synchronized (ActivityManagerService.this) {
7471                                                mDidUpdate = true;
7472                                            }
7473                                            writeLastDonePreBootReceivers(doneReceivers);
7474                                            showBootMessage(mContext.getText(
7475                                                    R.string.android_upgrading_complete),
7476                                                    false);
7477                                            systemReady(goingCallback);
7478                                        }
7479                                    });
7480                                }
7481                            };
7482                        }
7483                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7484                        /* TODO: Send this to all users */
7485                        broadcastIntentLocked(null, null, intent, null, finisher,
7486                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7487                                0 /* UserId zero */);
7488                        if (finisher != null) {
7489                            mWaitingUpdate = true;
7490                        }
7491                    }
7492                }
7493                if (mWaitingUpdate) {
7494                    return;
7495                }
7496                mDidUpdate = true;
7497            }
7498
7499            mSystemReady = true;
7500            if (!mStartRunning) {
7501                return;
7502            }
7503        }
7504
7505        ArrayList<ProcessRecord> procsToKill = null;
7506        synchronized(mPidsSelfLocked) {
7507            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7508                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7509                if (!isAllowedWhileBooting(proc.info)){
7510                    if (procsToKill == null) {
7511                        procsToKill = new ArrayList<ProcessRecord>();
7512                    }
7513                    procsToKill.add(proc);
7514                }
7515            }
7516        }
7517
7518        synchronized(this) {
7519            if (procsToKill != null) {
7520                for (int i=procsToKill.size()-1; i>=0; i--) {
7521                    ProcessRecord proc = procsToKill.get(i);
7522                    Slog.i(TAG, "Removing system update proc: " + proc);
7523                    removeProcessLocked(proc, true, false, "system update done");
7524                }
7525            }
7526
7527            // Now that we have cleaned up any update processes, we
7528            // are ready to start launching real processes and know that
7529            // we won't trample on them any more.
7530            mProcessesReady = true;
7531        }
7532
7533        Slog.i(TAG, "System now ready");
7534        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7535            SystemClock.uptimeMillis());
7536
7537        synchronized(this) {
7538            // Make sure we have no pre-ready processes sitting around.
7539
7540            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7541                ResolveInfo ri = mContext.getPackageManager()
7542                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7543                                STOCK_PM_FLAGS);
7544                CharSequence errorMsg = null;
7545                if (ri != null) {
7546                    ActivityInfo ai = ri.activityInfo;
7547                    ApplicationInfo app = ai.applicationInfo;
7548                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7549                        mTopAction = Intent.ACTION_FACTORY_TEST;
7550                        mTopData = null;
7551                        mTopComponent = new ComponentName(app.packageName,
7552                                ai.name);
7553                    } else {
7554                        errorMsg = mContext.getResources().getText(
7555                                com.android.internal.R.string.factorytest_not_system);
7556                    }
7557                } else {
7558                    errorMsg = mContext.getResources().getText(
7559                            com.android.internal.R.string.factorytest_no_action);
7560                }
7561                if (errorMsg != null) {
7562                    mTopAction = null;
7563                    mTopData = null;
7564                    mTopComponent = null;
7565                    Message msg = Message.obtain();
7566                    msg.what = SHOW_FACTORY_ERROR_MSG;
7567                    msg.getData().putCharSequence("msg", errorMsg);
7568                    mHandler.sendMessage(msg);
7569                }
7570            }
7571        }
7572
7573        retrieveSettings();
7574
7575        if (goingCallback != null) goingCallback.run();
7576
7577        synchronized (this) {
7578            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7579                try {
7580                    List apps = AppGlobals.getPackageManager().
7581                        getPersistentApplications(STOCK_PM_FLAGS);
7582                    if (apps != null) {
7583                        int N = apps.size();
7584                        int i;
7585                        for (i=0; i<N; i++) {
7586                            ApplicationInfo info
7587                                = (ApplicationInfo)apps.get(i);
7588                            if (info != null &&
7589                                    !info.packageName.equals("android")) {
7590                                addAppLocked(info, false);
7591                            }
7592                        }
7593                    }
7594                } catch (RemoteException ex) {
7595                    // pm is in same process, this will never happen.
7596                }
7597            }
7598
7599            // Start up initial activity.
7600            mBooting = true;
7601
7602            try {
7603                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7604                    Message msg = Message.obtain();
7605                    msg.what = SHOW_UID_ERROR_MSG;
7606                    mHandler.sendMessage(msg);
7607                }
7608            } catch (RemoteException e) {
7609            }
7610
7611            mMainStack.resumeTopActivityLocked(null);
7612        }
7613    }
7614
7615    private boolean makeAppCrashingLocked(ProcessRecord app,
7616            String shortMsg, String longMsg, String stackTrace) {
7617        app.crashing = true;
7618        app.crashingReport = generateProcessError(app,
7619                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7620        startAppProblemLocked(app);
7621        app.stopFreezingAllLocked();
7622        return handleAppCrashLocked(app);
7623    }
7624
7625    private void makeAppNotRespondingLocked(ProcessRecord app,
7626            String activity, String shortMsg, String longMsg) {
7627        app.notResponding = true;
7628        app.notRespondingReport = generateProcessError(app,
7629                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7630                activity, shortMsg, longMsg, null);
7631        startAppProblemLocked(app);
7632        app.stopFreezingAllLocked();
7633    }
7634
7635    /**
7636     * Generate a process error record, suitable for attachment to a ProcessRecord.
7637     *
7638     * @param app The ProcessRecord in which the error occurred.
7639     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7640     *                      ActivityManager.AppErrorStateInfo
7641     * @param activity The activity associated with the crash, if known.
7642     * @param shortMsg Short message describing the crash.
7643     * @param longMsg Long message describing the crash.
7644     * @param stackTrace Full crash stack trace, may be null.
7645     *
7646     * @return Returns a fully-formed AppErrorStateInfo record.
7647     */
7648    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7649            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7650        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7651
7652        report.condition = condition;
7653        report.processName = app.processName;
7654        report.pid = app.pid;
7655        report.uid = app.info.uid;
7656        report.tag = activity;
7657        report.shortMsg = shortMsg;
7658        report.longMsg = longMsg;
7659        report.stackTrace = stackTrace;
7660
7661        return report;
7662    }
7663
7664    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7665        synchronized (this) {
7666            app.crashing = false;
7667            app.crashingReport = null;
7668            app.notResponding = false;
7669            app.notRespondingReport = null;
7670            if (app.anrDialog == fromDialog) {
7671                app.anrDialog = null;
7672            }
7673            if (app.waitDialog == fromDialog) {
7674                app.waitDialog = null;
7675            }
7676            if (app.pid > 0 && app.pid != MY_PID) {
7677                handleAppCrashLocked(app);
7678                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7679                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7680                        app.processName, app.setAdj, "user's request after error");
7681                Process.killProcessQuiet(app.pid);
7682            }
7683        }
7684    }
7685
7686    private boolean handleAppCrashLocked(ProcessRecord app) {
7687        if (mHeadless) {
7688            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7689            return false;
7690        }
7691        long now = SystemClock.uptimeMillis();
7692
7693        Long crashTime;
7694        if (!app.isolated) {
7695            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7696        } else {
7697            crashTime = null;
7698        }
7699        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7700            // This process loses!
7701            Slog.w(TAG, "Process " + app.info.processName
7702                    + " has crashed too many times: killing!");
7703            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7704                    app.info.processName, app.uid);
7705            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7706                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7707                if (r.app == app) {
7708                    Slog.w(TAG, "  Force finishing activity "
7709                        + r.intent.getComponent().flattenToShortString());
7710                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7711                }
7712            }
7713            if (!app.persistent) {
7714                // We don't want to start this process again until the user
7715                // explicitly does so...  but for persistent process, we really
7716                // need to keep it running.  If a persistent process is actually
7717                // repeatedly crashing, then badness for everyone.
7718                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7719                        app.info.processName);
7720                if (!app.isolated) {
7721                    // XXX We don't have a way to mark isolated processes
7722                    // as bad, since they don't have a peristent identity.
7723                    mBadProcesses.put(app.info.processName, app.uid, now);
7724                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7725                }
7726                app.bad = true;
7727                app.removed = true;
7728                // Don't let services in this process be restarted and potentially
7729                // annoy the user repeatedly.  Unless it is persistent, since those
7730                // processes run critical code.
7731                removeProcessLocked(app, false, false, "crash");
7732                mMainStack.resumeTopActivityLocked(null);
7733                return false;
7734            }
7735            mMainStack.resumeTopActivityLocked(null);
7736        } else {
7737            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7738            if (r != null && r.app == app) {
7739                // If the top running activity is from this crashing
7740                // process, then terminate it to avoid getting in a loop.
7741                Slog.w(TAG, "  Force finishing activity "
7742                        + r.intent.getComponent().flattenToShortString());
7743                int index = mMainStack.indexOfActivityLocked(r);
7744                r.stack.finishActivityLocked(r, index,
7745                        Activity.RESULT_CANCELED, null, "crashed");
7746                // Also terminate any activities below it that aren't yet
7747                // stopped, to avoid a situation where one will get
7748                // re-start our crashing activity once it gets resumed again.
7749                index--;
7750                if (index >= 0) {
7751                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7752                    if (r.state == ActivityState.RESUMED
7753                            || r.state == ActivityState.PAUSING
7754                            || r.state == ActivityState.PAUSED) {
7755                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7756                            Slog.w(TAG, "  Force finishing activity "
7757                                    + r.intent.getComponent().flattenToShortString());
7758                            r.stack.finishActivityLocked(r, index,
7759                                    Activity.RESULT_CANCELED, null, "crashed");
7760                        }
7761                    }
7762                }
7763            }
7764        }
7765
7766        // Bump up the crash count of any services currently running in the proc.
7767        if (app.services.size() != 0) {
7768            // Any services running in the application need to be placed
7769            // back in the pending list.
7770            Iterator<ServiceRecord> it = app.services.iterator();
7771            while (it.hasNext()) {
7772                ServiceRecord sr = it.next();
7773                sr.crashCount++;
7774            }
7775        }
7776
7777        // If the crashing process is what we consider to be the "home process" and it has been
7778        // replaced by a third-party app, clear the package preferred activities from packages
7779        // with a home activity running in the process to prevent a repeatedly crashing app
7780        // from blocking the user to manually clear the list.
7781        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7782                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7783            Iterator it = mHomeProcess.activities.iterator();
7784            while (it.hasNext()) {
7785                ActivityRecord r = (ActivityRecord)it.next();
7786                if (r.isHomeActivity) {
7787                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7788                    try {
7789                        ActivityThread.getPackageManager()
7790                                .clearPackagePreferredActivities(r.packageName);
7791                    } catch (RemoteException c) {
7792                        // pm is in same process, this will never happen.
7793                    }
7794                }
7795            }
7796        }
7797
7798        if (!app.isolated) {
7799            // XXX Can't keep track of crash times for isolated processes,
7800            // because they don't have a perisistent identity.
7801            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7802        }
7803
7804        return true;
7805    }
7806
7807    void startAppProblemLocked(ProcessRecord app) {
7808        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7809                mContext, app.info.packageName, app.info.flags);
7810        skipCurrentReceiverLocked(app);
7811    }
7812
7813    void skipCurrentReceiverLocked(ProcessRecord app) {
7814        for (BroadcastQueue queue : mBroadcastQueues) {
7815            queue.skipCurrentReceiverLocked(app);
7816        }
7817    }
7818
7819    /**
7820     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7821     * The application process will exit immediately after this call returns.
7822     * @param app object of the crashing app, null for the system server
7823     * @param crashInfo describing the exception
7824     */
7825    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7826        ProcessRecord r = findAppProcess(app, "Crash");
7827        final String processName = app == null ? "system_server"
7828                : (r == null ? "unknown" : r.processName);
7829
7830        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7831                processName,
7832                r == null ? -1 : r.info.flags,
7833                crashInfo.exceptionClassName,
7834                crashInfo.exceptionMessage,
7835                crashInfo.throwFileName,
7836                crashInfo.throwLineNumber);
7837
7838        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7839
7840        crashApplication(r, crashInfo);
7841    }
7842
7843    public void handleApplicationStrictModeViolation(
7844            IBinder app,
7845            int violationMask,
7846            StrictMode.ViolationInfo info) {
7847        ProcessRecord r = findAppProcess(app, "StrictMode");
7848        if (r == null) {
7849            return;
7850        }
7851
7852        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7853            Integer stackFingerprint = info.hashCode();
7854            boolean logIt = true;
7855            synchronized (mAlreadyLoggedViolatedStacks) {
7856                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7857                    logIt = false;
7858                    // TODO: sub-sample into EventLog for these, with
7859                    // the info.durationMillis?  Then we'd get
7860                    // the relative pain numbers, without logging all
7861                    // the stack traces repeatedly.  We'd want to do
7862                    // likewise in the client code, which also does
7863                    // dup suppression, before the Binder call.
7864                } else {
7865                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7866                        mAlreadyLoggedViolatedStacks.clear();
7867                    }
7868                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7869                }
7870            }
7871            if (logIt) {
7872                logStrictModeViolationToDropBox(r, info);
7873            }
7874        }
7875
7876        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7877            AppErrorResult result = new AppErrorResult();
7878            synchronized (this) {
7879                final long origId = Binder.clearCallingIdentity();
7880
7881                Message msg = Message.obtain();
7882                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7883                HashMap<String, Object> data = new HashMap<String, Object>();
7884                data.put("result", result);
7885                data.put("app", r);
7886                data.put("violationMask", violationMask);
7887                data.put("info", info);
7888                msg.obj = data;
7889                mHandler.sendMessage(msg);
7890
7891                Binder.restoreCallingIdentity(origId);
7892            }
7893            int res = result.get();
7894            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7895        }
7896    }
7897
7898    // Depending on the policy in effect, there could be a bunch of
7899    // these in quick succession so we try to batch these together to
7900    // minimize disk writes, number of dropbox entries, and maximize
7901    // compression, by having more fewer, larger records.
7902    private void logStrictModeViolationToDropBox(
7903            ProcessRecord process,
7904            StrictMode.ViolationInfo info) {
7905        if (info == null) {
7906            return;
7907        }
7908        final boolean isSystemApp = process == null ||
7909                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7910                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7911        final String processName = process == null ? "unknown" : process.processName;
7912        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7913        final DropBoxManager dbox = (DropBoxManager)
7914                mContext.getSystemService(Context.DROPBOX_SERVICE);
7915
7916        // Exit early if the dropbox isn't configured to accept this report type.
7917        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7918
7919        boolean bufferWasEmpty;
7920        boolean needsFlush;
7921        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7922        synchronized (sb) {
7923            bufferWasEmpty = sb.length() == 0;
7924            appendDropBoxProcessHeaders(process, processName, sb);
7925            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7926            sb.append("System-App: ").append(isSystemApp).append("\n");
7927            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7928            if (info.violationNumThisLoop != 0) {
7929                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7930            }
7931            if (info.numAnimationsRunning != 0) {
7932                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7933            }
7934            if (info.broadcastIntentAction != null) {
7935                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7936            }
7937            if (info.durationMillis != -1) {
7938                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7939            }
7940            if (info.numInstances != -1) {
7941                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7942            }
7943            if (info.tags != null) {
7944                for (String tag : info.tags) {
7945                    sb.append("Span-Tag: ").append(tag).append("\n");
7946                }
7947            }
7948            sb.append("\n");
7949            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7950                sb.append(info.crashInfo.stackTrace);
7951            }
7952            sb.append("\n");
7953
7954            // Only buffer up to ~64k.  Various logging bits truncate
7955            // things at 128k.
7956            needsFlush = (sb.length() > 64 * 1024);
7957        }
7958
7959        // Flush immediately if the buffer's grown too large, or this
7960        // is a non-system app.  Non-system apps are isolated with a
7961        // different tag & policy and not batched.
7962        //
7963        // Batching is useful during internal testing with
7964        // StrictMode settings turned up high.  Without batching,
7965        // thousands of separate files could be created on boot.
7966        if (!isSystemApp || needsFlush) {
7967            new Thread("Error dump: " + dropboxTag) {
7968                @Override
7969                public void run() {
7970                    String report;
7971                    synchronized (sb) {
7972                        report = sb.toString();
7973                        sb.delete(0, sb.length());
7974                        sb.trimToSize();
7975                    }
7976                    if (report.length() != 0) {
7977                        dbox.addText(dropboxTag, report);
7978                    }
7979                }
7980            }.start();
7981            return;
7982        }
7983
7984        // System app batching:
7985        if (!bufferWasEmpty) {
7986            // An existing dropbox-writing thread is outstanding, so
7987            // we don't need to start it up.  The existing thread will
7988            // catch the buffer appends we just did.
7989            return;
7990        }
7991
7992        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7993        // (After this point, we shouldn't access AMS internal data structures.)
7994        new Thread("Error dump: " + dropboxTag) {
7995            @Override
7996            public void run() {
7997                // 5 second sleep to let stacks arrive and be batched together
7998                try {
7999                    Thread.sleep(5000);  // 5 seconds
8000                } catch (InterruptedException e) {}
8001
8002                String errorReport;
8003                synchronized (mStrictModeBuffer) {
8004                    errorReport = mStrictModeBuffer.toString();
8005                    if (errorReport.length() == 0) {
8006                        return;
8007                    }
8008                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8009                    mStrictModeBuffer.trimToSize();
8010                }
8011                dbox.addText(dropboxTag, errorReport);
8012            }
8013        }.start();
8014    }
8015
8016    /**
8017     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8018     * @param app object of the crashing app, null for the system server
8019     * @param tag reported by the caller
8020     * @param crashInfo describing the context of the error
8021     * @return true if the process should exit immediately (WTF is fatal)
8022     */
8023    public boolean handleApplicationWtf(IBinder app, String tag,
8024            ApplicationErrorReport.CrashInfo crashInfo) {
8025        ProcessRecord r = findAppProcess(app, "WTF");
8026        final String processName = app == null ? "system_server"
8027                : (r == null ? "unknown" : r.processName);
8028
8029        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8030                processName,
8031                r == null ? -1 : r.info.flags,
8032                tag, crashInfo.exceptionMessage);
8033
8034        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8035
8036        if (r != null && r.pid != Process.myPid() &&
8037                Settings.Secure.getInt(mContext.getContentResolver(),
8038                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8039            crashApplication(r, crashInfo);
8040            return true;
8041        } else {
8042            return false;
8043        }
8044    }
8045
8046    /**
8047     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8048     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8049     */
8050    private ProcessRecord findAppProcess(IBinder app, String reason) {
8051        if (app == null) {
8052            return null;
8053        }
8054
8055        synchronized (this) {
8056            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8057                final int NA = apps.size();
8058                for (int ia=0; ia<NA; ia++) {
8059                    ProcessRecord p = apps.valueAt(ia);
8060                    if (p.thread != null && p.thread.asBinder() == app) {
8061                        return p;
8062                    }
8063                }
8064            }
8065
8066            Slog.w(TAG, "Can't find mystery application for " + reason
8067                    + " from pid=" + Binder.getCallingPid()
8068                    + " uid=" + Binder.getCallingUid() + ": " + app);
8069            return null;
8070        }
8071    }
8072
8073    /**
8074     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8075     * to append various headers to the dropbox log text.
8076     */
8077    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8078            StringBuilder sb) {
8079        // Watchdog thread ends up invoking this function (with
8080        // a null ProcessRecord) to add the stack file to dropbox.
8081        // Do not acquire a lock on this (am) in such cases, as it
8082        // could cause a potential deadlock, if and when watchdog
8083        // is invoked due to unavailability of lock on am and it
8084        // would prevent watchdog from killing system_server.
8085        if (process == null) {
8086            sb.append("Process: ").append(processName).append("\n");
8087            return;
8088        }
8089        // Note: ProcessRecord 'process' is guarded by the service
8090        // instance.  (notably process.pkgList, which could otherwise change
8091        // concurrently during execution of this method)
8092        synchronized (this) {
8093            sb.append("Process: ").append(processName).append("\n");
8094            int flags = process.info.flags;
8095            IPackageManager pm = AppGlobals.getPackageManager();
8096            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8097            for (String pkg : process.pkgList) {
8098                sb.append("Package: ").append(pkg);
8099                try {
8100                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8101                    if (pi != null) {
8102                        sb.append(" v").append(pi.versionCode);
8103                        if (pi.versionName != null) {
8104                            sb.append(" (").append(pi.versionName).append(")");
8105                        }
8106                    }
8107                } catch (RemoteException e) {
8108                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8109                }
8110                sb.append("\n");
8111            }
8112        }
8113    }
8114
8115    private static String processClass(ProcessRecord process) {
8116        if (process == null || process.pid == MY_PID) {
8117            return "system_server";
8118        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8119            return "system_app";
8120        } else {
8121            return "data_app";
8122        }
8123    }
8124
8125    /**
8126     * Write a description of an error (crash, WTF, ANR) to the drop box.
8127     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8128     * @param process which caused the error, null means the system server
8129     * @param activity which triggered the error, null if unknown
8130     * @param parent activity related to the error, null if unknown
8131     * @param subject line related to the error, null if absent
8132     * @param report in long form describing the error, null if absent
8133     * @param logFile to include in the report, null if none
8134     * @param crashInfo giving an application stack trace, null if absent
8135     */
8136    public void addErrorToDropBox(String eventType,
8137            ProcessRecord process, String processName, ActivityRecord activity,
8138            ActivityRecord parent, String subject,
8139            final String report, final File logFile,
8140            final ApplicationErrorReport.CrashInfo crashInfo) {
8141        // NOTE -- this must never acquire the ActivityManagerService lock,
8142        // otherwise the watchdog may be prevented from resetting the system.
8143
8144        final String dropboxTag = processClass(process) + "_" + eventType;
8145        final DropBoxManager dbox = (DropBoxManager)
8146                mContext.getSystemService(Context.DROPBOX_SERVICE);
8147
8148        // Exit early if the dropbox isn't configured to accept this report type.
8149        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8150
8151        final StringBuilder sb = new StringBuilder(1024);
8152        appendDropBoxProcessHeaders(process, processName, sb);
8153        if (activity != null) {
8154            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8155        }
8156        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8157            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8158        }
8159        if (parent != null && parent != activity) {
8160            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8161        }
8162        if (subject != null) {
8163            sb.append("Subject: ").append(subject).append("\n");
8164        }
8165        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8166        if (Debug.isDebuggerConnected()) {
8167            sb.append("Debugger: Connected\n");
8168        }
8169        sb.append("\n");
8170
8171        // Do the rest in a worker thread to avoid blocking the caller on I/O
8172        // (After this point, we shouldn't access AMS internal data structures.)
8173        Thread worker = new Thread("Error dump: " + dropboxTag) {
8174            @Override
8175            public void run() {
8176                if (report != null) {
8177                    sb.append(report);
8178                }
8179                if (logFile != null) {
8180                    try {
8181                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8182                    } catch (IOException e) {
8183                        Slog.e(TAG, "Error reading " + logFile, e);
8184                    }
8185                }
8186                if (crashInfo != null && crashInfo.stackTrace != null) {
8187                    sb.append(crashInfo.stackTrace);
8188                }
8189
8190                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8191                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8192                if (lines > 0) {
8193                    sb.append("\n");
8194
8195                    // Merge several logcat streams, and take the last N lines
8196                    InputStreamReader input = null;
8197                    try {
8198                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8199                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8200                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8201
8202                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8203                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8204                        input = new InputStreamReader(logcat.getInputStream());
8205
8206                        int num;
8207                        char[] buf = new char[8192];
8208                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8209                    } catch (IOException e) {
8210                        Slog.e(TAG, "Error running logcat", e);
8211                    } finally {
8212                        if (input != null) try { input.close(); } catch (IOException e) {}
8213                    }
8214                }
8215
8216                dbox.addText(dropboxTag, sb.toString());
8217            }
8218        };
8219
8220        if (process == null) {
8221            // If process is null, we are being called from some internal code
8222            // and may be about to die -- run this synchronously.
8223            worker.run();
8224        } else {
8225            worker.start();
8226        }
8227    }
8228
8229    /**
8230     * Bring up the "unexpected error" dialog box for a crashing app.
8231     * Deal with edge cases (intercepts from instrumented applications,
8232     * ActivityController, error intent receivers, that sort of thing).
8233     * @param r the application crashing
8234     * @param crashInfo describing the failure
8235     */
8236    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8237        long timeMillis = System.currentTimeMillis();
8238        String shortMsg = crashInfo.exceptionClassName;
8239        String longMsg = crashInfo.exceptionMessage;
8240        String stackTrace = crashInfo.stackTrace;
8241        if (shortMsg != null && longMsg != null) {
8242            longMsg = shortMsg + ": " + longMsg;
8243        } else if (shortMsg != null) {
8244            longMsg = shortMsg;
8245        }
8246
8247        AppErrorResult result = new AppErrorResult();
8248        synchronized (this) {
8249            if (mController != null) {
8250                try {
8251                    String name = r != null ? r.processName : null;
8252                    int pid = r != null ? r.pid : Binder.getCallingPid();
8253                    if (!mController.appCrashed(name, pid,
8254                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8255                        Slog.w(TAG, "Force-killing crashed app " + name
8256                                + " at watcher's request");
8257                        Process.killProcess(pid);
8258                        return;
8259                    }
8260                } catch (RemoteException e) {
8261                    mController = null;
8262                }
8263            }
8264
8265            final long origId = Binder.clearCallingIdentity();
8266
8267            // If this process is running instrumentation, finish it.
8268            if (r != null && r.instrumentationClass != null) {
8269                Slog.w(TAG, "Error in app " + r.processName
8270                      + " running instrumentation " + r.instrumentationClass + ":");
8271                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8272                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8273                Bundle info = new Bundle();
8274                info.putString("shortMsg", shortMsg);
8275                info.putString("longMsg", longMsg);
8276                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8277                Binder.restoreCallingIdentity(origId);
8278                return;
8279            }
8280
8281            // If we can't identify the process or it's already exceeded its crash quota,
8282            // quit right away without showing a crash dialog.
8283            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8284                Binder.restoreCallingIdentity(origId);
8285                return;
8286            }
8287
8288            Message msg = Message.obtain();
8289            msg.what = SHOW_ERROR_MSG;
8290            HashMap data = new HashMap();
8291            data.put("result", result);
8292            data.put("app", r);
8293            msg.obj = data;
8294            mHandler.sendMessage(msg);
8295
8296            Binder.restoreCallingIdentity(origId);
8297        }
8298
8299        int res = result.get();
8300
8301        Intent appErrorIntent = null;
8302        synchronized (this) {
8303            if (r != null && !r.isolated) {
8304                // XXX Can't keep track of crash time for isolated processes,
8305                // since they don't have a persistent identity.
8306                mProcessCrashTimes.put(r.info.processName, r.uid,
8307                        SystemClock.uptimeMillis());
8308            }
8309            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8310                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8311            }
8312        }
8313
8314        if (appErrorIntent != null) {
8315            try {
8316                mContext.startActivity(appErrorIntent);
8317            } catch (ActivityNotFoundException e) {
8318                Slog.w(TAG, "bug report receiver dissappeared", e);
8319            }
8320        }
8321    }
8322
8323    Intent createAppErrorIntentLocked(ProcessRecord r,
8324            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8325        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8326        if (report == null) {
8327            return null;
8328        }
8329        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8330        result.setComponent(r.errorReportReceiver);
8331        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8332        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8333        return result;
8334    }
8335
8336    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8337            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8338        if (r.errorReportReceiver == null) {
8339            return null;
8340        }
8341
8342        if (!r.crashing && !r.notResponding) {
8343            return null;
8344        }
8345
8346        ApplicationErrorReport report = new ApplicationErrorReport();
8347        report.packageName = r.info.packageName;
8348        report.installerPackageName = r.errorReportReceiver.getPackageName();
8349        report.processName = r.processName;
8350        report.time = timeMillis;
8351        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8352
8353        if (r.crashing) {
8354            report.type = ApplicationErrorReport.TYPE_CRASH;
8355            report.crashInfo = crashInfo;
8356        } else if (r.notResponding) {
8357            report.type = ApplicationErrorReport.TYPE_ANR;
8358            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8359
8360            report.anrInfo.activity = r.notRespondingReport.tag;
8361            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8362            report.anrInfo.info = r.notRespondingReport.longMsg;
8363        }
8364
8365        return report;
8366    }
8367
8368    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8369        enforceNotIsolatedCaller("getProcessesInErrorState");
8370        // assume our apps are happy - lazy create the list
8371        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8372
8373        synchronized (this) {
8374
8375            // iterate across all processes
8376            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8377                ProcessRecord app = mLruProcesses.get(i);
8378                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8379                    // This one's in trouble, so we'll generate a report for it
8380                    // crashes are higher priority (in case there's a crash *and* an anr)
8381                    ActivityManager.ProcessErrorStateInfo report = null;
8382                    if (app.crashing) {
8383                        report = app.crashingReport;
8384                    } else if (app.notResponding) {
8385                        report = app.notRespondingReport;
8386                    }
8387
8388                    if (report != null) {
8389                        if (errList == null) {
8390                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8391                        }
8392                        errList.add(report);
8393                    } else {
8394                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8395                                " crashing = " + app.crashing +
8396                                " notResponding = " + app.notResponding);
8397                    }
8398                }
8399            }
8400        }
8401
8402        return errList;
8403    }
8404
8405    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8406        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8407            if (currApp != null) {
8408                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8409            }
8410            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8411        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8412            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8413        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8414            if (currApp != null) {
8415                currApp.lru = 0;
8416            }
8417            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8418        } else if (adj >= ProcessList.SERVICE_ADJ) {
8419            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8420        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8421            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8422        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8423            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8424        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8425            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8426        } else {
8427            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8428        }
8429    }
8430
8431    private void fillInProcMemInfo(ProcessRecord app,
8432            ActivityManager.RunningAppProcessInfo outInfo) {
8433        outInfo.pid = app.pid;
8434        outInfo.uid = app.info.uid;
8435        if (mHeavyWeightProcess == app) {
8436            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8437        }
8438        if (app.persistent) {
8439            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8440        }
8441        outInfo.lastTrimLevel = app.trimMemoryLevel;
8442        int adj = app.curAdj;
8443        outInfo.importance = oomAdjToImportance(adj, outInfo);
8444        outInfo.importanceReasonCode = app.adjTypeCode;
8445    }
8446
8447    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8448        enforceNotIsolatedCaller("getRunningAppProcesses");
8449        // Lazy instantiation of list
8450        List<ActivityManager.RunningAppProcessInfo> runList = null;
8451        synchronized (this) {
8452            // Iterate across all processes
8453            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8454                ProcessRecord app = mLruProcesses.get(i);
8455                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8456                    // Generate process state info for running application
8457                    ActivityManager.RunningAppProcessInfo currApp =
8458                        new ActivityManager.RunningAppProcessInfo(app.processName,
8459                                app.pid, app.getPackageList());
8460                    fillInProcMemInfo(app, currApp);
8461                    if (app.adjSource instanceof ProcessRecord) {
8462                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8463                        currApp.importanceReasonImportance = oomAdjToImportance(
8464                                app.adjSourceOom, null);
8465                    } else if (app.adjSource instanceof ActivityRecord) {
8466                        ActivityRecord r = (ActivityRecord)app.adjSource;
8467                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8468                    }
8469                    if (app.adjTarget instanceof ComponentName) {
8470                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8471                    }
8472                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8473                    //        + " lru=" + currApp.lru);
8474                    if (runList == null) {
8475                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8476                    }
8477                    runList.add(currApp);
8478                }
8479            }
8480        }
8481        return runList;
8482    }
8483
8484    public List<ApplicationInfo> getRunningExternalApplications() {
8485        enforceNotIsolatedCaller("getRunningExternalApplications");
8486        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8487        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8488        if (runningApps != null && runningApps.size() > 0) {
8489            Set<String> extList = new HashSet<String>();
8490            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8491                if (app.pkgList != null) {
8492                    for (String pkg : app.pkgList) {
8493                        extList.add(pkg);
8494                    }
8495                }
8496            }
8497            IPackageManager pm = AppGlobals.getPackageManager();
8498            for (String pkg : extList) {
8499                try {
8500                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8501                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8502                        retList.add(info);
8503                    }
8504                } catch (RemoteException e) {
8505                }
8506            }
8507        }
8508        return retList;
8509    }
8510
8511    @Override
8512    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8513        enforceNotIsolatedCaller("getMyMemoryState");
8514        synchronized (this) {
8515            ProcessRecord proc;
8516            synchronized (mPidsSelfLocked) {
8517                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8518            }
8519            fillInProcMemInfo(proc, outInfo);
8520        }
8521    }
8522
8523    @Override
8524    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8525        if (checkCallingPermission(android.Manifest.permission.DUMP)
8526                != PackageManager.PERMISSION_GRANTED) {
8527            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8528                    + Binder.getCallingPid()
8529                    + ", uid=" + Binder.getCallingUid()
8530                    + " without permission "
8531                    + android.Manifest.permission.DUMP);
8532            return;
8533        }
8534
8535        boolean dumpAll = false;
8536        boolean dumpClient = false;
8537        String dumpPackage = null;
8538
8539        int opti = 0;
8540        while (opti < args.length) {
8541            String opt = args[opti];
8542            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8543                break;
8544            }
8545            opti++;
8546            if ("-a".equals(opt)) {
8547                dumpAll = true;
8548            } else if ("-c".equals(opt)) {
8549                dumpClient = true;
8550            } else if ("-h".equals(opt)) {
8551                pw.println("Activity manager dump options:");
8552                pw.println("  [-a] [-c] [-h] [cmd] ...");
8553                pw.println("  cmd may be one of:");
8554                pw.println("    a[ctivities]: activity stack state");
8555                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8556                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8557                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8558                pw.println("    o[om]: out of memory management");
8559                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8560                pw.println("    provider [COMP_SPEC]: provider client-side state");
8561                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8562                pw.println("    service [COMP_SPEC]: service client-side state");
8563                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8564                pw.println("    all: dump all activities");
8565                pw.println("    top: dump the top activity");
8566                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8567                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8568                pw.println("    a partial substring in a component name, a");
8569                pw.println("    hex object identifier.");
8570                pw.println("  -a: include all available server state.");
8571                pw.println("  -c: include client state.");
8572                return;
8573            } else {
8574                pw.println("Unknown argument: " + opt + "; use -h for help");
8575            }
8576        }
8577
8578        long origId = Binder.clearCallingIdentity();
8579        boolean more = false;
8580        // Is the caller requesting to dump a particular piece of data?
8581        if (opti < args.length) {
8582            String cmd = args[opti];
8583            opti++;
8584            if ("activities".equals(cmd) || "a".equals(cmd)) {
8585                synchronized (this) {
8586                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8587                }
8588            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8589                String[] newArgs;
8590                String name;
8591                if (opti >= args.length) {
8592                    name = null;
8593                    newArgs = EMPTY_STRING_ARRAY;
8594                } else {
8595                    name = args[opti];
8596                    opti++;
8597                    newArgs = new String[args.length - opti];
8598                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8599                            args.length - opti);
8600                }
8601                synchronized (this) {
8602                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8603                }
8604            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8605                String[] newArgs;
8606                String name;
8607                if (opti >= args.length) {
8608                    name = null;
8609                    newArgs = EMPTY_STRING_ARRAY;
8610                } else {
8611                    name = args[opti];
8612                    opti++;
8613                    newArgs = new String[args.length - opti];
8614                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8615                            args.length - opti);
8616                }
8617                synchronized (this) {
8618                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8619                }
8620            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8621                String[] newArgs;
8622                String name;
8623                if (opti >= args.length) {
8624                    name = null;
8625                    newArgs = EMPTY_STRING_ARRAY;
8626                } else {
8627                    name = args[opti];
8628                    opti++;
8629                    newArgs = new String[args.length - opti];
8630                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8631                            args.length - opti);
8632                }
8633                synchronized (this) {
8634                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8635                }
8636            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8637                synchronized (this) {
8638                    dumpOomLocked(fd, pw, args, opti, true);
8639                }
8640            } else if ("provider".equals(cmd)) {
8641                String[] newArgs;
8642                String name;
8643                if (opti >= args.length) {
8644                    name = null;
8645                    newArgs = EMPTY_STRING_ARRAY;
8646                } else {
8647                    name = args[opti];
8648                    opti++;
8649                    newArgs = new String[args.length - opti];
8650                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8651                }
8652                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8653                    pw.println("No providers match: " + name);
8654                    pw.println("Use -h for help.");
8655                }
8656            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8657                synchronized (this) {
8658                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8659                }
8660            } else if ("service".equals(cmd)) {
8661                String[] newArgs;
8662                String name;
8663                if (opti >= args.length) {
8664                    name = null;
8665                    newArgs = EMPTY_STRING_ARRAY;
8666                } else {
8667                    name = args[opti];
8668                    opti++;
8669                    newArgs = new String[args.length - opti];
8670                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8671                            args.length - opti);
8672                }
8673                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8674                    pw.println("No services match: " + name);
8675                    pw.println("Use -h for help.");
8676                }
8677            } else if ("package".equals(cmd)) {
8678                String[] newArgs;
8679                if (opti >= args.length) {
8680                    pw.println("package: no package name specified");
8681                    pw.println("Use -h for help.");
8682                } else {
8683                    dumpPackage = args[opti];
8684                    opti++;
8685                    newArgs = new String[args.length - opti];
8686                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8687                            args.length - opti);
8688                    args = newArgs;
8689                    opti = 0;
8690                    more = true;
8691                }
8692            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8693                synchronized (this) {
8694                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8695                }
8696            } else {
8697                // Dumping a single activity?
8698                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8699                    pw.println("Bad activity command, or no activities match: " + cmd);
8700                    pw.println("Use -h for help.");
8701                }
8702            }
8703            if (!more) {
8704                Binder.restoreCallingIdentity(origId);
8705                return;
8706            }
8707        }
8708
8709        // No piece of data specified, dump everything.
8710        synchronized (this) {
8711            boolean needSep;
8712            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8713            if (needSep) {
8714                pw.println(" ");
8715            }
8716            if (dumpAll) {
8717                pw.println("-------------------------------------------------------------------------------");
8718            }
8719            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8720            if (needSep) {
8721                pw.println(" ");
8722            }
8723            if (dumpAll) {
8724                pw.println("-------------------------------------------------------------------------------");
8725            }
8726            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8727            if (needSep) {
8728                pw.println(" ");
8729            }
8730            if (dumpAll) {
8731                pw.println("-------------------------------------------------------------------------------");
8732            }
8733            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8734            if (needSep) {
8735                pw.println(" ");
8736            }
8737            if (dumpAll) {
8738                pw.println("-------------------------------------------------------------------------------");
8739            }
8740            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8741            if (needSep) {
8742                pw.println(" ");
8743            }
8744            if (dumpAll) {
8745                pw.println("-------------------------------------------------------------------------------");
8746            }
8747            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8748        }
8749        Binder.restoreCallingIdentity(origId);
8750    }
8751
8752    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8753            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8754        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8755        pw.println("  Main stack:");
8756        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8757                dumpPackage);
8758        pw.println(" ");
8759        pw.println("  Running activities (most recent first):");
8760        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8761                dumpPackage);
8762        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8763            pw.println(" ");
8764            pw.println("  Activities waiting for another to become visible:");
8765            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8766                    !dumpAll, false, dumpPackage);
8767        }
8768        if (mMainStack.mStoppingActivities.size() > 0) {
8769            pw.println(" ");
8770            pw.println("  Activities waiting to stop:");
8771            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8772                    !dumpAll, false, dumpPackage);
8773        }
8774        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8775            pw.println(" ");
8776            pw.println("  Activities waiting to sleep:");
8777            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8778                    !dumpAll, false, dumpPackage);
8779        }
8780        if (mMainStack.mFinishingActivities.size() > 0) {
8781            pw.println(" ");
8782            pw.println("  Activities waiting to finish:");
8783            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8784                    !dumpAll, false, dumpPackage);
8785        }
8786
8787        pw.println(" ");
8788        if (mMainStack.mPausingActivity != null) {
8789            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8790        }
8791        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8792        pw.println("  mFocusedActivity: " + mFocusedActivity);
8793        if (dumpAll) {
8794            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8795            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8796            pw.println("  mDismissKeyguardOnNextActivity: "
8797                    + mMainStack.mDismissKeyguardOnNextActivity);
8798        }
8799
8800        if (mRecentTasks.size() > 0) {
8801            pw.println();
8802            pw.println("  Recent tasks:");
8803
8804            final int N = mRecentTasks.size();
8805            for (int i=0; i<N; i++) {
8806                TaskRecord tr = mRecentTasks.get(i);
8807                if (dumpPackage != null) {
8808                    if (tr.realActivity == null ||
8809                            !dumpPackage.equals(tr.realActivity)) {
8810                        continue;
8811                    }
8812                }
8813                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8814                        pw.println(tr);
8815                if (dumpAll) {
8816                    mRecentTasks.get(i).dump(pw, "    ");
8817                }
8818            }
8819        }
8820
8821        if (dumpAll) {
8822            pw.println(" ");
8823            pw.println("  mCurTask: " + mCurTask);
8824        }
8825
8826        return true;
8827    }
8828
8829    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8830            int opti, boolean dumpAll, String dumpPackage) {
8831        boolean needSep = false;
8832        int numPers = 0;
8833
8834        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8835
8836        if (dumpAll) {
8837            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8838                final int NA = procs.size();
8839                for (int ia=0; ia<NA; ia++) {
8840                    ProcessRecord r = procs.valueAt(ia);
8841                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8842                        continue;
8843                    }
8844                    if (!needSep) {
8845                        pw.println("  All known processes:");
8846                        needSep = true;
8847                    }
8848                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8849                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8850                        pw.print(" "); pw.println(r);
8851                    r.dump(pw, "    ");
8852                    if (r.persistent) {
8853                        numPers++;
8854                    }
8855                }
8856            }
8857        }
8858
8859        if (mIsolatedProcesses.size() > 0) {
8860            if (needSep) pw.println(" ");
8861            needSep = true;
8862            pw.println("  Isolated process list (sorted by uid):");
8863            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8864                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8865                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8866                    continue;
8867                }
8868                pw.println(String.format("%sIsolated #%2d: %s",
8869                        "    ", i, r.toString()));
8870            }
8871        }
8872
8873        if (mLruProcesses.size() > 0) {
8874            if (needSep) pw.println(" ");
8875            needSep = true;
8876            pw.println("  Process LRU list (sorted by oom_adj):");
8877            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8878                    "Proc", "PERS", false, dumpPackage);
8879            needSep = true;
8880        }
8881
8882        if (dumpAll) {
8883            synchronized (mPidsSelfLocked) {
8884                boolean printed = false;
8885                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8886                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8887                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8888                        continue;
8889                    }
8890                    if (!printed) {
8891                        if (needSep) pw.println(" ");
8892                        needSep = true;
8893                        pw.println("  PID mappings:");
8894                        printed = true;
8895                    }
8896                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8897                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8898                }
8899            }
8900        }
8901
8902        if (mForegroundProcesses.size() > 0) {
8903            synchronized (mPidsSelfLocked) {
8904                boolean printed = false;
8905                for (int i=0; i<mForegroundProcesses.size(); i++) {
8906                    ProcessRecord r = mPidsSelfLocked.get(
8907                            mForegroundProcesses.valueAt(i).pid);
8908                    if (dumpPackage != null && (r == null
8909                            || !dumpPackage.equals(r.info.packageName))) {
8910                        continue;
8911                    }
8912                    if (!printed) {
8913                        if (needSep) pw.println(" ");
8914                        needSep = true;
8915                        pw.println("  Foreground Processes:");
8916                        printed = true;
8917                    }
8918                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8919                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8920                }
8921            }
8922        }
8923
8924        if (mPersistentStartingProcesses.size() > 0) {
8925            if (needSep) pw.println(" ");
8926            needSep = true;
8927            pw.println("  Persisent processes that are starting:");
8928            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8929                    "Starting Norm", "Restarting PERS", dumpPackage);
8930        }
8931
8932        if (mRemovedProcesses.size() > 0) {
8933            if (needSep) pw.println(" ");
8934            needSep = true;
8935            pw.println("  Processes that are being removed:");
8936            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8937                    "Removed Norm", "Removed PERS", dumpPackage);
8938        }
8939
8940        if (mProcessesOnHold.size() > 0) {
8941            if (needSep) pw.println(" ");
8942            needSep = true;
8943            pw.println("  Processes that are on old until the system is ready:");
8944            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8945                    "OnHold Norm", "OnHold PERS", dumpPackage);
8946        }
8947
8948        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8949
8950        if (mProcessCrashTimes.getMap().size() > 0) {
8951            boolean printed = false;
8952            long now = SystemClock.uptimeMillis();
8953            for (Map.Entry<String, SparseArray<Long>> procs
8954                    : mProcessCrashTimes.getMap().entrySet()) {
8955                String pname = procs.getKey();
8956                SparseArray<Long> uids = procs.getValue();
8957                final int N = uids.size();
8958                for (int i=0; i<N; i++) {
8959                    int puid = uids.keyAt(i);
8960                    ProcessRecord r = mProcessNames.get(pname, puid);
8961                    if (dumpPackage != null && (r == null
8962                            || !dumpPackage.equals(r.info.packageName))) {
8963                        continue;
8964                    }
8965                    if (!printed) {
8966                        if (needSep) pw.println(" ");
8967                        needSep = true;
8968                        pw.println("  Time since processes crashed:");
8969                        printed = true;
8970                    }
8971                    pw.print("    Process "); pw.print(pname);
8972                            pw.print(" uid "); pw.print(puid);
8973                            pw.print(": last crashed ");
8974                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
8975                            pw.println(" ago");
8976                }
8977            }
8978        }
8979
8980        if (mBadProcesses.getMap().size() > 0) {
8981            boolean printed = false;
8982            for (Map.Entry<String, SparseArray<Long>> procs
8983                    : mBadProcesses.getMap().entrySet()) {
8984                String pname = procs.getKey();
8985                SparseArray<Long> uids = procs.getValue();
8986                final int N = uids.size();
8987                for (int i=0; i<N; i++) {
8988                    int puid = uids.keyAt(i);
8989                    ProcessRecord r = mProcessNames.get(pname, puid);
8990                    if (dumpPackage != null && (r == null
8991                            || !dumpPackage.equals(r.info.packageName))) {
8992                        continue;
8993                    }
8994                    if (!printed) {
8995                        if (needSep) pw.println(" ");
8996                        needSep = true;
8997                        pw.println("  Bad processes:");
8998                    }
8999                    pw.print("    Bad process "); pw.print(pname);
9000                            pw.print(" uid "); pw.print(puid);
9001                            pw.print(": crashed at time ");
9002                            pw.println(uids.valueAt(i));
9003                }
9004            }
9005        }
9006
9007        pw.println();
9008        pw.println("  mHomeProcess: " + mHomeProcess);
9009        pw.println("  mPreviousProcess: " + mPreviousProcess);
9010        if (dumpAll) {
9011            StringBuilder sb = new StringBuilder(128);
9012            sb.append("  mPreviousProcessVisibleTime: ");
9013            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9014            pw.println(sb);
9015        }
9016        if (mHeavyWeightProcess != null) {
9017            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9018        }
9019        pw.println("  mConfiguration: " + mConfiguration);
9020        if (dumpAll) {
9021            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9022            if (mCompatModePackages.getPackages().size() > 0) {
9023                boolean printed = false;
9024                for (Map.Entry<String, Integer> entry
9025                        : mCompatModePackages.getPackages().entrySet()) {
9026                    String pkg = entry.getKey();
9027                    int mode = entry.getValue();
9028                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9029                        continue;
9030                    }
9031                    if (!printed) {
9032                        pw.println("  mScreenCompatPackages:");
9033                        printed = true;
9034                    }
9035                    pw.print("    "); pw.print(pkg); pw.print(": ");
9036                            pw.print(mode); pw.println();
9037                }
9038            }
9039        }
9040        if (mSleeping || mWentToSleep || mLockScreenShown) {
9041            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9042                    + " mLockScreenShown " + mLockScreenShown);
9043        }
9044        if (mShuttingDown) {
9045            pw.println("  mShuttingDown=" + mShuttingDown);
9046        }
9047        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9048                || mOrigWaitForDebugger) {
9049            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9050                    + " mDebugTransient=" + mDebugTransient
9051                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9052        }
9053        if (mOpenGlTraceApp != null) {
9054            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9055        }
9056        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9057                || mProfileFd != null) {
9058            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9059            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9060            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9061                    + mAutoStopProfiler);
9062        }
9063        if (mAlwaysFinishActivities || mController != null) {
9064            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9065                    + " mController=" + mController);
9066        }
9067        if (dumpAll) {
9068            pw.println("  Total persistent processes: " + numPers);
9069            pw.println("  mStartRunning=" + mStartRunning
9070                    + " mProcessesReady=" + mProcessesReady
9071                    + " mSystemReady=" + mSystemReady);
9072            pw.println("  mBooting=" + mBooting
9073                    + " mBooted=" + mBooted
9074                    + " mFactoryTest=" + mFactoryTest);
9075            pw.print("  mLastPowerCheckRealtime=");
9076                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9077                    pw.println("");
9078            pw.print("  mLastPowerCheckUptime=");
9079                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9080                    pw.println("");
9081            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9082            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9083            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9084            pw.println("  mNumServiceProcs=" + mNumServiceProcs
9085                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9086        }
9087
9088        return true;
9089    }
9090
9091    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9092            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9093        if (mProcessesToGc.size() > 0) {
9094            boolean printed = false;
9095            long now = SystemClock.uptimeMillis();
9096            for (int i=0; i<mProcessesToGc.size(); i++) {
9097                ProcessRecord proc = mProcessesToGc.get(i);
9098                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9099                    continue;
9100                }
9101                if (!printed) {
9102                    if (needSep) pw.println(" ");
9103                    needSep = true;
9104                    pw.println("  Processes that are waiting to GC:");
9105                    printed = true;
9106                }
9107                pw.print("    Process "); pw.println(proc);
9108                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9109                        pw.print(", last gced=");
9110                        pw.print(now-proc.lastRequestedGc);
9111                        pw.print(" ms ago, last lowMem=");
9112                        pw.print(now-proc.lastLowMemory);
9113                        pw.println(" ms ago");
9114
9115            }
9116        }
9117        return needSep;
9118    }
9119
9120    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9121            int opti, boolean dumpAll) {
9122        boolean needSep = false;
9123
9124        if (mLruProcesses.size() > 0) {
9125            if (needSep) pw.println(" ");
9126            needSep = true;
9127            pw.println("  OOM levels:");
9128            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9129            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9130            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9131            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9132            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9133            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9134            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9135            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9136            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9137            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9138            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9139            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9140            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9141
9142            if (needSep) pw.println(" ");
9143            needSep = true;
9144            pw.println("  Process OOM control:");
9145            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9146                    "Proc", "PERS", true, null);
9147            needSep = true;
9148        }
9149
9150        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9151
9152        pw.println();
9153        pw.println("  mHomeProcess: " + mHomeProcess);
9154        pw.println("  mPreviousProcess: " + mPreviousProcess);
9155        if (mHeavyWeightProcess != null) {
9156            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9157        }
9158
9159        return true;
9160    }
9161
9162    /**
9163     * There are three ways to call this:
9164     *  - no provider specified: dump all the providers
9165     *  - a flattened component name that matched an existing provider was specified as the
9166     *    first arg: dump that one provider
9167     *  - the first arg isn't the flattened component name of an existing provider:
9168     *    dump all providers whose component contains the first arg as a substring
9169     */
9170    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9171            int opti, boolean dumpAll) {
9172        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9173    }
9174
9175    static class ItemMatcher {
9176        ArrayList<ComponentName> components;
9177        ArrayList<String> strings;
9178        ArrayList<Integer> objects;
9179        boolean all;
9180
9181        ItemMatcher() {
9182            all = true;
9183        }
9184
9185        void build(String name) {
9186            ComponentName componentName = ComponentName.unflattenFromString(name);
9187            if (componentName != null) {
9188                if (components == null) {
9189                    components = new ArrayList<ComponentName>();
9190                }
9191                components.add(componentName);
9192                all = false;
9193            } else {
9194                int objectId = 0;
9195                // Not a '/' separated full component name; maybe an object ID?
9196                try {
9197                    objectId = Integer.parseInt(name, 16);
9198                    if (objects == null) {
9199                        objects = new ArrayList<Integer>();
9200                    }
9201                    objects.add(objectId);
9202                    all = false;
9203                } catch (RuntimeException e) {
9204                    // Not an integer; just do string match.
9205                    if (strings == null) {
9206                        strings = new ArrayList<String>();
9207                    }
9208                    strings.add(name);
9209                    all = false;
9210                }
9211            }
9212        }
9213
9214        int build(String[] args, int opti) {
9215            for (; opti<args.length; opti++) {
9216                String name = args[opti];
9217                if ("--".equals(name)) {
9218                    return opti+1;
9219                }
9220                build(name);
9221            }
9222            return opti;
9223        }
9224
9225        boolean match(Object object, ComponentName comp) {
9226            if (all) {
9227                return true;
9228            }
9229            if (components != null) {
9230                for (int i=0; i<components.size(); i++) {
9231                    if (components.get(i).equals(comp)) {
9232                        return true;
9233                    }
9234                }
9235            }
9236            if (objects != null) {
9237                for (int i=0; i<objects.size(); i++) {
9238                    if (System.identityHashCode(object) == objects.get(i)) {
9239                        return true;
9240                    }
9241                }
9242            }
9243            if (strings != null) {
9244                String flat = comp.flattenToString();
9245                for (int i=0; i<strings.size(); i++) {
9246                    if (flat.contains(strings.get(i))) {
9247                        return true;
9248                    }
9249                }
9250            }
9251            return false;
9252        }
9253    }
9254
9255    /**
9256     * There are three things that cmd can be:
9257     *  - a flattened component name that matches an existing activity
9258     *  - the cmd arg isn't the flattened component name of an existing activity:
9259     *    dump all activity whose component contains the cmd as a substring
9260     *  - A hex number of the ActivityRecord object instance.
9261     */
9262    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9263            int opti, boolean dumpAll) {
9264        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9265
9266        if ("all".equals(name)) {
9267            synchronized (this) {
9268                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9269                    activities.add(r1);
9270                }
9271            }
9272        } else if ("top".equals(name)) {
9273            synchronized (this) {
9274                final int N = mMainStack.mHistory.size();
9275                if (N > 0) {
9276                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9277                }
9278            }
9279        } else {
9280            ItemMatcher matcher = new ItemMatcher();
9281            matcher.build(name);
9282
9283            synchronized (this) {
9284                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9285                    if (matcher.match(r1, r1.intent.getComponent())) {
9286                        activities.add(r1);
9287                    }
9288                }
9289            }
9290        }
9291
9292        if (activities.size() <= 0) {
9293            return false;
9294        }
9295
9296        String[] newArgs = new String[args.length - opti];
9297        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9298
9299        TaskRecord lastTask = null;
9300        boolean needSep = false;
9301        for (int i=activities.size()-1; i>=0; i--) {
9302            ActivityRecord r = (ActivityRecord)activities.get(i);
9303            if (needSep) {
9304                pw.println();
9305            }
9306            needSep = true;
9307            synchronized (this) {
9308                if (lastTask != r.task) {
9309                    lastTask = r.task;
9310                    pw.print("TASK "); pw.print(lastTask.affinity);
9311                            pw.print(" id="); pw.println(lastTask.taskId);
9312                    if (dumpAll) {
9313                        lastTask.dump(pw, "  ");
9314                    }
9315                }
9316            }
9317            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9318        }
9319        return true;
9320    }
9321
9322    /**
9323     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9324     * there is a thread associated with the activity.
9325     */
9326    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9327            final ActivityRecord r, String[] args, boolean dumpAll) {
9328        String innerPrefix = prefix + "  ";
9329        synchronized (this) {
9330            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9331                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9332                    pw.print(" pid=");
9333                    if (r.app != null) pw.println(r.app.pid);
9334                    else pw.println("(not running)");
9335            if (dumpAll) {
9336                r.dump(pw, innerPrefix);
9337            }
9338        }
9339        if (r.app != null && r.app.thread != null) {
9340            // flush anything that is already in the PrintWriter since the thread is going
9341            // to write to the file descriptor directly
9342            pw.flush();
9343            try {
9344                TransferPipe tp = new TransferPipe();
9345                try {
9346                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9347                            r.appToken, innerPrefix, args);
9348                    tp.go(fd);
9349                } finally {
9350                    tp.kill();
9351                }
9352            } catch (IOException e) {
9353                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9354            } catch (RemoteException e) {
9355                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9356            }
9357        }
9358    }
9359
9360    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9361            int opti, boolean dumpAll, String dumpPackage) {
9362        boolean needSep = false;
9363
9364        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9365        if (dumpAll) {
9366            if (mRegisteredReceivers.size() > 0) {
9367                boolean printed = false;
9368                Iterator it = mRegisteredReceivers.values().iterator();
9369                while (it.hasNext()) {
9370                    ReceiverList r = (ReceiverList)it.next();
9371                    if (dumpPackage != null && (r.app == null ||
9372                            !dumpPackage.equals(r.app.info.packageName))) {
9373                        continue;
9374                    }
9375                    if (!printed) {
9376                        pw.println("  Registered Receivers:");
9377                        needSep = true;
9378                        printed = true;
9379                    }
9380                    pw.print("  * "); pw.println(r);
9381                    r.dump(pw, "    ");
9382                }
9383            }
9384
9385            if (mReceiverResolver.dump(pw, needSep ?
9386                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9387                    "    ", dumpPackage, false)) {
9388                needSep = true;
9389            }
9390        }
9391
9392        for (BroadcastQueue q : mBroadcastQueues) {
9393            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9394        }
9395
9396        needSep = true;
9397
9398        if (mStickyBroadcasts != null && dumpPackage == null) {
9399            if (needSep) {
9400                pw.println();
9401            }
9402            needSep = true;
9403            pw.println("  Sticky broadcasts:");
9404            StringBuilder sb = new StringBuilder(128);
9405            for (Map.Entry<String, ArrayList<Intent>> ent
9406                    : mStickyBroadcasts.entrySet()) {
9407                pw.print("  * Sticky action "); pw.print(ent.getKey());
9408                if (dumpAll) {
9409                    pw.println(":");
9410                    ArrayList<Intent> intents = ent.getValue();
9411                    final int N = intents.size();
9412                    for (int i=0; i<N; i++) {
9413                        sb.setLength(0);
9414                        sb.append("    Intent: ");
9415                        intents.get(i).toShortString(sb, false, true, false, false);
9416                        pw.println(sb.toString());
9417                        Bundle bundle = intents.get(i).getExtras();
9418                        if (bundle != null) {
9419                            pw.print("      ");
9420                            pw.println(bundle.toString());
9421                        }
9422                    }
9423                } else {
9424                    pw.println("");
9425                }
9426            }
9427            needSep = true;
9428        }
9429
9430        if (dumpAll) {
9431            pw.println();
9432            for (BroadcastQueue queue : mBroadcastQueues) {
9433                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9434                        + queue.mBroadcastsScheduled);
9435            }
9436            pw.println("  mHandler:");
9437            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9438            needSep = true;
9439        }
9440
9441        return needSep;
9442    }
9443
9444    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9445            int opti, boolean dumpAll, String dumpPackage) {
9446        boolean needSep = true;
9447
9448        ItemMatcher matcher = new ItemMatcher();
9449        matcher.build(args, opti);
9450
9451        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9452
9453        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9454
9455        if (mLaunchingProviders.size() > 0) {
9456            boolean printed = false;
9457            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9458                ContentProviderRecord r = mLaunchingProviders.get(i);
9459                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9460                    continue;
9461                }
9462                if (!printed) {
9463                    if (needSep) pw.println(" ");
9464                    needSep = true;
9465                    pw.println("  Launching content providers:");
9466                    printed = true;
9467                }
9468                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9469                        pw.println(r);
9470            }
9471        }
9472
9473        if (mGrantedUriPermissions.size() > 0) {
9474            if (needSep) pw.println();
9475            needSep = true;
9476            pw.println("Granted Uri Permissions:");
9477            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9478                int uid = mGrantedUriPermissions.keyAt(i);
9479                HashMap<Uri, UriPermission> perms
9480                        = mGrantedUriPermissions.valueAt(i);
9481                pw.print("  * UID "); pw.print(uid);
9482                        pw.println(" holds:");
9483                for (UriPermission perm : perms.values()) {
9484                    pw.print("    "); pw.println(perm);
9485                    if (dumpAll) {
9486                        perm.dump(pw, "      ");
9487                    }
9488                }
9489            }
9490            needSep = true;
9491        }
9492
9493        return needSep;
9494    }
9495
9496    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9497            int opti, boolean dumpAll, String dumpPackage) {
9498        boolean needSep = false;
9499
9500        if (mIntentSenderRecords.size() > 0) {
9501            boolean printed = false;
9502            Iterator<WeakReference<PendingIntentRecord>> it
9503                    = mIntentSenderRecords.values().iterator();
9504            while (it.hasNext()) {
9505                WeakReference<PendingIntentRecord> ref = it.next();
9506                PendingIntentRecord rec = ref != null ? ref.get(): null;
9507                if (dumpPackage != null && (rec == null
9508                        || !dumpPackage.equals(rec.key.packageName))) {
9509                    continue;
9510                }
9511                if (!printed) {
9512                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9513                    printed = true;
9514                }
9515                needSep = true;
9516                if (rec != null) {
9517                    pw.print("  * "); pw.println(rec);
9518                    if (dumpAll) {
9519                        rec.dump(pw, "    ");
9520                    }
9521                } else {
9522                    pw.print("  * "); pw.println(ref);
9523                }
9524            }
9525        }
9526
9527        return needSep;
9528    }
9529
9530    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9531            String prefix, String label, boolean complete, boolean brief, boolean client,
9532            String dumpPackage) {
9533        TaskRecord lastTask = null;
9534        boolean needNL = false;
9535        final String innerPrefix = prefix + "      ";
9536        final String[] args = new String[0];
9537        for (int i=list.size()-1; i>=0; i--) {
9538            final ActivityRecord r = (ActivityRecord)list.get(i);
9539            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9540                continue;
9541            }
9542            final boolean full = !brief && (complete || !r.isInHistory());
9543            if (needNL) {
9544                pw.println(" ");
9545                needNL = false;
9546            }
9547            if (lastTask != r.task) {
9548                lastTask = r.task;
9549                pw.print(prefix);
9550                pw.print(full ? "* " : "  ");
9551                pw.println(lastTask);
9552                if (full) {
9553                    lastTask.dump(pw, prefix + "  ");
9554                } else if (complete) {
9555                    // Complete + brief == give a summary.  Isn't that obvious?!?
9556                    if (lastTask.intent != null) {
9557                        pw.print(prefix); pw.print("  ");
9558                                pw.println(lastTask.intent.toInsecureStringWithClip());
9559                    }
9560                }
9561            }
9562            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9563            pw.print(" #"); pw.print(i); pw.print(": ");
9564            pw.println(r);
9565            if (full) {
9566                r.dump(pw, innerPrefix);
9567            } else if (complete) {
9568                // Complete + brief == give a summary.  Isn't that obvious?!?
9569                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9570                if (r.app != null) {
9571                    pw.print(innerPrefix); pw.println(r.app);
9572                }
9573            }
9574            if (client && r.app != null && r.app.thread != null) {
9575                // flush anything that is already in the PrintWriter since the thread is going
9576                // to write to the file descriptor directly
9577                pw.flush();
9578                try {
9579                    TransferPipe tp = new TransferPipe();
9580                    try {
9581                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9582                                r.appToken, innerPrefix, args);
9583                        // Short timeout, since blocking here can
9584                        // deadlock with the application.
9585                        tp.go(fd, 2000);
9586                    } finally {
9587                        tp.kill();
9588                    }
9589                } catch (IOException e) {
9590                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9591                } catch (RemoteException e) {
9592                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9593                }
9594                needNL = true;
9595            }
9596        }
9597    }
9598
9599    private static String buildOomTag(String prefix, String space, int val, int base) {
9600        if (val == base) {
9601            if (space == null) return prefix;
9602            return prefix + "  ";
9603        }
9604        return prefix + "+" + Integer.toString(val-base);
9605    }
9606
9607    private static final int dumpProcessList(PrintWriter pw,
9608            ActivityManagerService service, List list,
9609            String prefix, String normalLabel, String persistentLabel,
9610            String dumpPackage) {
9611        int numPers = 0;
9612        final int N = list.size()-1;
9613        for (int i=N; i>=0; i--) {
9614            ProcessRecord r = (ProcessRecord)list.get(i);
9615            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9616                continue;
9617            }
9618            pw.println(String.format("%s%s #%2d: %s",
9619                    prefix, (r.persistent ? persistentLabel : normalLabel),
9620                    i, r.toString()));
9621            if (r.persistent) {
9622                numPers++;
9623            }
9624        }
9625        return numPers;
9626    }
9627
9628    private static final boolean dumpProcessOomList(PrintWriter pw,
9629            ActivityManagerService service, List<ProcessRecord> origList,
9630            String prefix, String normalLabel, String persistentLabel,
9631            boolean inclDetails, String dumpPackage) {
9632
9633        ArrayList<Pair<ProcessRecord, Integer>> list
9634                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9635        for (int i=0; i<origList.size(); i++) {
9636            ProcessRecord r = origList.get(i);
9637            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9638                continue;
9639            }
9640            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9641        }
9642
9643        if (list.size() <= 0) {
9644            return false;
9645        }
9646
9647        Comparator<Pair<ProcessRecord, Integer>> comparator
9648                = new Comparator<Pair<ProcessRecord, Integer>>() {
9649            @Override
9650            public int compare(Pair<ProcessRecord, Integer> object1,
9651                    Pair<ProcessRecord, Integer> object2) {
9652                if (object1.first.setAdj != object2.first.setAdj) {
9653                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9654                }
9655                if (object1.second.intValue() != object2.second.intValue()) {
9656                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9657                }
9658                return 0;
9659            }
9660        };
9661
9662        Collections.sort(list, comparator);
9663
9664        final long curRealtime = SystemClock.elapsedRealtime();
9665        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9666        final long curUptime = SystemClock.uptimeMillis();
9667        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9668
9669        for (int i=list.size()-1; i>=0; i--) {
9670            ProcessRecord r = list.get(i).first;
9671            String oomAdj;
9672            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9673                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9674            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9675                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9676            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9677                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9678            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9679                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9680            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9681                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9682            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9683                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9684            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9685                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9686            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9687                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9688            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9689                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9690            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9691                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9692            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9693                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9694            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9695                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9696            } else {
9697                oomAdj = Integer.toString(r.setAdj);
9698            }
9699            String schedGroup;
9700            switch (r.setSchedGroup) {
9701                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9702                    schedGroup = "B";
9703                    break;
9704                case Process.THREAD_GROUP_DEFAULT:
9705                    schedGroup = "F";
9706                    break;
9707                default:
9708                    schedGroup = Integer.toString(r.setSchedGroup);
9709                    break;
9710            }
9711            String foreground;
9712            if (r.foregroundActivities) {
9713                foreground = "A";
9714            } else if (r.foregroundServices) {
9715                foreground = "S";
9716            } else {
9717                foreground = " ";
9718            }
9719            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9720                    prefix, (r.persistent ? persistentLabel : normalLabel),
9721                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9722                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9723            if (r.adjSource != null || r.adjTarget != null) {
9724                pw.print(prefix);
9725                pw.print("    ");
9726                if (r.adjTarget instanceof ComponentName) {
9727                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9728                } else if (r.adjTarget != null) {
9729                    pw.print(r.adjTarget.toString());
9730                } else {
9731                    pw.print("{null}");
9732                }
9733                pw.print("<=");
9734                if (r.adjSource instanceof ProcessRecord) {
9735                    pw.print("Proc{");
9736                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9737                    pw.println("}");
9738                } else if (r.adjSource != null) {
9739                    pw.println(r.adjSource.toString());
9740                } else {
9741                    pw.println("{null}");
9742                }
9743            }
9744            if (inclDetails) {
9745                pw.print(prefix);
9746                pw.print("    ");
9747                pw.print("oom: max="); pw.print(r.maxAdj);
9748                pw.print(" hidden="); pw.print(r.hiddenAdj);
9749                pw.print(" curRaw="); pw.print(r.curRawAdj);
9750                pw.print(" setRaw="); pw.print(r.setRawAdj);
9751                pw.print(" cur="); pw.print(r.curAdj);
9752                pw.print(" set="); pw.println(r.setAdj);
9753                pw.print(prefix);
9754                pw.print("    ");
9755                pw.print("keeping="); pw.print(r.keeping);
9756                pw.print(" hidden="); pw.print(r.hidden);
9757                pw.print(" empty="); pw.print(r.empty);
9758                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9759
9760                if (!r.keeping) {
9761                    if (r.lastWakeTime != 0) {
9762                        long wtime;
9763                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9764                        synchronized (stats) {
9765                            wtime = stats.getProcessWakeTime(r.info.uid,
9766                                    r.pid, curRealtime);
9767                        }
9768                        long timeUsed = wtime - r.lastWakeTime;
9769                        pw.print(prefix);
9770                        pw.print("    ");
9771                        pw.print("keep awake over ");
9772                        TimeUtils.formatDuration(realtimeSince, pw);
9773                        pw.print(" used ");
9774                        TimeUtils.formatDuration(timeUsed, pw);
9775                        pw.print(" (");
9776                        pw.print((timeUsed*100)/realtimeSince);
9777                        pw.println("%)");
9778                    }
9779                    if (r.lastCpuTime != 0) {
9780                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9781                        pw.print(prefix);
9782                        pw.print("    ");
9783                        pw.print("run cpu over ");
9784                        TimeUtils.formatDuration(uptimeSince, pw);
9785                        pw.print(" used ");
9786                        TimeUtils.formatDuration(timeUsed, pw);
9787                        pw.print(" (");
9788                        pw.print((timeUsed*100)/uptimeSince);
9789                        pw.println("%)");
9790                    }
9791                }
9792            }
9793        }
9794        return true;
9795    }
9796
9797    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9798        ArrayList<ProcessRecord> procs;
9799        synchronized (this) {
9800            if (args != null && args.length > start
9801                    && args[start].charAt(0) != '-') {
9802                procs = new ArrayList<ProcessRecord>();
9803                int pid = -1;
9804                try {
9805                    pid = Integer.parseInt(args[start]);
9806                } catch (NumberFormatException e) {
9807
9808                }
9809                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9810                    ProcessRecord proc = mLruProcesses.get(i);
9811                    if (proc.pid == pid) {
9812                        procs.add(proc);
9813                    } else if (proc.processName.equals(args[start])) {
9814                        procs.add(proc);
9815                    }
9816                }
9817                if (procs.size() <= 0) {
9818                    pw.println("No process found for: " + args[start]);
9819                    return null;
9820                }
9821            } else {
9822                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9823            }
9824        }
9825        return procs;
9826    }
9827
9828    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9829            PrintWriter pw, String[] args) {
9830        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9831        if (procs == null) {
9832            return;
9833        }
9834
9835        long uptime = SystemClock.uptimeMillis();
9836        long realtime = SystemClock.elapsedRealtime();
9837        pw.println("Applications Graphics Acceleration Info:");
9838        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9839
9840        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9841            ProcessRecord r = procs.get(i);
9842            if (r.thread != null) {
9843                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9844                pw.flush();
9845                try {
9846                    TransferPipe tp = new TransferPipe();
9847                    try {
9848                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9849                        tp.go(fd);
9850                    } finally {
9851                        tp.kill();
9852                    }
9853                } catch (IOException e) {
9854                    pw.println("Failure while dumping the app: " + r);
9855                    pw.flush();
9856                } catch (RemoteException e) {
9857                    pw.println("Got a RemoteException while dumping the app " + r);
9858                    pw.flush();
9859                }
9860            }
9861        }
9862    }
9863
9864    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9865        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9866        if (procs == null) {
9867            return;
9868        }
9869
9870        pw.println("Applications Database Info:");
9871
9872        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9873            ProcessRecord r = procs.get(i);
9874            if (r.thread != null) {
9875                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9876                pw.flush();
9877                try {
9878                    TransferPipe tp = new TransferPipe();
9879                    try {
9880                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9881                        tp.go(fd);
9882                    } finally {
9883                        tp.kill();
9884                    }
9885                } catch (IOException e) {
9886                    pw.println("Failure while dumping the app: " + r);
9887                    pw.flush();
9888                } catch (RemoteException e) {
9889                    pw.println("Got a RemoteException while dumping the app " + r);
9890                    pw.flush();
9891                }
9892            }
9893        }
9894    }
9895
9896    final static class MemItem {
9897        final String label;
9898        final String shortLabel;
9899        final long pss;
9900        final int id;
9901        ArrayList<MemItem> subitems;
9902
9903        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9904            label = _label;
9905            shortLabel = _shortLabel;
9906            pss = _pss;
9907            id = _id;
9908        }
9909    }
9910
9911    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9912            boolean sort) {
9913        if (sort) {
9914            Collections.sort(items, new Comparator<MemItem>() {
9915                @Override
9916                public int compare(MemItem lhs, MemItem rhs) {
9917                    if (lhs.pss < rhs.pss) {
9918                        return 1;
9919                    } else if (lhs.pss > rhs.pss) {
9920                        return -1;
9921                    }
9922                    return 0;
9923                }
9924            });
9925        }
9926
9927        for (int i=0; i<items.size(); i++) {
9928            MemItem mi = items.get(i);
9929            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9930            if (mi.subitems != null) {
9931                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9932            }
9933        }
9934    }
9935
9936    // These are in KB.
9937    static final long[] DUMP_MEM_BUCKETS = new long[] {
9938        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9939        120*1024, 160*1024, 200*1024,
9940        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9941        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9942    };
9943
9944    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9945            boolean stackLike) {
9946        int start = label.lastIndexOf('.');
9947        if (start >= 0) start++;
9948        else start = 0;
9949        int end = label.length();
9950        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9951            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9952                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9953                out.append(bucket);
9954                out.append(stackLike ? "MB." : "MB ");
9955                out.append(label, start, end);
9956                return;
9957            }
9958        }
9959        out.append(memKB/1024);
9960        out.append(stackLike ? "MB." : "MB ");
9961        out.append(label, start, end);
9962    }
9963
9964    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9965            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9966            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9967            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9968            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9969    };
9970    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9971            "System", "Persistent", "Foreground",
9972            "Visible", "Perceptible", "Heavy Weight",
9973            "Backup", "A Services", "Home", "Previous",
9974            "B Services", "Background"
9975    };
9976
9977    final void dumpApplicationMemoryUsage(FileDescriptor fd,
9978            PrintWriter pw, String prefix, String[] args, boolean brief,
9979            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
9980        boolean dumpAll = false;
9981        boolean oomOnly = false;
9982
9983        int opti = 0;
9984        while (opti < args.length) {
9985            String opt = args[opti];
9986            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9987                break;
9988            }
9989            opti++;
9990            if ("-a".equals(opt)) {
9991                dumpAll = true;
9992            } else if ("--oom".equals(opt)) {
9993                oomOnly = true;
9994            } else if ("-h".equals(opt)) {
9995                pw.println("meminfo dump options: [-a] [--oom] [process]");
9996                pw.println("  -a: include all available information for each process.");
9997                pw.println("  --oom: only show processes organized by oom adj.");
9998                pw.println("If [process] is specified it can be the name or ");
9999                pw.println("pid of a specific process to dump.");
10000                return;
10001            } else {
10002                pw.println("Unknown argument: " + opt + "; use -h for help");
10003            }
10004        }
10005
10006        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10007        if (procs == null) {
10008            return;
10009        }
10010
10011        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10012        long uptime = SystemClock.uptimeMillis();
10013        long realtime = SystemClock.elapsedRealtime();
10014
10015        if (procs.size() == 1 || isCheckinRequest) {
10016            dumpAll = true;
10017        }
10018
10019        if (isCheckinRequest) {
10020            // short checkin version
10021            pw.println(uptime + "," + realtime);
10022            pw.flush();
10023        } else {
10024            pw.println("Applications Memory Usage (kB):");
10025            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10026        }
10027
10028        String[] innerArgs = new String[args.length-opti];
10029        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10030
10031        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10032        long nativePss=0, dalvikPss=0, otherPss=0;
10033        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10034
10035        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10036        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10037                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10038
10039        long totalPss = 0;
10040
10041        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10042            ProcessRecord r = procs.get(i);
10043            if (r.thread != null) {
10044                if (!isCheckinRequest && dumpAll) {
10045                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10046                    pw.flush();
10047                }
10048                Debug.MemoryInfo mi = null;
10049                if (dumpAll) {
10050                    try {
10051                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10052                    } catch (RemoteException e) {
10053                        if (!isCheckinRequest) {
10054                            pw.println("Got RemoteException!");
10055                            pw.flush();
10056                        }
10057                    }
10058                } else {
10059                    mi = new Debug.MemoryInfo();
10060                    Debug.getMemoryInfo(r.pid, mi);
10061                }
10062
10063                if (!isCheckinRequest && mi != null) {
10064                    long myTotalPss = mi.getTotalPss();
10065                    totalPss += myTotalPss;
10066                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10067                            r.processName, myTotalPss, 0);
10068                    procMems.add(pssItem);
10069
10070                    nativePss += mi.nativePss;
10071                    dalvikPss += mi.dalvikPss;
10072                    otherPss += mi.otherPss;
10073                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10074                        long mem = mi.getOtherPss(j);
10075                        miscPss[j] += mem;
10076                        otherPss -= mem;
10077                    }
10078
10079                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10080                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10081                                || oomIndex == (oomPss.length-1)) {
10082                            oomPss[oomIndex] += myTotalPss;
10083                            if (oomProcs[oomIndex] == null) {
10084                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10085                            }
10086                            oomProcs[oomIndex].add(pssItem);
10087                            break;
10088                        }
10089                    }
10090                }
10091            }
10092        }
10093
10094        if (!isCheckinRequest && procs.size() > 1) {
10095            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10096
10097            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10098            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10099            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10100            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10101                String label = Debug.MemoryInfo.getOtherLabel(j);
10102                catMems.add(new MemItem(label, label, miscPss[j], j));
10103            }
10104
10105            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10106            for (int j=0; j<oomPss.length; j++) {
10107                if (oomPss[j] != 0) {
10108                    String label = DUMP_MEM_OOM_LABEL[j];
10109                    MemItem item = new MemItem(label, label, oomPss[j],
10110                            DUMP_MEM_OOM_ADJ[j]);
10111                    item.subitems = oomProcs[j];
10112                    oomMems.add(item);
10113                }
10114            }
10115
10116            if (outTag != null || outStack != null) {
10117                if (outTag != null) {
10118                    appendMemBucket(outTag, totalPss, "total", false);
10119                }
10120                if (outStack != null) {
10121                    appendMemBucket(outStack, totalPss, "total", true);
10122                }
10123                boolean firstLine = true;
10124                for (int i=0; i<oomMems.size(); i++) {
10125                    MemItem miCat = oomMems.get(i);
10126                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10127                        continue;
10128                    }
10129                    if (miCat.id < ProcessList.SERVICE_ADJ
10130                            || miCat.id == ProcessList.HOME_APP_ADJ
10131                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10132                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10133                            outTag.append(" / ");
10134                        }
10135                        if (outStack != null) {
10136                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10137                                if (firstLine) {
10138                                    outStack.append(":");
10139                                    firstLine = false;
10140                                }
10141                                outStack.append("\n\t at ");
10142                            } else {
10143                                outStack.append("$");
10144                            }
10145                        }
10146                        for (int j=0; j<miCat.subitems.size(); j++) {
10147                            MemItem mi = miCat.subitems.get(j);
10148                            if (j > 0) {
10149                                if (outTag != null) {
10150                                    outTag.append(" ");
10151                                }
10152                                if (outStack != null) {
10153                                    outStack.append("$");
10154                                }
10155                            }
10156                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10157                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10158                            }
10159                            if (outStack != null) {
10160                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10161                            }
10162                        }
10163                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10164                            outStack.append("(");
10165                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10166                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10167                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10168                                    outStack.append(":");
10169                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10170                                }
10171                            }
10172                            outStack.append(")");
10173                        }
10174                    }
10175                }
10176            }
10177
10178            if (!brief && !oomOnly) {
10179                pw.println();
10180                pw.println("Total PSS by process:");
10181                dumpMemItems(pw, "  ", procMems, true);
10182                pw.println();
10183            }
10184            pw.println("Total PSS by OOM adjustment:");
10185            dumpMemItems(pw, "  ", oomMems, false);
10186            if (!oomOnly) {
10187                PrintWriter out = categoryPw != null ? categoryPw : pw;
10188                out.println();
10189                out.println("Total PSS by category:");
10190                dumpMemItems(out, "  ", catMems, true);
10191            }
10192            pw.println();
10193            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10194            final int[] SINGLE_LONG_FORMAT = new int[] {
10195                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10196            };
10197            long[] longOut = new long[1];
10198            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10199                    SINGLE_LONG_FORMAT, null, longOut, null);
10200            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10201            longOut[0] = 0;
10202            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10203                    SINGLE_LONG_FORMAT, null, longOut, null);
10204            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10205            longOut[0] = 0;
10206            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10207                    SINGLE_LONG_FORMAT, null, longOut, null);
10208            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10209            longOut[0] = 0;
10210            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10211                    SINGLE_LONG_FORMAT, null, longOut, null);
10212            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10213            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10214                    pw.print(shared); pw.println(" kB");
10215            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10216                    pw.print(voltile); pw.println(" kB volatile");
10217        }
10218    }
10219
10220    /**
10221     * Searches array of arguments for the specified string
10222     * @param args array of argument strings
10223     * @param value value to search for
10224     * @return true if the value is contained in the array
10225     */
10226    private static boolean scanArgs(String[] args, String value) {
10227        if (args != null) {
10228            for (String arg : args) {
10229                if (value.equals(arg)) {
10230                    return true;
10231                }
10232            }
10233        }
10234        return false;
10235    }
10236
10237    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10238            ContentProviderRecord cpr, boolean always) {
10239        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10240
10241        if (!inLaunching || always) {
10242            synchronized (cpr) {
10243                cpr.launchingApp = null;
10244                cpr.notifyAll();
10245            }
10246            mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10247            String names[] = cpr.info.authority.split(";");
10248            for (int j = 0; j < names.length; j++) {
10249                mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10250            }
10251        }
10252
10253        for (int i=0; i<cpr.connections.size(); i++) {
10254            ContentProviderConnection conn = cpr.connections.get(i);
10255            if (conn.waiting) {
10256                // If this connection is waiting for the provider, then we don't
10257                // need to mess with its process unless we are always removing
10258                // or for some reason the provider is not currently launching.
10259                if (inLaunching && !always) {
10260                    continue;
10261                }
10262            }
10263            ProcessRecord capp = conn.client;
10264            conn.dead = true;
10265            if (conn.stableCount > 0) {
10266                if (!capp.persistent && capp.thread != null
10267                        && capp.pid != 0
10268                        && capp.pid != MY_PID) {
10269                    Slog.i(TAG, "Kill " + capp.processName
10270                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10271                            + " in dying process " + (proc != null ? proc.processName : "??"));
10272                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10273                            capp.processName, capp.setAdj, "dying provider "
10274                                    + cpr.name.toShortString());
10275                    Process.killProcessQuiet(capp.pid);
10276                }
10277            } else if (capp.thread != null && conn.provider.provider != null) {
10278                try {
10279                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10280                } catch (RemoteException e) {
10281                }
10282                // In the protocol here, we don't expect the client to correctly
10283                // clean up this connection, we'll just remove it.
10284                cpr.connections.remove(i);
10285                conn.client.conProviders.remove(conn);
10286            }
10287        }
10288
10289        if (inLaunching && always) {
10290            mLaunchingProviders.remove(cpr);
10291        }
10292        return inLaunching;
10293    }
10294
10295    /**
10296     * Main code for cleaning up a process when it has gone away.  This is
10297     * called both as a result of the process dying, or directly when stopping
10298     * a process when running in single process mode.
10299     */
10300    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10301            boolean restarting, boolean allowRestart, int index) {
10302        if (index >= 0) {
10303            mLruProcesses.remove(index);
10304        }
10305
10306        mProcessesToGc.remove(app);
10307
10308        // Dismiss any open dialogs.
10309        if (app.crashDialog != null) {
10310            app.crashDialog.dismiss();
10311            app.crashDialog = null;
10312        }
10313        if (app.anrDialog != null) {
10314            app.anrDialog.dismiss();
10315            app.anrDialog = null;
10316        }
10317        if (app.waitDialog != null) {
10318            app.waitDialog.dismiss();
10319            app.waitDialog = null;
10320        }
10321
10322        app.crashing = false;
10323        app.notResponding = false;
10324
10325        app.resetPackageList();
10326        app.unlinkDeathRecipient();
10327        app.thread = null;
10328        app.forcingToForeground = null;
10329        app.foregroundServices = false;
10330        app.foregroundActivities = false;
10331        app.hasShownUi = false;
10332        app.hasAboveClient = false;
10333
10334        mServices.killServicesLocked(app, allowRestart);
10335
10336        boolean restart = false;
10337
10338        // Remove published content providers.
10339        if (!app.pubProviders.isEmpty()) {
10340            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10341            while (it.hasNext()) {
10342                ContentProviderRecord cpr = it.next();
10343
10344                final boolean always = app.bad || !allowRestart;
10345                if (removeDyingProviderLocked(app, cpr, always) || always) {
10346                    // We left the provider in the launching list, need to
10347                    // restart it.
10348                    restart = true;
10349                }
10350
10351                cpr.provider = null;
10352                cpr.proc = null;
10353            }
10354            app.pubProviders.clear();
10355        }
10356
10357        // Take care of any launching providers waiting for this process.
10358        if (checkAppInLaunchingProvidersLocked(app, false)) {
10359            restart = true;
10360        }
10361
10362        // Unregister from connected content providers.
10363        if (!app.conProviders.isEmpty()) {
10364            for (int i=0; i<app.conProviders.size(); i++) {
10365                ContentProviderConnection conn = app.conProviders.get(i);
10366                conn.provider.connections.remove(conn);
10367            }
10368            app.conProviders.clear();
10369        }
10370
10371        // At this point there may be remaining entries in mLaunchingProviders
10372        // where we were the only one waiting, so they are no longer of use.
10373        // Look for these and clean up if found.
10374        // XXX Commented out for now.  Trying to figure out a way to reproduce
10375        // the actual situation to identify what is actually going on.
10376        if (false) {
10377            for (int i=0; i<mLaunchingProviders.size(); i++) {
10378                ContentProviderRecord cpr = (ContentProviderRecord)
10379                        mLaunchingProviders.get(i);
10380                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10381                    synchronized (cpr) {
10382                        cpr.launchingApp = null;
10383                        cpr.notifyAll();
10384                    }
10385                }
10386            }
10387        }
10388
10389        skipCurrentReceiverLocked(app);
10390
10391        // Unregister any receivers.
10392        if (app.receivers.size() > 0) {
10393            Iterator<ReceiverList> it = app.receivers.iterator();
10394            while (it.hasNext()) {
10395                removeReceiverLocked(it.next());
10396            }
10397            app.receivers.clear();
10398        }
10399
10400        // If the app is undergoing backup, tell the backup manager about it
10401        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10402            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10403            try {
10404                IBackupManager bm = IBackupManager.Stub.asInterface(
10405                        ServiceManager.getService(Context.BACKUP_SERVICE));
10406                bm.agentDisconnected(app.info.packageName);
10407            } catch (RemoteException e) {
10408                // can't happen; backup manager is local
10409            }
10410        }
10411
10412        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10413            ProcessChangeItem item = mPendingProcessChanges.get(i);
10414            if (item.pid == app.pid) {
10415                mPendingProcessChanges.remove(i);
10416                mAvailProcessChanges.add(item);
10417            }
10418        }
10419        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10420
10421        // If the caller is restarting this app, then leave it in its
10422        // current lists and let the caller take care of it.
10423        if (restarting) {
10424            return;
10425        }
10426
10427        if (!app.persistent || app.isolated) {
10428            if (DEBUG_PROCESSES) Slog.v(TAG,
10429                    "Removing non-persistent process during cleanup: " + app);
10430            mProcessNames.remove(app.processName, app.uid);
10431            mIsolatedProcesses.remove(app.uid);
10432            if (mHeavyWeightProcess == app) {
10433                mHeavyWeightProcess = null;
10434                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10435            }
10436        } else if (!app.removed) {
10437            // This app is persistent, so we need to keep its record around.
10438            // If it is not already on the pending app list, add it there
10439            // and start a new process for it.
10440            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10441                mPersistentStartingProcesses.add(app);
10442                restart = true;
10443            }
10444        }
10445        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10446                "Clean-up removing on hold: " + app);
10447        mProcessesOnHold.remove(app);
10448
10449        if (app == mHomeProcess) {
10450            mHomeProcess = null;
10451        }
10452        if (app == mPreviousProcess) {
10453            mPreviousProcess = null;
10454        }
10455
10456        if (restart && !app.isolated) {
10457            // We have components that still need to be running in the
10458            // process, so re-launch it.
10459            mProcessNames.put(app.processName, app.uid, app);
10460            startProcessLocked(app, "restart", app.processName);
10461        } else if (app.pid > 0 && app.pid != MY_PID) {
10462            // Goodbye!
10463            synchronized (mPidsSelfLocked) {
10464                mPidsSelfLocked.remove(app.pid);
10465                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10466            }
10467            app.setPid(0);
10468        }
10469    }
10470
10471    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10472        // Look through the content providers we are waiting to have launched,
10473        // and if any run in this process then either schedule a restart of
10474        // the process or kill the client waiting for it if this process has
10475        // gone bad.
10476        int NL = mLaunchingProviders.size();
10477        boolean restart = false;
10478        for (int i=0; i<NL; i++) {
10479            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10480            if (cpr.launchingApp == app) {
10481                if (!alwaysBad && !app.bad) {
10482                    restart = true;
10483                } else {
10484                    removeDyingProviderLocked(app, cpr, true);
10485                    NL = mLaunchingProviders.size();
10486                }
10487            }
10488        }
10489        return restart;
10490    }
10491
10492    // =========================================================
10493    // SERVICES
10494    // =========================================================
10495
10496    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10497            int flags) {
10498        enforceNotIsolatedCaller("getServices");
10499        synchronized (this) {
10500            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10501        }
10502    }
10503
10504    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10505        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10506        synchronized (this) {
10507            return mServices.getRunningServiceControlPanelLocked(name);
10508        }
10509    }
10510
10511    public ComponentName startService(IApplicationThread caller, Intent service,
10512            String resolvedType) {
10513        enforceNotIsolatedCaller("startService");
10514        // Refuse possible leaked file descriptors
10515        if (service != null && service.hasFileDescriptors() == true) {
10516            throw new IllegalArgumentException("File descriptors passed in Intent");
10517        }
10518
10519        if (DEBUG_SERVICE)
10520            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10521        synchronized(this) {
10522            final int callingPid = Binder.getCallingPid();
10523            final int callingUid = Binder.getCallingUid();
10524            final long origId = Binder.clearCallingIdentity();
10525            ComponentName res = mServices.startServiceLocked(caller, service,
10526                    resolvedType, callingPid, callingUid);
10527            Binder.restoreCallingIdentity(origId);
10528            return res;
10529        }
10530    }
10531
10532    ComponentName startServiceInPackage(int uid,
10533            Intent service, String resolvedType) {
10534        synchronized(this) {
10535            if (DEBUG_SERVICE)
10536                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10537            final long origId = Binder.clearCallingIdentity();
10538            ComponentName res = mServices.startServiceLocked(null, service,
10539                    resolvedType, -1, uid);
10540            Binder.restoreCallingIdentity(origId);
10541            return res;
10542        }
10543    }
10544
10545    public int stopService(IApplicationThread caller, Intent service,
10546            String resolvedType) {
10547        enforceNotIsolatedCaller("stopService");
10548        // Refuse possible leaked file descriptors
10549        if (service != null && service.hasFileDescriptors() == true) {
10550            throw new IllegalArgumentException("File descriptors passed in Intent");
10551        }
10552
10553        synchronized(this) {
10554            return mServices.stopServiceLocked(caller, service, resolvedType);
10555        }
10556    }
10557
10558    public IBinder peekService(Intent service, String resolvedType) {
10559        enforceNotIsolatedCaller("peekService");
10560        // Refuse possible leaked file descriptors
10561        if (service != null && service.hasFileDescriptors() == true) {
10562            throw new IllegalArgumentException("File descriptors passed in Intent");
10563        }
10564        synchronized(this) {
10565            return mServices.peekServiceLocked(service, resolvedType);
10566        }
10567    }
10568
10569    public boolean stopServiceToken(ComponentName className, IBinder token,
10570            int startId) {
10571        synchronized(this) {
10572            return mServices.stopServiceTokenLocked(className, token, startId);
10573        }
10574    }
10575
10576    public void setServiceForeground(ComponentName className, IBinder token,
10577            int id, Notification notification, boolean removeNotification) {
10578        synchronized(this) {
10579            mServices.setServiceForegroundLocked(className, token, id, notification,
10580                    removeNotification);
10581        }
10582    }
10583
10584    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10585            String className, int flags) {
10586        boolean result = false;
10587        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10588            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10589                if (ActivityManager.checkUidPermission(
10590                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10591                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10592                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10593                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10594                            + " requests FLAG_SINGLE_USER, but app does not hold "
10595                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10596                    Slog.w(TAG, msg);
10597                    throw new SecurityException(msg);
10598                }
10599                result = true;
10600            }
10601        } else if (componentProcessName == aInfo.packageName) {
10602            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10603        } else if ("system".equals(componentProcessName)) {
10604            result = true;
10605        }
10606        if (DEBUG_MU) {
10607            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10608                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10609        }
10610        return result;
10611    }
10612
10613    public int bindService(IApplicationThread caller, IBinder token,
10614            Intent service, String resolvedType,
10615            IServiceConnection connection, int flags, int userId) {
10616        enforceNotIsolatedCaller("bindService");
10617        // Refuse possible leaked file descriptors
10618        if (service != null && service.hasFileDescriptors() == true) {
10619            throw new IllegalArgumentException("File descriptors passed in Intent");
10620        }
10621
10622        checkValidCaller(Binder.getCallingUid(), userId);
10623
10624        synchronized(this) {
10625            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10626                    connection, flags, userId);
10627        }
10628    }
10629
10630    public boolean unbindService(IServiceConnection connection) {
10631        synchronized (this) {
10632            return mServices.unbindServiceLocked(connection);
10633        }
10634    }
10635
10636    public void publishService(IBinder token, Intent intent, IBinder service) {
10637        // Refuse possible leaked file descriptors
10638        if (intent != null && intent.hasFileDescriptors() == true) {
10639            throw new IllegalArgumentException("File descriptors passed in Intent");
10640        }
10641
10642        synchronized(this) {
10643            if (!(token instanceof ServiceRecord)) {
10644                throw new IllegalArgumentException("Invalid service token");
10645            }
10646            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10647        }
10648    }
10649
10650    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10651        // Refuse possible leaked file descriptors
10652        if (intent != null && intent.hasFileDescriptors() == true) {
10653            throw new IllegalArgumentException("File descriptors passed in Intent");
10654        }
10655
10656        synchronized(this) {
10657            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10658        }
10659    }
10660
10661    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10662        synchronized(this) {
10663            if (!(token instanceof ServiceRecord)) {
10664                throw new IllegalArgumentException("Invalid service token");
10665            }
10666            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10667        }
10668    }
10669
10670    // =========================================================
10671    // BACKUP AND RESTORE
10672    // =========================================================
10673
10674    // Cause the target app to be launched if necessary and its backup agent
10675    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10676    // activity manager to announce its creation.
10677    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10678        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10679        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10680
10681        synchronized(this) {
10682            // !!! TODO: currently no check here that we're already bound
10683            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10684            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10685            synchronized (stats) {
10686                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10687            }
10688
10689            // Backup agent is now in use, its package can't be stopped.
10690            try {
10691                AppGlobals.getPackageManager().setPackageStoppedState(
10692                        app.packageName, false, UserId.getUserId(app.uid));
10693            } catch (RemoteException e) {
10694            } catch (IllegalArgumentException e) {
10695                Slog.w(TAG, "Failed trying to unstop package "
10696                        + app.packageName + ": " + e);
10697            }
10698
10699            BackupRecord r = new BackupRecord(ss, app, backupMode);
10700            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10701                    ? new ComponentName(app.packageName, app.backupAgentName)
10702                    : new ComponentName("android", "FullBackupAgent");
10703            // startProcessLocked() returns existing proc's record if it's already running
10704            ProcessRecord proc = startProcessLocked(app.processName, app,
10705                    false, 0, "backup", hostingName, false, false);
10706            if (proc == null) {
10707                Slog.e(TAG, "Unable to start backup agent process " + r);
10708                return false;
10709            }
10710
10711            r.app = proc;
10712            mBackupTarget = r;
10713            mBackupAppName = app.packageName;
10714
10715            // Try not to kill the process during backup
10716            updateOomAdjLocked(proc);
10717
10718            // If the process is already attached, schedule the creation of the backup agent now.
10719            // If it is not yet live, this will be done when it attaches to the framework.
10720            if (proc.thread != null) {
10721                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10722                try {
10723                    proc.thread.scheduleCreateBackupAgent(app,
10724                            compatibilityInfoForPackageLocked(app), backupMode);
10725                } catch (RemoteException e) {
10726                    // Will time out on the backup manager side
10727                }
10728            } else {
10729                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10730            }
10731            // Invariants: at this point, the target app process exists and the application
10732            // is either already running or in the process of coming up.  mBackupTarget and
10733            // mBackupAppName describe the app, so that when it binds back to the AM we
10734            // know that it's scheduled for a backup-agent operation.
10735        }
10736
10737        return true;
10738    }
10739
10740    // A backup agent has just come up
10741    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10742        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10743                + " = " + agent);
10744
10745        synchronized(this) {
10746            if (!agentPackageName.equals(mBackupAppName)) {
10747                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10748                return;
10749            }
10750        }
10751
10752        long oldIdent = Binder.clearCallingIdentity();
10753        try {
10754            IBackupManager bm = IBackupManager.Stub.asInterface(
10755                    ServiceManager.getService(Context.BACKUP_SERVICE));
10756            bm.agentConnected(agentPackageName, agent);
10757        } catch (RemoteException e) {
10758            // can't happen; the backup manager service is local
10759        } catch (Exception e) {
10760            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10761            e.printStackTrace();
10762        } finally {
10763            Binder.restoreCallingIdentity(oldIdent);
10764        }
10765    }
10766
10767    // done with this agent
10768    public void unbindBackupAgent(ApplicationInfo appInfo) {
10769        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10770        if (appInfo == null) {
10771            Slog.w(TAG, "unbind backup agent for null app");
10772            return;
10773        }
10774
10775        synchronized(this) {
10776            if (mBackupAppName == null) {
10777                Slog.w(TAG, "Unbinding backup agent with no active backup");
10778                return;
10779            }
10780
10781            if (!mBackupAppName.equals(appInfo.packageName)) {
10782                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10783                return;
10784            }
10785
10786            ProcessRecord proc = mBackupTarget.app;
10787            mBackupTarget = null;
10788            mBackupAppName = null;
10789
10790            // Not backing this app up any more; reset its OOM adjustment
10791            updateOomAdjLocked(proc);
10792
10793            // If the app crashed during backup, 'thread' will be null here
10794            if (proc.thread != null) {
10795                try {
10796                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10797                            compatibilityInfoForPackageLocked(appInfo));
10798                } catch (Exception e) {
10799                    Slog.e(TAG, "Exception when unbinding backup agent:");
10800                    e.printStackTrace();
10801                }
10802            }
10803        }
10804    }
10805    // =========================================================
10806    // BROADCASTS
10807    // =========================================================
10808
10809    private final List getStickiesLocked(String action, IntentFilter filter,
10810            List cur) {
10811        final ContentResolver resolver = mContext.getContentResolver();
10812        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10813        if (list == null) {
10814            return cur;
10815        }
10816        int N = list.size();
10817        for (int i=0; i<N; i++) {
10818            Intent intent = list.get(i);
10819            if (filter.match(resolver, intent, true, TAG) >= 0) {
10820                if (cur == null) {
10821                    cur = new ArrayList<Intent>();
10822                }
10823                cur.add(intent);
10824            }
10825        }
10826        return cur;
10827    }
10828
10829    boolean isPendingBroadcastProcessLocked(int pid) {
10830        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10831                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10832    }
10833
10834    void skipPendingBroadcastLocked(int pid) {
10835            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10836            for (BroadcastQueue queue : mBroadcastQueues) {
10837                queue.skipPendingBroadcastLocked(pid);
10838            }
10839    }
10840
10841    // The app just attached; send any pending broadcasts that it should receive
10842    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10843        boolean didSomething = false;
10844        for (BroadcastQueue queue : mBroadcastQueues) {
10845            didSomething |= queue.sendPendingBroadcastsLocked(app);
10846        }
10847        return didSomething;
10848    }
10849
10850    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10851            IIntentReceiver receiver, IntentFilter filter, String permission) {
10852        enforceNotIsolatedCaller("registerReceiver");
10853        int callingUid;
10854        synchronized(this) {
10855            ProcessRecord callerApp = null;
10856            if (caller != null) {
10857                callerApp = getRecordForAppLocked(caller);
10858                if (callerApp == null) {
10859                    throw new SecurityException(
10860                            "Unable to find app for caller " + caller
10861                            + " (pid=" + Binder.getCallingPid()
10862                            + ") when registering receiver " + receiver);
10863                }
10864                if (callerApp.info.uid != Process.SYSTEM_UID &&
10865                        !callerApp.pkgList.contains(callerPackage)) {
10866                    throw new SecurityException("Given caller package " + callerPackage
10867                            + " is not running in process " + callerApp);
10868                }
10869                callingUid = callerApp.info.uid;
10870            } else {
10871                callerPackage = null;
10872                callingUid = Binder.getCallingUid();
10873            }
10874
10875            List allSticky = null;
10876
10877            // Look for any matching sticky broadcasts...
10878            Iterator actions = filter.actionsIterator();
10879            if (actions != null) {
10880                while (actions.hasNext()) {
10881                    String action = (String)actions.next();
10882                    allSticky = getStickiesLocked(action, filter, allSticky);
10883                }
10884            } else {
10885                allSticky = getStickiesLocked(null, filter, allSticky);
10886            }
10887
10888            // The first sticky in the list is returned directly back to
10889            // the client.
10890            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10891
10892            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10893                    + ": " + sticky);
10894
10895            if (receiver == null) {
10896                return sticky;
10897            }
10898
10899            ReceiverList rl
10900                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10901            if (rl == null) {
10902                rl = new ReceiverList(this, callerApp,
10903                        Binder.getCallingPid(),
10904                        Binder.getCallingUid(), receiver);
10905                if (rl.app != null) {
10906                    rl.app.receivers.add(rl);
10907                } else {
10908                    try {
10909                        receiver.asBinder().linkToDeath(rl, 0);
10910                    } catch (RemoteException e) {
10911                        return sticky;
10912                    }
10913                    rl.linkedToDeath = true;
10914                }
10915                mRegisteredReceivers.put(receiver.asBinder(), rl);
10916            }
10917            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10918                    permission, callingUid);
10919            rl.add(bf);
10920            if (!bf.debugCheck()) {
10921                Slog.w(TAG, "==> For Dynamic broadast");
10922            }
10923            mReceiverResolver.addFilter(bf);
10924
10925            // Enqueue broadcasts for all existing stickies that match
10926            // this filter.
10927            if (allSticky != null) {
10928                ArrayList receivers = new ArrayList();
10929                receivers.add(bf);
10930
10931                int N = allSticky.size();
10932                for (int i=0; i<N; i++) {
10933                    Intent intent = (Intent)allSticky.get(i);
10934                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10935                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10936                            null, -1, -1, null, receivers, null, 0, null, null,
10937                            false, true, true, false);
10938                    queue.enqueueParallelBroadcastLocked(r);
10939                    queue.scheduleBroadcastsLocked();
10940                }
10941            }
10942
10943            return sticky;
10944        }
10945    }
10946
10947    public void unregisterReceiver(IIntentReceiver receiver) {
10948        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10949
10950        final long origId = Binder.clearCallingIdentity();
10951        try {
10952            boolean doTrim = false;
10953
10954            synchronized(this) {
10955                ReceiverList rl
10956                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10957                if (rl != null) {
10958                    if (rl.curBroadcast != null) {
10959                        BroadcastRecord r = rl.curBroadcast;
10960                        final boolean doNext = finishReceiverLocked(
10961                                receiver.asBinder(), r.resultCode, r.resultData,
10962                                r.resultExtras, r.resultAbort, true);
10963                        if (doNext) {
10964                            doTrim = true;
10965                            r.queue.processNextBroadcast(false);
10966                        }
10967                    }
10968
10969                    if (rl.app != null) {
10970                        rl.app.receivers.remove(rl);
10971                    }
10972                    removeReceiverLocked(rl);
10973                    if (rl.linkedToDeath) {
10974                        rl.linkedToDeath = false;
10975                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
10976                    }
10977                }
10978            }
10979
10980            // If we actually concluded any broadcasts, we might now be able
10981            // to trim the recipients' apps from our working set
10982            if (doTrim) {
10983                trimApplications();
10984                return;
10985            }
10986
10987        } finally {
10988            Binder.restoreCallingIdentity(origId);
10989        }
10990    }
10991
10992    void removeReceiverLocked(ReceiverList rl) {
10993        mRegisteredReceivers.remove(rl.receiver.asBinder());
10994        int N = rl.size();
10995        for (int i=0; i<N; i++) {
10996            mReceiverResolver.removeFilter(rl.get(i));
10997        }
10998    }
10999
11000    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11001        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11002            ProcessRecord r = mLruProcesses.get(i);
11003            if (r.thread != null) {
11004                try {
11005                    r.thread.dispatchPackageBroadcast(cmd, packages);
11006                } catch (RemoteException ex) {
11007                }
11008            }
11009        }
11010    }
11011
11012    private final int broadcastIntentLocked(ProcessRecord callerApp,
11013            String callerPackage, Intent intent, String resolvedType,
11014            IIntentReceiver resultTo, int resultCode, String resultData,
11015            Bundle map, String requiredPermission,
11016            boolean ordered, boolean sticky, int callingPid, int callingUid,
11017            int userId) {
11018        intent = new Intent(intent);
11019
11020        // By default broadcasts do not go to stopped apps.
11021        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11022
11023        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11024            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11025            + " ordered=" + ordered + " userid=" + userId);
11026        if ((resultTo != null) && !ordered) {
11027            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11028        }
11029
11030        boolean onlySendToCaller = false;
11031
11032        // If the caller is trying to send this broadcast to a different
11033        // user, verify that is allowed.
11034        if (UserId.getUserId(callingUid) != userId) {
11035            if (checkComponentPermission(
11036                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11037                    callingPid, callingUid, -1, true)
11038                    != PackageManager.PERMISSION_GRANTED) {
11039                if (checkComponentPermission(
11040                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11041                        callingPid, callingUid, -1, true)
11042                        == PackageManager.PERMISSION_GRANTED) {
11043                    onlySendToCaller = true;
11044                } else {
11045                    String msg = "Permission Denial: " + intent.getAction()
11046                            + " broadcast from " + callerPackage
11047                            + " asks to send as user " + userId
11048                            + " but is calling from user " + UserId.getUserId(callingUid)
11049                            + "; this requires "
11050                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11051                    Slog.w(TAG, msg);
11052                    throw new SecurityException(msg);
11053                }
11054            }
11055        }
11056
11057        // Handle special intents: if this broadcast is from the package
11058        // manager about a package being removed, we need to remove all of
11059        // its activities from the history stack.
11060        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11061                intent.getAction());
11062        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11063                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11064                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11065                || uidRemoved) {
11066            if (checkComponentPermission(
11067                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11068                    callingPid, callingUid, -1, true)
11069                    == PackageManager.PERMISSION_GRANTED) {
11070                if (uidRemoved) {
11071                    final Bundle intentExtras = intent.getExtras();
11072                    final int uid = intentExtras != null
11073                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11074                    if (uid >= 0) {
11075                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11076                        synchronized (bs) {
11077                            bs.removeUidStatsLocked(uid);
11078                        }
11079                    }
11080                } else {
11081                    // If resources are unvailble just force stop all
11082                    // those packages and flush the attribute cache as well.
11083                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11084                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11085                        if (list != null && (list.length > 0)) {
11086                            for (String pkg : list) {
11087                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11088                            }
11089                            sendPackageBroadcastLocked(
11090                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11091                        }
11092                    } else {
11093                        Uri data = intent.getData();
11094                        String ssp;
11095                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11096                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11097                                forceStopPackageLocked(ssp,
11098                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11099                                        false, userId);
11100                            }
11101                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11102                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11103                                        new String[] {ssp});
11104                            }
11105                        }
11106                    }
11107                }
11108            } else {
11109                String msg = "Permission Denial: " + intent.getAction()
11110                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11111                        + ", uid=" + callingUid + ")"
11112                        + " requires "
11113                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11114                Slog.w(TAG, msg);
11115                throw new SecurityException(msg);
11116            }
11117
11118        // Special case for adding a package: by default turn on compatibility
11119        // mode.
11120        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11121            Uri data = intent.getData();
11122            String ssp;
11123            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11124                mCompatModePackages.handlePackageAddedLocked(ssp,
11125                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11126            }
11127        }
11128
11129        /*
11130         * If this is the time zone changed action, queue up a message that will reset the timezone
11131         * of all currently running processes. This message will get queued up before the broadcast
11132         * happens.
11133         */
11134        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11135            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11136        }
11137
11138        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11139            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11140        }
11141
11142        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11143            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11144            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11145        }
11146
11147        /*
11148         * Prevent non-system code (defined here to be non-persistent
11149         * processes) from sending protected broadcasts.
11150         */
11151        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11152            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11153            callingUid == 0) {
11154            // Always okay.
11155        } else if (callerApp == null || !callerApp.persistent) {
11156            try {
11157                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11158                        intent.getAction())) {
11159                    String msg = "Permission Denial: not allowed to send broadcast "
11160                            + intent.getAction() + " from pid="
11161                            + callingPid + ", uid=" + callingUid;
11162                    Slog.w(TAG, msg);
11163                    throw new SecurityException(msg);
11164                }
11165            } catch (RemoteException e) {
11166                Slog.w(TAG, "Remote exception", e);
11167                return ActivityManager.BROADCAST_SUCCESS;
11168            }
11169        }
11170
11171        // Add to the sticky list if requested.
11172        if (sticky) {
11173            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11174                    callingPid, callingUid)
11175                    != PackageManager.PERMISSION_GRANTED) {
11176                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11177                        + callingPid + ", uid=" + callingUid
11178                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11179                Slog.w(TAG, msg);
11180                throw new SecurityException(msg);
11181            }
11182            if (requiredPermission != null) {
11183                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11184                        + " and enforce permission " + requiredPermission);
11185                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11186            }
11187            if (intent.getComponent() != null) {
11188                throw new SecurityException(
11189                        "Sticky broadcasts can't target a specific component");
11190            }
11191            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11192            if (list == null) {
11193                list = new ArrayList<Intent>();
11194                mStickyBroadcasts.put(intent.getAction(), list);
11195            }
11196            int N = list.size();
11197            int i;
11198            for (i=0; i<N; i++) {
11199                if (intent.filterEquals(list.get(i))) {
11200                    // This sticky already exists, replace it.
11201                    list.set(i, new Intent(intent));
11202                    break;
11203                }
11204            }
11205            if (i >= N) {
11206                list.add(new Intent(intent));
11207            }
11208        }
11209
11210        // Figure out who all will receive this broadcast.
11211        List receivers = null;
11212        List<BroadcastFilter> registeredReceivers = null;
11213        try {
11214            // Need to resolve the intent to interested receivers...
11215            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11216                     == 0) {
11217                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11218                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11219            }
11220            if (intent.getComponent() == null) {
11221                registeredReceivers = mReceiverResolver.queryIntent(intent,
11222                        resolvedType, false, userId);
11223            }
11224        } catch (RemoteException ex) {
11225            // pm is in same process, this will never happen.
11226        }
11227
11228        final boolean replacePending =
11229                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11230
11231        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11232                + " replacePending=" + replacePending);
11233
11234        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11235        if (!ordered && NR > 0) {
11236            // If we are not serializing this broadcast, then send the
11237            // registered receivers separately so they don't wait for the
11238            // components to be launched.
11239            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11240            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11241                    callerPackage, callingPid, callingUid, requiredPermission,
11242                    registeredReceivers, resultTo, resultCode, resultData, map,
11243                    ordered, sticky, false, onlySendToCaller);
11244            if (DEBUG_BROADCAST) Slog.v(
11245                    TAG, "Enqueueing parallel broadcast " + r);
11246            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11247            if (!replaced) {
11248                queue.enqueueParallelBroadcastLocked(r);
11249                queue.scheduleBroadcastsLocked();
11250            }
11251            registeredReceivers = null;
11252            NR = 0;
11253        }
11254
11255        // Merge into one list.
11256        int ir = 0;
11257        if (receivers != null) {
11258            // A special case for PACKAGE_ADDED: do not allow the package
11259            // being added to see this broadcast.  This prevents them from
11260            // using this as a back door to get run as soon as they are
11261            // installed.  Maybe in the future we want to have a special install
11262            // broadcast or such for apps, but we'd like to deliberately make
11263            // this decision.
11264            String skipPackages[] = null;
11265            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11266                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11267                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11268                Uri data = intent.getData();
11269                if (data != null) {
11270                    String pkgName = data.getSchemeSpecificPart();
11271                    if (pkgName != null) {
11272                        skipPackages = new String[] { pkgName };
11273                    }
11274                }
11275            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11276                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11277            }
11278            if (skipPackages != null && (skipPackages.length > 0)) {
11279                for (String skipPackage : skipPackages) {
11280                    if (skipPackage != null) {
11281                        int NT = receivers.size();
11282                        for (int it=0; it<NT; it++) {
11283                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11284                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11285                                receivers.remove(it);
11286                                it--;
11287                                NT--;
11288                            }
11289                        }
11290                    }
11291                }
11292            }
11293
11294            int NT = receivers != null ? receivers.size() : 0;
11295            int it = 0;
11296            ResolveInfo curt = null;
11297            BroadcastFilter curr = null;
11298            while (it < NT && ir < NR) {
11299                if (curt == null) {
11300                    curt = (ResolveInfo)receivers.get(it);
11301                }
11302                if (curr == null) {
11303                    curr = registeredReceivers.get(ir);
11304                }
11305                if (curr.getPriority() >= curt.priority) {
11306                    // Insert this broadcast record into the final list.
11307                    receivers.add(it, curr);
11308                    ir++;
11309                    curr = null;
11310                    it++;
11311                    NT++;
11312                } else {
11313                    // Skip to the next ResolveInfo in the final list.
11314                    it++;
11315                    curt = null;
11316                }
11317            }
11318        }
11319        while (ir < NR) {
11320            if (receivers == null) {
11321                receivers = new ArrayList();
11322            }
11323            receivers.add(registeredReceivers.get(ir));
11324            ir++;
11325        }
11326
11327        if ((receivers != null && receivers.size() > 0)
11328                || resultTo != null) {
11329            BroadcastQueue queue = broadcastQueueForIntent(intent);
11330            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11331                    callerPackage, callingPid, callingUid, requiredPermission,
11332                    receivers, resultTo, resultCode, resultData, map, ordered,
11333                    sticky, false, onlySendToCaller);
11334            if (DEBUG_BROADCAST) Slog.v(
11335                    TAG, "Enqueueing ordered broadcast " + r
11336                    + ": prev had " + queue.mOrderedBroadcasts.size());
11337            if (DEBUG_BROADCAST) {
11338                int seq = r.intent.getIntExtra("seq", -1);
11339                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11340            }
11341            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11342            if (!replaced) {
11343                queue.enqueueOrderedBroadcastLocked(r);
11344                queue.scheduleBroadcastsLocked();
11345            }
11346        }
11347
11348        return ActivityManager.BROADCAST_SUCCESS;
11349    }
11350
11351    final Intent verifyBroadcastLocked(Intent intent) {
11352        // Refuse possible leaked file descriptors
11353        if (intent != null && intent.hasFileDescriptors() == true) {
11354            throw new IllegalArgumentException("File descriptors passed in Intent");
11355        }
11356
11357        int flags = intent.getFlags();
11358
11359        if (!mProcessesReady) {
11360            // if the caller really truly claims to know what they're doing, go
11361            // ahead and allow the broadcast without launching any receivers
11362            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11363                intent = new Intent(intent);
11364                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11365            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11366                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11367                        + " before boot completion");
11368                throw new IllegalStateException("Cannot broadcast before boot completed");
11369            }
11370        }
11371
11372        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11373            throw new IllegalArgumentException(
11374                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11375        }
11376
11377        return intent;
11378    }
11379
11380    public final int broadcastIntent(IApplicationThread caller,
11381            Intent intent, String resolvedType, IIntentReceiver resultTo,
11382            int resultCode, String resultData, Bundle map,
11383            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11384        enforceNotIsolatedCaller("broadcastIntent");
11385        synchronized(this) {
11386            intent = verifyBroadcastLocked(intent);
11387
11388            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11389            final int callingPid = Binder.getCallingPid();
11390            final int callingUid = Binder.getCallingUid();
11391            final long origId = Binder.clearCallingIdentity();
11392            int res = broadcastIntentLocked(callerApp,
11393                    callerApp != null ? callerApp.info.packageName : null,
11394                    intent, resolvedType, resultTo,
11395                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11396                    callingPid, callingUid, userId);
11397            Binder.restoreCallingIdentity(origId);
11398            return res;
11399        }
11400    }
11401
11402    int broadcastIntentInPackage(String packageName, int uid,
11403            Intent intent, String resolvedType, IIntentReceiver resultTo,
11404            int resultCode, String resultData, Bundle map,
11405            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11406        synchronized(this) {
11407            intent = verifyBroadcastLocked(intent);
11408
11409            final long origId = Binder.clearCallingIdentity();
11410            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11411                    resultTo, resultCode, resultData, map, requiredPermission,
11412                    serialized, sticky, -1, uid, userId);
11413            Binder.restoreCallingIdentity(origId);
11414            return res;
11415        }
11416    }
11417
11418    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11419    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11420        // Refuse possible leaked file descriptors
11421        if (intent != null && intent.hasFileDescriptors() == true) {
11422            throw new IllegalArgumentException("File descriptors passed in Intent");
11423        }
11424
11425        synchronized(this) {
11426            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11427                    != PackageManager.PERMISSION_GRANTED) {
11428                String msg = "Permission Denial: unbroadcastIntent() from pid="
11429                        + Binder.getCallingPid()
11430                        + ", uid=" + Binder.getCallingUid()
11431                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11432                Slog.w(TAG, msg);
11433                throw new SecurityException(msg);
11434            }
11435            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11436            if (list != null) {
11437                int N = list.size();
11438                int i;
11439                for (i=0; i<N; i++) {
11440                    if (intent.filterEquals(list.get(i))) {
11441                        list.remove(i);
11442                        break;
11443                    }
11444                }
11445            }
11446        }
11447    }
11448
11449    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11450            String resultData, Bundle resultExtras, boolean resultAbort,
11451            boolean explicit) {
11452        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11453        if (r == null) {
11454            Slog.w(TAG, "finishReceiver called but not found on queue");
11455            return false;
11456        }
11457
11458        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11459                explicit);
11460    }
11461
11462    public void finishReceiver(IBinder who, int resultCode, String resultData,
11463            Bundle resultExtras, boolean resultAbort) {
11464        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11465
11466        // Refuse possible leaked file descriptors
11467        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11468            throw new IllegalArgumentException("File descriptors passed in Bundle");
11469        }
11470
11471        final long origId = Binder.clearCallingIdentity();
11472        try {
11473            boolean doNext = false;
11474            BroadcastRecord r = null;
11475
11476            synchronized(this) {
11477                r = broadcastRecordForReceiverLocked(who);
11478                if (r != null) {
11479                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11480                        resultData, resultExtras, resultAbort, true);
11481                }
11482            }
11483
11484            if (doNext) {
11485                r.queue.processNextBroadcast(false);
11486            }
11487            trimApplications();
11488        } finally {
11489            Binder.restoreCallingIdentity(origId);
11490        }
11491    }
11492
11493    // =========================================================
11494    // INSTRUMENTATION
11495    // =========================================================
11496
11497    public boolean startInstrumentation(ComponentName className,
11498            String profileFile, int flags, Bundle arguments,
11499            IInstrumentationWatcher watcher) {
11500        enforceNotIsolatedCaller("startInstrumentation");
11501        // Refuse possible leaked file descriptors
11502        if (arguments != null && arguments.hasFileDescriptors()) {
11503            throw new IllegalArgumentException("File descriptors passed in Bundle");
11504        }
11505
11506        synchronized(this) {
11507            InstrumentationInfo ii = null;
11508            ApplicationInfo ai = null;
11509            try {
11510                ii = mContext.getPackageManager().getInstrumentationInfo(
11511                    className, STOCK_PM_FLAGS);
11512                ai = mContext.getPackageManager().getApplicationInfo(
11513                        ii.targetPackage, STOCK_PM_FLAGS);
11514            } catch (PackageManager.NameNotFoundException e) {
11515            }
11516            if (ii == null) {
11517                reportStartInstrumentationFailure(watcher, className,
11518                        "Unable to find instrumentation info for: " + className);
11519                return false;
11520            }
11521            if (ai == null) {
11522                reportStartInstrumentationFailure(watcher, className,
11523                        "Unable to find instrumentation target package: " + ii.targetPackage);
11524                return false;
11525            }
11526
11527            int match = mContext.getPackageManager().checkSignatures(
11528                    ii.targetPackage, ii.packageName);
11529            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11530                String msg = "Permission Denial: starting instrumentation "
11531                        + className + " from pid="
11532                        + Binder.getCallingPid()
11533                        + ", uid=" + Binder.getCallingPid()
11534                        + " not allowed because package " + ii.packageName
11535                        + " does not have a signature matching the target "
11536                        + ii.targetPackage;
11537                reportStartInstrumentationFailure(watcher, className, msg);
11538                throw new SecurityException(msg);
11539            }
11540
11541            int userId = UserId.getCallingUserId();
11542            final long origId = Binder.clearCallingIdentity();
11543            // Instrumentation can kill and relaunch even persistent processes
11544            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11545            ProcessRecord app = addAppLocked(ai, false);
11546            app.instrumentationClass = className;
11547            app.instrumentationInfo = ai;
11548            app.instrumentationProfileFile = profileFile;
11549            app.instrumentationArguments = arguments;
11550            app.instrumentationWatcher = watcher;
11551            app.instrumentationResultClass = className;
11552            Binder.restoreCallingIdentity(origId);
11553        }
11554
11555        return true;
11556    }
11557
11558    /**
11559     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11560     * error to the logs, but if somebody is watching, send the report there too.  This enables
11561     * the "am" command to report errors with more information.
11562     *
11563     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11564     * @param cn The component name of the instrumentation.
11565     * @param report The error report.
11566     */
11567    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11568            ComponentName cn, String report) {
11569        Slog.w(TAG, report);
11570        try {
11571            if (watcher != null) {
11572                Bundle results = new Bundle();
11573                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11574                results.putString("Error", report);
11575                watcher.instrumentationStatus(cn, -1, results);
11576            }
11577        } catch (RemoteException e) {
11578            Slog.w(TAG, e);
11579        }
11580    }
11581
11582    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11583        if (app.instrumentationWatcher != null) {
11584            try {
11585                // NOTE:  IInstrumentationWatcher *must* be oneway here
11586                app.instrumentationWatcher.instrumentationFinished(
11587                    app.instrumentationClass,
11588                    resultCode,
11589                    results);
11590            } catch (RemoteException e) {
11591            }
11592        }
11593        app.instrumentationWatcher = null;
11594        app.instrumentationClass = null;
11595        app.instrumentationInfo = null;
11596        app.instrumentationProfileFile = null;
11597        app.instrumentationArguments = null;
11598
11599        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11600    }
11601
11602    public void finishInstrumentation(IApplicationThread target,
11603            int resultCode, Bundle results) {
11604        int userId = UserId.getCallingUserId();
11605        // Refuse possible leaked file descriptors
11606        if (results != null && results.hasFileDescriptors()) {
11607            throw new IllegalArgumentException("File descriptors passed in Intent");
11608        }
11609
11610        synchronized(this) {
11611            ProcessRecord app = getRecordForAppLocked(target);
11612            if (app == null) {
11613                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11614                return;
11615            }
11616            final long origId = Binder.clearCallingIdentity();
11617            finishInstrumentationLocked(app, resultCode, results);
11618            Binder.restoreCallingIdentity(origId);
11619        }
11620    }
11621
11622    // =========================================================
11623    // CONFIGURATION
11624    // =========================================================
11625
11626    public ConfigurationInfo getDeviceConfigurationInfo() {
11627        ConfigurationInfo config = new ConfigurationInfo();
11628        synchronized (this) {
11629            config.reqTouchScreen = mConfiguration.touchscreen;
11630            config.reqKeyboardType = mConfiguration.keyboard;
11631            config.reqNavigation = mConfiguration.navigation;
11632            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11633                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11634                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11635            }
11636            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11637                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11638                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11639            }
11640            config.reqGlEsVersion = GL_ES_VERSION;
11641        }
11642        return config;
11643    }
11644
11645    public Configuration getConfiguration() {
11646        Configuration ci;
11647        synchronized(this) {
11648            ci = new Configuration(mConfiguration);
11649        }
11650        return ci;
11651    }
11652
11653    public void updatePersistentConfiguration(Configuration values) {
11654        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11655                "updateConfiguration()");
11656        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11657                "updateConfiguration()");
11658        if (values == null) {
11659            throw new NullPointerException("Configuration must not be null");
11660        }
11661
11662        synchronized(this) {
11663            final long origId = Binder.clearCallingIdentity();
11664            updateConfigurationLocked(values, null, true, false);
11665            Binder.restoreCallingIdentity(origId);
11666        }
11667    }
11668
11669    public void updateConfiguration(Configuration values) {
11670        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11671                "updateConfiguration()");
11672
11673        synchronized(this) {
11674            if (values == null && mWindowManager != null) {
11675                // sentinel: fetch the current configuration from the window manager
11676                values = mWindowManager.computeNewConfiguration();
11677            }
11678
11679            if (mWindowManager != null) {
11680                mProcessList.applyDisplaySize(mWindowManager);
11681            }
11682
11683            final long origId = Binder.clearCallingIdentity();
11684            if (values != null) {
11685                Settings.System.clearConfiguration(values);
11686            }
11687            updateConfigurationLocked(values, null, false, false);
11688            Binder.restoreCallingIdentity(origId);
11689        }
11690    }
11691
11692    /**
11693     * Do either or both things: (1) change the current configuration, and (2)
11694     * make sure the given activity is running with the (now) current
11695     * configuration.  Returns true if the activity has been left running, or
11696     * false if <var>starting</var> is being destroyed to match the new
11697     * configuration.
11698     * @param persistent TODO
11699     */
11700    boolean updateConfigurationLocked(Configuration values,
11701            ActivityRecord starting, boolean persistent, boolean initLocale) {
11702        // do nothing if we are headless
11703        if (mHeadless) return true;
11704
11705        int changes = 0;
11706
11707        boolean kept = true;
11708
11709        if (values != null) {
11710            Configuration newConfig = new Configuration(mConfiguration);
11711            changes = newConfig.updateFrom(values);
11712            if (changes != 0) {
11713                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11714                    Slog.i(TAG, "Updating configuration to: " + values);
11715                }
11716
11717                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11718
11719                if (values.locale != null && !initLocale) {
11720                    saveLocaleLocked(values.locale,
11721                                     !values.locale.equals(mConfiguration.locale),
11722                                     values.userSetLocale);
11723                }
11724
11725                mConfigurationSeq++;
11726                if (mConfigurationSeq <= 0) {
11727                    mConfigurationSeq = 1;
11728                }
11729                newConfig.seq = mConfigurationSeq;
11730                mConfiguration = newConfig;
11731                Slog.i(TAG, "Config changed: " + newConfig);
11732
11733                final Configuration configCopy = new Configuration(mConfiguration);
11734
11735                // TODO: If our config changes, should we auto dismiss any currently
11736                // showing dialogs?
11737                mShowDialogs = shouldShowDialogs(newConfig);
11738
11739                AttributeCache ac = AttributeCache.instance();
11740                if (ac != null) {
11741                    ac.updateConfiguration(configCopy);
11742                }
11743
11744                // Make sure all resources in our process are updated
11745                // right now, so that anyone who is going to retrieve
11746                // resource values after we return will be sure to get
11747                // the new ones.  This is especially important during
11748                // boot, where the first config change needs to guarantee
11749                // all resources have that config before following boot
11750                // code is executed.
11751                mSystemThread.applyConfigurationToResources(configCopy);
11752
11753                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11754                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11755                    msg.obj = new Configuration(configCopy);
11756                    mHandler.sendMessage(msg);
11757                }
11758
11759                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11760                    ProcessRecord app = mLruProcesses.get(i);
11761                    try {
11762                        if (app.thread != null) {
11763                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11764                                    + app.processName + " new config " + mConfiguration);
11765                            app.thread.scheduleConfigurationChanged(configCopy);
11766                        }
11767                    } catch (Exception e) {
11768                    }
11769                }
11770                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11771                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11772                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11773                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11774                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11775                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11776                    broadcastIntentLocked(null, null,
11777                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11778                            null, null, 0, null, null,
11779                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11780                }
11781            }
11782        }
11783
11784        if (changes != 0 && starting == null) {
11785            // If the configuration changed, and the caller is not already
11786            // in the process of starting an activity, then find the top
11787            // activity to check if its configuration needs to change.
11788            starting = mMainStack.topRunningActivityLocked(null);
11789        }
11790
11791        if (starting != null) {
11792            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11793            // And we need to make sure at this point that all other activities
11794            // are made visible with the correct configuration.
11795            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11796        }
11797
11798        if (values != null && mWindowManager != null) {
11799            mWindowManager.setNewConfiguration(mConfiguration);
11800        }
11801
11802        return kept;
11803    }
11804
11805    /**
11806     * Decide based on the configuration whether we should shouw the ANR,
11807     * crash, etc dialogs.  The idea is that if there is no affordnace to
11808     * press the on-screen buttons, we shouldn't show the dialog.
11809     *
11810     * A thought: SystemUI might also want to get told about this, the Power
11811     * dialog / global actions also might want different behaviors.
11812     */
11813    private static final boolean shouldShowDialogs(Configuration config) {
11814        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11815                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11816    }
11817
11818    /**
11819     * Save the locale.  You must be inside a synchronized (this) block.
11820     */
11821    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11822        if(isDiff) {
11823            SystemProperties.set("user.language", l.getLanguage());
11824            SystemProperties.set("user.region", l.getCountry());
11825        }
11826
11827        if(isPersist) {
11828            SystemProperties.set("persist.sys.language", l.getLanguage());
11829            SystemProperties.set("persist.sys.country", l.getCountry());
11830            SystemProperties.set("persist.sys.localevar", l.getVariant());
11831        }
11832    }
11833
11834    @Override
11835    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11836        ActivityRecord srec = ActivityRecord.forToken(token);
11837        return srec != null && srec.task.affinity != null &&
11838                srec.task.affinity.equals(destAffinity);
11839    }
11840
11841    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11842            Intent resultData) {
11843        ComponentName dest = destIntent.getComponent();
11844
11845        synchronized (this) {
11846            ActivityRecord srec = ActivityRecord.forToken(token);
11847            if (srec == null) {
11848                return false;
11849            }
11850            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11851            final int start = history.indexOf(srec);
11852            if (start < 0) {
11853                // Current activity is not in history stack; do nothing.
11854                return false;
11855            }
11856            int finishTo = start - 1;
11857            ActivityRecord parent = null;
11858            boolean foundParentInTask = false;
11859            if (dest != null) {
11860                TaskRecord tr = srec.task;
11861                for (int i = start - 1; i >= 0; i--) {
11862                    ActivityRecord r = history.get(i);
11863                    if (tr != r.task) {
11864                        // Couldn't find parent in the same task; stop at the one above this.
11865                        // (Root of current task; in-app "home" behavior)
11866                        // Always at least finish the current activity.
11867                        finishTo = Math.min(start - 1, i + 1);
11868                        parent = history.get(finishTo);
11869                        break;
11870                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11871                            r.info.name.equals(dest.getClassName())) {
11872                        finishTo = i;
11873                        parent = r;
11874                        foundParentInTask = true;
11875                        break;
11876                    }
11877                }
11878            }
11879
11880            if (mController != null) {
11881                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11882                if (next != null) {
11883                    // ask watcher if this is allowed
11884                    boolean resumeOK = true;
11885                    try {
11886                        resumeOK = mController.activityResuming(next.packageName);
11887                    } catch (RemoteException e) {
11888                        mController = null;
11889                    }
11890
11891                    if (!resumeOK) {
11892                        return false;
11893                    }
11894                }
11895            }
11896            final long origId = Binder.clearCallingIdentity();
11897            for (int i = start; i > finishTo; i--) {
11898                ActivityRecord r = history.get(i);
11899                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11900                        "navigate-up");
11901                // Only return the supplied result for the first activity finished
11902                resultCode = Activity.RESULT_CANCELED;
11903                resultData = null;
11904            }
11905
11906            if (parent != null && foundParentInTask) {
11907                final int parentLaunchMode = parent.info.launchMode;
11908                final int destIntentFlags = destIntent.getFlags();
11909                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11910                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11911                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11912                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11913                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11914                } else {
11915                    try {
11916                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11917                                destIntent.getComponent(), 0, UserId.getCallingUserId());
11918                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11919                                null, aInfo, parent.appToken, null,
11920                                0, -1, parent.launchedFromUid, 0, null, true, null);
11921                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11922                    } catch (RemoteException e) {
11923                        foundParentInTask = false;
11924                    }
11925                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11926                            resultData, "navigate-up");
11927                }
11928            }
11929            Binder.restoreCallingIdentity(origId);
11930            return foundParentInTask;
11931        }
11932    }
11933
11934    public int getLaunchedFromUid(IBinder activityToken) {
11935        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11936        if (srec == null) {
11937            return -1;
11938        }
11939        return srec.launchedFromUid;
11940    }
11941
11942    // =========================================================
11943    // LIFETIME MANAGEMENT
11944    // =========================================================
11945
11946    // Returns which broadcast queue the app is the current [or imminent] receiver
11947    // on, or 'null' if the app is not an active broadcast recipient.
11948    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11949        BroadcastRecord r = app.curReceiver;
11950        if (r != null) {
11951            return r.queue;
11952        }
11953
11954        // It's not the current receiver, but it might be starting up to become one
11955        synchronized (this) {
11956            for (BroadcastQueue queue : mBroadcastQueues) {
11957                r = queue.mPendingBroadcast;
11958                if (r != null && r.curApp == app) {
11959                    // found it; report which queue it's in
11960                    return queue;
11961                }
11962            }
11963        }
11964
11965        return null;
11966    }
11967
11968    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11969            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
11970        if (mAdjSeq == app.adjSeq) {
11971            // This adjustment has already been computed.  If we are calling
11972            // from the top, we may have already computed our adjustment with
11973            // an earlier hidden adjustment that isn't really for us... if
11974            // so, use the new hidden adjustment.
11975            if (!recursed && app.hidden) {
11976                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
11977            }
11978            return app.curRawAdj;
11979        }
11980
11981        if (app.thread == null) {
11982            app.adjSeq = mAdjSeq;
11983            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11984            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
11985        }
11986
11987        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
11988        app.adjSource = null;
11989        app.adjTarget = null;
11990        app.empty = false;
11991        app.hidden = false;
11992
11993        final int activitiesSize = app.activities.size();
11994
11995        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
11996            // The max adjustment doesn't allow this app to be anything
11997            // below foreground, so it is not worth doing work for it.
11998            app.adjType = "fixed";
11999            app.adjSeq = mAdjSeq;
12000            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12001            app.foregroundActivities = false;
12002            app.keeping = true;
12003            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12004            // System process can do UI, and when they do we want to have
12005            // them trim their memory after the user leaves the UI.  To
12006            // facilitate this, here we need to determine whether or not it
12007            // is currently showing UI.
12008            app.systemNoUi = true;
12009            if (app == TOP_APP) {
12010                app.systemNoUi = false;
12011            } else if (activitiesSize > 0) {
12012                for (int j = 0; j < activitiesSize; j++) {
12013                    final ActivityRecord r = app.activities.get(j);
12014                    if (r.visible) {
12015                        app.systemNoUi = false;
12016                        break;
12017                    }
12018                }
12019            }
12020            return (app.curAdj=app.maxAdj);
12021        }
12022
12023        app.keeping = false;
12024        app.systemNoUi = false;
12025
12026        // Determine the importance of the process, starting with most
12027        // important to least, and assign an appropriate OOM adjustment.
12028        int adj;
12029        int schedGroup;
12030        boolean foregroundActivities = false;
12031        boolean interesting = false;
12032        BroadcastQueue queue;
12033        if (app == TOP_APP) {
12034            // The last app on the list is the foreground app.
12035            adj = ProcessList.FOREGROUND_APP_ADJ;
12036            schedGroup = Process.THREAD_GROUP_DEFAULT;
12037            app.adjType = "top-activity";
12038            foregroundActivities = true;
12039            interesting = true;
12040        } else if (app.instrumentationClass != null) {
12041            // Don't want to kill running instrumentation.
12042            adj = ProcessList.FOREGROUND_APP_ADJ;
12043            schedGroup = Process.THREAD_GROUP_DEFAULT;
12044            app.adjType = "instrumentation";
12045            interesting = true;
12046        } else if ((queue = isReceivingBroadcast(app)) != null) {
12047            // An app that is currently receiving a broadcast also
12048            // counts as being in the foreground for OOM killer purposes.
12049            // It's placed in a sched group based on the nature of the
12050            // broadcast as reflected by which queue it's active in.
12051            adj = ProcessList.FOREGROUND_APP_ADJ;
12052            schedGroup = (queue == mFgBroadcastQueue)
12053                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12054            app.adjType = "broadcast";
12055        } else if (app.executingServices.size() > 0) {
12056            // An app that is currently executing a service callback also
12057            // counts as being in the foreground.
12058            adj = ProcessList.FOREGROUND_APP_ADJ;
12059            schedGroup = Process.THREAD_GROUP_DEFAULT;
12060            app.adjType = "exec-service";
12061        } else if (activitiesSize > 0) {
12062            // This app is in the background with paused activities.
12063            // We inspect activities to potentially upgrade adjustment further below.
12064            adj = hiddenAdj;
12065            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12066            app.hidden = true;
12067            app.adjType = "bg-activities";
12068        } else {
12069            // A very not-needed process.  If this is lower in the lru list,
12070            // we will push it in to the empty bucket.
12071            adj = hiddenAdj;
12072            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12073            app.hidden = true;
12074            app.empty = true;
12075            app.adjType = "bg-empty";
12076        }
12077
12078        boolean hasStoppingActivities = false;
12079
12080        // Examine all activities if not already foreground.
12081        if (!foregroundActivities && activitiesSize > 0) {
12082            for (int j = 0; j < activitiesSize; j++) {
12083                final ActivityRecord r = app.activities.get(j);
12084                if (r.visible) {
12085                    // App has a visible activity; only upgrade adjustment.
12086                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12087                        adj = ProcessList.VISIBLE_APP_ADJ;
12088                        app.adjType = "visible";
12089                    }
12090                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12091                    app.hidden = false;
12092                    foregroundActivities = true;
12093                    break;
12094                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12095                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12096                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12097                        app.adjType = "pausing";
12098                    }
12099                    app.hidden = false;
12100                    foregroundActivities = true;
12101                } else if (r.state == ActivityState.STOPPING) {
12102                    // We will apply the actual adjustment later, because
12103                    // we want to allow this process to immediately go through
12104                    // any memory trimming that is in effect.
12105                    app.hidden = false;
12106                    foregroundActivities = true;
12107                    hasStoppingActivities = true;
12108                }
12109            }
12110        }
12111
12112        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12113            if (app.foregroundServices) {
12114                // The user is aware of this app, so make it visible.
12115                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12116                app.hidden = false;
12117                app.adjType = "foreground-service";
12118                schedGroup = Process.THREAD_GROUP_DEFAULT;
12119            } else if (app.forcingToForeground != null) {
12120                // The user is aware of this app, so make it visible.
12121                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12122                app.hidden = false;
12123                app.adjType = "force-foreground";
12124                app.adjSource = app.forcingToForeground;
12125                schedGroup = Process.THREAD_GROUP_DEFAULT;
12126            }
12127        }
12128
12129        if (app.foregroundServices) {
12130            interesting = true;
12131        }
12132
12133        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12134            // We don't want to kill the current heavy-weight process.
12135            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12136            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12137            app.hidden = false;
12138            app.adjType = "heavy";
12139        }
12140
12141        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12142            // This process is hosting what we currently consider to be the
12143            // home app, so we don't want to let it go into the background.
12144            adj = ProcessList.HOME_APP_ADJ;
12145            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12146            app.hidden = false;
12147            app.adjType = "home";
12148        }
12149
12150        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12151                && app.activities.size() > 0) {
12152            // This was the previous process that showed UI to the user.
12153            // We want to try to keep it around more aggressively, to give
12154            // a good experience around switching between two apps.
12155            adj = ProcessList.PREVIOUS_APP_ADJ;
12156            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12157            app.hidden = false;
12158            app.adjType = "previous";
12159        }
12160
12161        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12162                + " reason=" + app.adjType);
12163
12164        // By default, we use the computed adjustment.  It may be changed if
12165        // there are applications dependent on our services or providers, but
12166        // this gives us a baseline and makes sure we don't get into an
12167        // infinite recursion.
12168        app.adjSeq = mAdjSeq;
12169        app.curRawAdj = app.nonStoppingAdj = adj;
12170
12171        if (mBackupTarget != null && app == mBackupTarget.app) {
12172            // If possible we want to avoid killing apps while they're being backed up
12173            if (adj > ProcessList.BACKUP_APP_ADJ) {
12174                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12175                adj = ProcessList.BACKUP_APP_ADJ;
12176                app.adjType = "backup";
12177                app.hidden = false;
12178            }
12179        }
12180
12181        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12182                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12183            final long now = SystemClock.uptimeMillis();
12184            // This process is more important if the top activity is
12185            // bound to the service.
12186            Iterator<ServiceRecord> jt = app.services.iterator();
12187            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12188                ServiceRecord s = jt.next();
12189                if (s.startRequested) {
12190                    if (app.hasShownUi && app != mHomeProcess) {
12191                        // If this process has shown some UI, let it immediately
12192                        // go to the LRU list because it may be pretty heavy with
12193                        // UI stuff.  We'll tag it with a label just to help
12194                        // debug and understand what is going on.
12195                        if (adj > ProcessList.SERVICE_ADJ) {
12196                            app.adjType = "started-bg-ui-services";
12197                        }
12198                    } else {
12199                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12200                            // This service has seen some activity within
12201                            // recent memory, so we will keep its process ahead
12202                            // of the background processes.
12203                            if (adj > ProcessList.SERVICE_ADJ) {
12204                                adj = ProcessList.SERVICE_ADJ;
12205                                app.adjType = "started-services";
12206                                app.hidden = false;
12207                            }
12208                        }
12209                        // If we have let the service slide into the background
12210                        // state, still have some text describing what it is doing
12211                        // even though the service no longer has an impact.
12212                        if (adj > ProcessList.SERVICE_ADJ) {
12213                            app.adjType = "started-bg-services";
12214                        }
12215                    }
12216                    // Don't kill this process because it is doing work; it
12217                    // has said it is doing work.
12218                    app.keeping = true;
12219                }
12220                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12221                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12222                    Iterator<ArrayList<ConnectionRecord>> kt
12223                            = s.connections.values().iterator();
12224                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12225                        ArrayList<ConnectionRecord> clist = kt.next();
12226                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12227                            // XXX should compute this based on the max of
12228                            // all connected clients.
12229                            ConnectionRecord cr = clist.get(i);
12230                            if (cr.binding.client == app) {
12231                                // Binding to ourself is not interesting.
12232                                continue;
12233                            }
12234                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12235                                ProcessRecord client = cr.binding.client;
12236                                int clientAdj = adj;
12237                                int myHiddenAdj = hiddenAdj;
12238                                if (myHiddenAdj > client.hiddenAdj) {
12239                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12240                                        myHiddenAdj = client.hiddenAdj;
12241                                    } else {
12242                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12243                                    }
12244                                }
12245                                clientAdj = computeOomAdjLocked(
12246                                    client, myHiddenAdj, TOP_APP, true, doingAll);
12247                                String adjType = null;
12248                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12249                                    // Not doing bind OOM management, so treat
12250                                    // this guy more like a started service.
12251                                    if (app.hasShownUi && app != mHomeProcess) {
12252                                        // If this process has shown some UI, let it immediately
12253                                        // go to the LRU list because it may be pretty heavy with
12254                                        // UI stuff.  We'll tag it with a label just to help
12255                                        // debug and understand what is going on.
12256                                        if (adj > clientAdj) {
12257                                            adjType = "bound-bg-ui-services";
12258                                        }
12259                                        app.hidden = false;
12260                                        clientAdj = adj;
12261                                    } else {
12262                                        if (now >= (s.lastActivity
12263                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12264                                            // This service has not seen activity within
12265                                            // recent memory, so allow it to drop to the
12266                                            // LRU list if there is no other reason to keep
12267                                            // it around.  We'll also tag it with a label just
12268                                            // to help debug and undertand what is going on.
12269                                            if (adj > clientAdj) {
12270                                                adjType = "bound-bg-services";
12271                                            }
12272                                            clientAdj = adj;
12273                                        }
12274                                    }
12275                                }
12276                                if (adj > clientAdj) {
12277                                    // If this process has recently shown UI, and
12278                                    // the process that is binding to it is less
12279                                    // important than being visible, then we don't
12280                                    // care about the binding as much as we care
12281                                    // about letting this process get into the LRU
12282                                    // list to be killed and restarted if needed for
12283                                    // memory.
12284                                    if (app.hasShownUi && app != mHomeProcess
12285                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12286                                        adjType = "bound-bg-ui-services";
12287                                    } else {
12288                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12289                                                |Context.BIND_IMPORTANT)) != 0) {
12290                                            adj = clientAdj;
12291                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12292                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12293                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12294                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12295                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12296                                            adj = clientAdj;
12297                                        } else {
12298                                            app.pendingUiClean = true;
12299                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12300                                                adj = ProcessList.VISIBLE_APP_ADJ;
12301                                            }
12302                                        }
12303                                        if (!client.hidden) {
12304                                            app.hidden = false;
12305                                        }
12306                                        if (client.keeping) {
12307                                            app.keeping = true;
12308                                        }
12309                                        adjType = "service";
12310                                    }
12311                                }
12312                                if (adjType != null) {
12313                                    app.adjType = adjType;
12314                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12315                                            .REASON_SERVICE_IN_USE;
12316                                    app.adjSource = cr.binding.client;
12317                                    app.adjSourceOom = clientAdj;
12318                                    app.adjTarget = s.name;
12319                                }
12320                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12321                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12322                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12323                                    }
12324                                }
12325                            }
12326                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12327                                ActivityRecord a = cr.activity;
12328                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12329                                        (a.visible || a.state == ActivityState.RESUMED
12330                                         || a.state == ActivityState.PAUSING)) {
12331                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12332                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12333                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12334                                    }
12335                                    app.hidden = false;
12336                                    app.adjType = "service";
12337                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12338                                            .REASON_SERVICE_IN_USE;
12339                                    app.adjSource = a;
12340                                    app.adjSourceOom = adj;
12341                                    app.adjTarget = s.name;
12342                                }
12343                            }
12344                        }
12345                    }
12346                }
12347            }
12348
12349            // Finally, if this process has active services running in it, we
12350            // would like to avoid killing it unless it would prevent the current
12351            // application from running.  By default we put the process in
12352            // with the rest of the background processes; as we scan through
12353            // its services we may bump it up from there.
12354            if (adj > hiddenAdj) {
12355                adj = hiddenAdj;
12356                app.hidden = false;
12357                app.adjType = "bg-services";
12358            }
12359        }
12360
12361        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12362                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12363            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12364            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12365                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12366                ContentProviderRecord cpr = jt.next();
12367                for (int i = cpr.connections.size()-1;
12368                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12369                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12370                        i--) {
12371                    ContentProviderConnection conn = cpr.connections.get(i);
12372                    ProcessRecord client = conn.client;
12373                    if (client == app) {
12374                        // Being our own client is not interesting.
12375                        continue;
12376                    }
12377                    int myHiddenAdj = hiddenAdj;
12378                    if (myHiddenAdj > client.hiddenAdj) {
12379                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12380                            myHiddenAdj = client.hiddenAdj;
12381                        } else {
12382                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12383                        }
12384                    }
12385                    int clientAdj = computeOomAdjLocked(
12386                        client, myHiddenAdj, TOP_APP, true, doingAll);
12387                    if (adj > clientAdj) {
12388                        if (app.hasShownUi && app != mHomeProcess
12389                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12390                            app.adjType = "bg-ui-provider";
12391                        } else {
12392                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12393                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12394                            app.adjType = "provider";
12395                        }
12396                        if (!client.hidden) {
12397                            app.hidden = false;
12398                        }
12399                        if (client.keeping) {
12400                            app.keeping = true;
12401                        }
12402                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12403                                .REASON_PROVIDER_IN_USE;
12404                        app.adjSource = client;
12405                        app.adjSourceOom = clientAdj;
12406                        app.adjTarget = cpr.name;
12407                    }
12408                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12409                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12410                    }
12411                }
12412                // If the provider has external (non-framework) process
12413                // dependencies, ensure that its adjustment is at least
12414                // FOREGROUND_APP_ADJ.
12415                if (cpr.hasExternalProcessHandles()) {
12416                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12417                        adj = ProcessList.FOREGROUND_APP_ADJ;
12418                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12419                        app.hidden = false;
12420                        app.keeping = true;
12421                        app.adjType = "provider";
12422                        app.adjTarget = cpr.name;
12423                    }
12424                }
12425            }
12426        }
12427
12428        if (adj == ProcessList.SERVICE_ADJ) {
12429            if (doingAll) {
12430                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12431                mNewNumServiceProcs++;
12432            }
12433            if (app.serviceb) {
12434                adj = ProcessList.SERVICE_B_ADJ;
12435            }
12436        } else {
12437            app.serviceb = false;
12438        }
12439
12440        app.nonStoppingAdj = adj;
12441
12442        if (hasStoppingActivities) {
12443            // Only upgrade adjustment.
12444            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12445                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12446                app.adjType = "stopping";
12447            }
12448        }
12449
12450        app.curRawAdj = adj;
12451
12452        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12453        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12454        if (adj > app.maxAdj) {
12455            adj = app.maxAdj;
12456            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12457                schedGroup = Process.THREAD_GROUP_DEFAULT;
12458            }
12459        }
12460        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12461            app.keeping = true;
12462        }
12463
12464        if (app.hasAboveClient) {
12465            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12466            // then we need to drop its adjustment to be lower than the service's
12467            // in order to honor the request.  We want to drop it by one adjustment
12468            // level...  but there is special meaning applied to various levels so
12469            // we will skip some of them.
12470            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12471                // System process will not get dropped, ever
12472            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12473                adj = ProcessList.VISIBLE_APP_ADJ;
12474            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12475                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12476            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12477                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12478            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12479                adj++;
12480            }
12481        }
12482
12483        int importance = app.memImportance;
12484        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12485            app.curAdj = adj;
12486            app.curSchedGroup = schedGroup;
12487            if (!interesting) {
12488                // For this reporting, if there is not something explicitly
12489                // interesting in this process then we will push it to the
12490                // background importance.
12491                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12492            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12493                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12494            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12495                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12496            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12497                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12498            } else if (adj >= ProcessList.SERVICE_ADJ) {
12499                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12500            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12501                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12502            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12503                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12504            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12505                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12506            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12507                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12508            } else {
12509                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12510            }
12511        }
12512
12513        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12514        if (foregroundActivities != app.foregroundActivities) {
12515            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12516        }
12517        if (changes != 0) {
12518            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12519            app.memImportance = importance;
12520            app.foregroundActivities = foregroundActivities;
12521            int i = mPendingProcessChanges.size()-1;
12522            ProcessChangeItem item = null;
12523            while (i >= 0) {
12524                item = mPendingProcessChanges.get(i);
12525                if (item.pid == app.pid) {
12526                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12527                    break;
12528                }
12529                i--;
12530            }
12531            if (i < 0) {
12532                // No existing item in pending changes; need a new one.
12533                final int NA = mAvailProcessChanges.size();
12534                if (NA > 0) {
12535                    item = mAvailProcessChanges.remove(NA-1);
12536                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12537                } else {
12538                    item = new ProcessChangeItem();
12539                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12540                }
12541                item.changes = 0;
12542                item.pid = app.pid;
12543                item.uid = app.info.uid;
12544                if (mPendingProcessChanges.size() == 0) {
12545                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12546                            "*** Enqueueing dispatch processes changed!");
12547                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12548                }
12549                mPendingProcessChanges.add(item);
12550            }
12551            item.changes |= changes;
12552            item.importance = importance;
12553            item.foregroundActivities = foregroundActivities;
12554            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12555                    + Integer.toHexString(System.identityHashCode(item))
12556                    + " " + app.toShortString() + ": changes=" + item.changes
12557                    + " importance=" + item.importance
12558                    + " foreground=" + item.foregroundActivities
12559                    + " type=" + app.adjType + " source=" + app.adjSource
12560                    + " target=" + app.adjTarget);
12561        }
12562
12563        return app.curRawAdj;
12564    }
12565
12566    /**
12567     * Ask a given process to GC right now.
12568     */
12569    final void performAppGcLocked(ProcessRecord app) {
12570        try {
12571            app.lastRequestedGc = SystemClock.uptimeMillis();
12572            if (app.thread != null) {
12573                if (app.reportLowMemory) {
12574                    app.reportLowMemory = false;
12575                    app.thread.scheduleLowMemory();
12576                } else {
12577                    app.thread.processInBackground();
12578                }
12579            }
12580        } catch (Exception e) {
12581            // whatever.
12582        }
12583    }
12584
12585    /**
12586     * Returns true if things are idle enough to perform GCs.
12587     */
12588    private final boolean canGcNowLocked() {
12589        boolean processingBroadcasts = false;
12590        for (BroadcastQueue q : mBroadcastQueues) {
12591            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12592                processingBroadcasts = true;
12593            }
12594        }
12595        return !processingBroadcasts
12596                && (mSleeping || (mMainStack.mResumedActivity != null &&
12597                        mMainStack.mResumedActivity.idle));
12598    }
12599
12600    /**
12601     * Perform GCs on all processes that are waiting for it, but only
12602     * if things are idle.
12603     */
12604    final void performAppGcsLocked() {
12605        final int N = mProcessesToGc.size();
12606        if (N <= 0) {
12607            return;
12608        }
12609        if (canGcNowLocked()) {
12610            while (mProcessesToGc.size() > 0) {
12611                ProcessRecord proc = mProcessesToGc.remove(0);
12612                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12613                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12614                            <= SystemClock.uptimeMillis()) {
12615                        // To avoid spamming the system, we will GC processes one
12616                        // at a time, waiting a few seconds between each.
12617                        performAppGcLocked(proc);
12618                        scheduleAppGcsLocked();
12619                        return;
12620                    } else {
12621                        // It hasn't been long enough since we last GCed this
12622                        // process...  put it in the list to wait for its time.
12623                        addProcessToGcListLocked(proc);
12624                        break;
12625                    }
12626                }
12627            }
12628
12629            scheduleAppGcsLocked();
12630        }
12631    }
12632
12633    /**
12634     * If all looks good, perform GCs on all processes waiting for them.
12635     */
12636    final void performAppGcsIfAppropriateLocked() {
12637        if (canGcNowLocked()) {
12638            performAppGcsLocked();
12639            return;
12640        }
12641        // Still not idle, wait some more.
12642        scheduleAppGcsLocked();
12643    }
12644
12645    /**
12646     * Schedule the execution of all pending app GCs.
12647     */
12648    final void scheduleAppGcsLocked() {
12649        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12650
12651        if (mProcessesToGc.size() > 0) {
12652            // Schedule a GC for the time to the next process.
12653            ProcessRecord proc = mProcessesToGc.get(0);
12654            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12655
12656            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12657            long now = SystemClock.uptimeMillis();
12658            if (when < (now+GC_TIMEOUT)) {
12659                when = now + GC_TIMEOUT;
12660            }
12661            mHandler.sendMessageAtTime(msg, when);
12662        }
12663    }
12664
12665    /**
12666     * Add a process to the array of processes waiting to be GCed.  Keeps the
12667     * list in sorted order by the last GC time.  The process can't already be
12668     * on the list.
12669     */
12670    final void addProcessToGcListLocked(ProcessRecord proc) {
12671        boolean added = false;
12672        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12673            if (mProcessesToGc.get(i).lastRequestedGc <
12674                    proc.lastRequestedGc) {
12675                added = true;
12676                mProcessesToGc.add(i+1, proc);
12677                break;
12678            }
12679        }
12680        if (!added) {
12681            mProcessesToGc.add(0, proc);
12682        }
12683    }
12684
12685    /**
12686     * Set up to ask a process to GC itself.  This will either do it
12687     * immediately, or put it on the list of processes to gc the next
12688     * time things are idle.
12689     */
12690    final void scheduleAppGcLocked(ProcessRecord app) {
12691        long now = SystemClock.uptimeMillis();
12692        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12693            return;
12694        }
12695        if (!mProcessesToGc.contains(app)) {
12696            addProcessToGcListLocked(app);
12697            scheduleAppGcsLocked();
12698        }
12699    }
12700
12701    final void checkExcessivePowerUsageLocked(boolean doKills) {
12702        updateCpuStatsNow();
12703
12704        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12705        boolean doWakeKills = doKills;
12706        boolean doCpuKills = doKills;
12707        if (mLastPowerCheckRealtime == 0) {
12708            doWakeKills = false;
12709        }
12710        if (mLastPowerCheckUptime == 0) {
12711            doCpuKills = false;
12712        }
12713        if (stats.isScreenOn()) {
12714            doWakeKills = false;
12715        }
12716        final long curRealtime = SystemClock.elapsedRealtime();
12717        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12718        final long curUptime = SystemClock.uptimeMillis();
12719        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12720        mLastPowerCheckRealtime = curRealtime;
12721        mLastPowerCheckUptime = curUptime;
12722        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12723            doWakeKills = false;
12724        }
12725        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12726            doCpuKills = false;
12727        }
12728        int i = mLruProcesses.size();
12729        while (i > 0) {
12730            i--;
12731            ProcessRecord app = mLruProcesses.get(i);
12732            if (!app.keeping) {
12733                long wtime;
12734                synchronized (stats) {
12735                    wtime = stats.getProcessWakeTime(app.info.uid,
12736                            app.pid, curRealtime);
12737                }
12738                long wtimeUsed = wtime - app.lastWakeTime;
12739                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12740                if (DEBUG_POWER) {
12741                    StringBuilder sb = new StringBuilder(128);
12742                    sb.append("Wake for ");
12743                    app.toShortString(sb);
12744                    sb.append(": over ");
12745                    TimeUtils.formatDuration(realtimeSince, sb);
12746                    sb.append(" used ");
12747                    TimeUtils.formatDuration(wtimeUsed, sb);
12748                    sb.append(" (");
12749                    sb.append((wtimeUsed*100)/realtimeSince);
12750                    sb.append("%)");
12751                    Slog.i(TAG, sb.toString());
12752                    sb.setLength(0);
12753                    sb.append("CPU for ");
12754                    app.toShortString(sb);
12755                    sb.append(": over ");
12756                    TimeUtils.formatDuration(uptimeSince, sb);
12757                    sb.append(" used ");
12758                    TimeUtils.formatDuration(cputimeUsed, sb);
12759                    sb.append(" (");
12760                    sb.append((cputimeUsed*100)/uptimeSince);
12761                    sb.append("%)");
12762                    Slog.i(TAG, sb.toString());
12763                }
12764                // If a process has held a wake lock for more
12765                // than 50% of the time during this period,
12766                // that sounds bad.  Kill!
12767                if (doWakeKills && realtimeSince > 0
12768                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12769                    synchronized (stats) {
12770                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12771                                realtimeSince, wtimeUsed);
12772                    }
12773                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12774                            + " (pid " + app.pid + "): held " + wtimeUsed
12775                            + " during " + realtimeSince);
12776                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12777                            app.processName, app.setAdj, "excessive wake lock");
12778                    Process.killProcessQuiet(app.pid);
12779                } else if (doCpuKills && uptimeSince > 0
12780                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12781                    synchronized (stats) {
12782                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12783                                uptimeSince, cputimeUsed);
12784                    }
12785                    Slog.w(TAG, "Excessive CPU in " + app.processName
12786                            + " (pid " + app.pid + "): used " + cputimeUsed
12787                            + " during " + uptimeSince);
12788                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12789                            app.processName, app.setAdj, "excessive cpu");
12790                    Process.killProcessQuiet(app.pid);
12791                } else {
12792                    app.lastWakeTime = wtime;
12793                    app.lastCpuTime = app.curCpuTime;
12794                }
12795            }
12796        }
12797    }
12798
12799    private final boolean updateOomAdjLocked(
12800            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
12801        app.hiddenAdj = hiddenAdj;
12802
12803        if (app.thread == null) {
12804            return false;
12805        }
12806
12807        final boolean wasKeeping = app.keeping;
12808
12809        boolean success = true;
12810
12811        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
12812
12813        if (app.curRawAdj != app.setRawAdj) {
12814            if (wasKeeping && !app.keeping) {
12815                // This app is no longer something we want to keep.  Note
12816                // its current wake lock time to later know to kill it if
12817                // it is not behaving well.
12818                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12819                synchronized (stats) {
12820                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12821                            app.pid, SystemClock.elapsedRealtime());
12822                }
12823                app.lastCpuTime = app.curCpuTime;
12824            }
12825
12826            app.setRawAdj = app.curRawAdj;
12827        }
12828
12829        if (app.curAdj != app.setAdj) {
12830            if (Process.setOomAdj(app.pid, app.curAdj)) {
12831                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12832                    TAG, "Set " + app.pid + " " + app.processName +
12833                    " adj " + app.curAdj + ": " + app.adjType);
12834                app.setAdj = app.curAdj;
12835            } else {
12836                success = false;
12837                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12838            }
12839        }
12840        if (app.setSchedGroup != app.curSchedGroup) {
12841            app.setSchedGroup = app.curSchedGroup;
12842            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12843                    "Setting process group of " + app.processName
12844                    + " to " + app.curSchedGroup);
12845            if (app.waitingToKill != null &&
12846                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12847                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12848                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12849                        app.processName, app.setAdj, app.waitingToKill);
12850                app.killedBackground = true;
12851                Process.killProcessQuiet(app.pid);
12852                success = false;
12853            } else {
12854                if (true) {
12855                    long oldId = Binder.clearCallingIdentity();
12856                    try {
12857                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12858                    } catch (Exception e) {
12859                        Slog.w(TAG, "Failed setting process group of " + app.pid
12860                                + " to " + app.curSchedGroup);
12861                        e.printStackTrace();
12862                    } finally {
12863                        Binder.restoreCallingIdentity(oldId);
12864                    }
12865                } else {
12866                    if (app.thread != null) {
12867                        try {
12868                            app.thread.setSchedulingGroup(app.curSchedGroup);
12869                        } catch (RemoteException e) {
12870                        }
12871                    }
12872                }
12873            }
12874        }
12875        return success;
12876    }
12877
12878    private final ActivityRecord resumedAppLocked() {
12879        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12880        if (resumedActivity == null || resumedActivity.app == null) {
12881            resumedActivity = mMainStack.mPausingActivity;
12882            if (resumedActivity == null || resumedActivity.app == null) {
12883                resumedActivity = mMainStack.topRunningActivityLocked(null);
12884            }
12885        }
12886        return resumedActivity;
12887    }
12888
12889    final boolean updateOomAdjLocked(ProcessRecord app) {
12890        final ActivityRecord TOP_ACT = resumedAppLocked();
12891        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12892        int curAdj = app.curAdj;
12893        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12894            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12895
12896        mAdjSeq++;
12897
12898        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
12899        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12900            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12901        if (nowHidden != wasHidden) {
12902            // Changed to/from hidden state, so apps after it in the LRU
12903            // list may also be changed.
12904            updateOomAdjLocked();
12905        }
12906        return success;
12907    }
12908
12909    final void updateOomAdjLocked() {
12910        final ActivityRecord TOP_ACT = resumedAppLocked();
12911        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12912
12913        if (false) {
12914            RuntimeException e = new RuntimeException();
12915            e.fillInStackTrace();
12916            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12917        }
12918
12919        mAdjSeq++;
12920        mNewNumServiceProcs = 0;
12921
12922        // Let's determine how many processes we have running vs.
12923        // how many slots we have for background processes; we may want
12924        // to put multiple processes in a slot of there are enough of
12925        // them.
12926        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
12927        int factor = (mLruProcesses.size()-4)/numSlots;
12928        if (factor < 1) factor = 1;
12929        int step = 0;
12930        int numHidden = 0;
12931        int numTrimming = 0;
12932
12933        // First update the OOM adjustment for each of the
12934        // application processes based on their current state.
12935        int i = mLruProcesses.size();
12936        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
12937        while (i > 0) {
12938            i--;
12939            ProcessRecord app = mLruProcesses.get(i);
12940            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
12941            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
12942            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
12943                && app.curAdj == curHiddenAdj) {
12944                step++;
12945                if (step >= factor) {
12946                    step = 0;
12947                    curHiddenAdj++;
12948                }
12949            }
12950            if (!app.killedBackground) {
12951                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12952                    numHidden++;
12953                    if (numHidden > mProcessLimit) {
12954                        Slog.i(TAG, "No longer want " + app.processName
12955                                + " (pid " + app.pid + "): hidden #" + numHidden);
12956                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12957                                app.processName, app.setAdj, "too many background");
12958                        app.killedBackground = true;
12959                        Process.killProcessQuiet(app.pid);
12960                    }
12961                }
12962                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
12963                    // If this is an isolated process, and there are no
12964                    // services running in it, then the process is no longer
12965                    // needed.  We agressively kill these because we can by
12966                    // definition not re-use the same process again, and it is
12967                    // good to avoid having whatever code was running in them
12968                    // left sitting around after no longer needed.
12969                    Slog.i(TAG, "Isolated process " + app.processName
12970                            + " (pid " + app.pid + ") no longer needed");
12971                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12972                            app.processName, app.setAdj, "isolated not needed");
12973                    app.killedBackground = true;
12974                    Process.killProcessQuiet(app.pid);
12975                }
12976                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
12977                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
12978                        && !app.killedBackground) {
12979                    numTrimming++;
12980                }
12981            }
12982        }
12983
12984        mNumServiceProcs = mNewNumServiceProcs;
12985
12986        // Now determine the memory trimming level of background processes.
12987        // Unfortunately we need to start at the back of the list to do this
12988        // properly.  We only do this if the number of background apps we
12989        // are managing to keep around is less than half the maximum we desire;
12990        // if we are keeping a good number around, we'll let them use whatever
12991        // memory they want.
12992        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
12993            final int N = mLruProcesses.size();
12994            factor = numTrimming/3;
12995            int minFactor = 2;
12996            if (mHomeProcess != null) minFactor++;
12997            if (mPreviousProcess != null) minFactor++;
12998            if (factor < minFactor) factor = minFactor;
12999            step = 0;
13000            int fgTrimLevel;
13001            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13002                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13003            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13004                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13005            } else {
13006                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13007            }
13008            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13009            for (i=0; i<N; i++) {
13010                ProcessRecord app = mLruProcesses.get(i);
13011                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13012                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13013                        && !app.killedBackground) {
13014                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13015                        try {
13016                            app.thread.scheduleTrimMemory(curLevel);
13017                        } catch (RemoteException e) {
13018                        }
13019                        if (false) {
13020                            // For now we won't do this; our memory trimming seems
13021                            // to be good enough at this point that destroying
13022                            // activities causes more harm than good.
13023                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13024                                    && app != mHomeProcess && app != mPreviousProcess) {
13025                                // Need to do this on its own message because the stack may not
13026                                // be in a consistent state at this point.
13027                                // For these apps we will also finish their activities
13028                                // to help them free memory.
13029                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13030                            }
13031                        }
13032                    }
13033                    app.trimMemoryLevel = curLevel;
13034                    step++;
13035                    if (step >= factor) {
13036                        step = 0;
13037                        switch (curLevel) {
13038                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13039                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13040                                break;
13041                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13042                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13043                                break;
13044                        }
13045                    }
13046                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13047                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13048                            && app.thread != null) {
13049                        try {
13050                            app.thread.scheduleTrimMemory(
13051                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13052                        } catch (RemoteException e) {
13053                        }
13054                    }
13055                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13056                } else {
13057                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13058                            && app.pendingUiClean) {
13059                        // If this application is now in the background and it
13060                        // had done UI, then give it the special trim level to
13061                        // have it free UI resources.
13062                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13063                        if (app.trimMemoryLevel < level && app.thread != null) {
13064                            try {
13065                                app.thread.scheduleTrimMemory(level);
13066                            } catch (RemoteException e) {
13067                            }
13068                        }
13069                        app.pendingUiClean = false;
13070                    }
13071                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13072                        try {
13073                            app.thread.scheduleTrimMemory(fgTrimLevel);
13074                        } catch (RemoteException e) {
13075                        }
13076                    }
13077                    app.trimMemoryLevel = fgTrimLevel;
13078                }
13079            }
13080        } else {
13081            final int N = mLruProcesses.size();
13082            for (i=0; i<N; i++) {
13083                ProcessRecord app = mLruProcesses.get(i);
13084                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13085                        && app.pendingUiClean) {
13086                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13087                            && app.thread != null) {
13088                        try {
13089                            app.thread.scheduleTrimMemory(
13090                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13091                        } catch (RemoteException e) {
13092                        }
13093                    }
13094                    app.pendingUiClean = false;
13095                }
13096                app.trimMemoryLevel = 0;
13097            }
13098        }
13099
13100        if (mAlwaysFinishActivities) {
13101            // Need to do this on its own message because the stack may not
13102            // be in a consistent state at this point.
13103            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13104        }
13105    }
13106
13107    final void trimApplications() {
13108        synchronized (this) {
13109            int i;
13110
13111            // First remove any unused application processes whose package
13112            // has been removed.
13113            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13114                final ProcessRecord app = mRemovedProcesses.get(i);
13115                if (app.activities.size() == 0
13116                        && app.curReceiver == null && app.services.size() == 0) {
13117                    Slog.i(
13118                        TAG, "Exiting empty application process "
13119                        + app.processName + " ("
13120                        + (app.thread != null ? app.thread.asBinder() : null)
13121                        + ")\n");
13122                    if (app.pid > 0 && app.pid != MY_PID) {
13123                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13124                                app.processName, app.setAdj, "empty");
13125                        Process.killProcessQuiet(app.pid);
13126                    } else {
13127                        try {
13128                            app.thread.scheduleExit();
13129                        } catch (Exception e) {
13130                            // Ignore exceptions.
13131                        }
13132                    }
13133                    cleanUpApplicationRecordLocked(app, false, true, -1);
13134                    mRemovedProcesses.remove(i);
13135
13136                    if (app.persistent) {
13137                        if (app.persistent) {
13138                            addAppLocked(app.info, false);
13139                        }
13140                    }
13141                }
13142            }
13143
13144            // Now update the oom adj for all processes.
13145            updateOomAdjLocked();
13146        }
13147    }
13148
13149    /** This method sends the specified signal to each of the persistent apps */
13150    public void signalPersistentProcesses(int sig) throws RemoteException {
13151        if (sig != Process.SIGNAL_USR1) {
13152            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13153        }
13154
13155        synchronized (this) {
13156            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13157                    != PackageManager.PERMISSION_GRANTED) {
13158                throw new SecurityException("Requires permission "
13159                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13160            }
13161
13162            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13163                ProcessRecord r = mLruProcesses.get(i);
13164                if (r.thread != null && r.persistent) {
13165                    Process.sendSignal(r.pid, sig);
13166                }
13167            }
13168        }
13169    }
13170
13171    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13172        if (proc == null || proc == mProfileProc) {
13173            proc = mProfileProc;
13174            path = mProfileFile;
13175            profileType = mProfileType;
13176            clearProfilerLocked();
13177        }
13178        if (proc == null) {
13179            return;
13180        }
13181        try {
13182            proc.thread.profilerControl(false, path, null, profileType);
13183        } catch (RemoteException e) {
13184            throw new IllegalStateException("Process disappeared");
13185        }
13186    }
13187
13188    private void clearProfilerLocked() {
13189        if (mProfileFd != null) {
13190            try {
13191                mProfileFd.close();
13192            } catch (IOException e) {
13193            }
13194        }
13195        mProfileApp = null;
13196        mProfileProc = null;
13197        mProfileFile = null;
13198        mProfileType = 0;
13199        mAutoStopProfiler = false;
13200    }
13201
13202    public boolean profileControl(String process, boolean start,
13203            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13204
13205        try {
13206            synchronized (this) {
13207                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13208                // its own permission.
13209                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13210                        != PackageManager.PERMISSION_GRANTED) {
13211                    throw new SecurityException("Requires permission "
13212                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13213                }
13214
13215                if (start && fd == null) {
13216                    throw new IllegalArgumentException("null fd");
13217                }
13218
13219                ProcessRecord proc = null;
13220                if (process != null) {
13221                    try {
13222                        int pid = Integer.parseInt(process);
13223                        synchronized (mPidsSelfLocked) {
13224                            proc = mPidsSelfLocked.get(pid);
13225                        }
13226                    } catch (NumberFormatException e) {
13227                    }
13228
13229                    if (proc == null) {
13230                        HashMap<String, SparseArray<ProcessRecord>> all
13231                                = mProcessNames.getMap();
13232                        SparseArray<ProcessRecord> procs = all.get(process);
13233                        if (procs != null && procs.size() > 0) {
13234                            proc = procs.valueAt(0);
13235                        }
13236                    }
13237                }
13238
13239                if (start && (proc == null || proc.thread == null)) {
13240                    throw new IllegalArgumentException("Unknown process: " + process);
13241                }
13242
13243                if (start) {
13244                    stopProfilerLocked(null, null, 0);
13245                    setProfileApp(proc.info, proc.processName, path, fd, false);
13246                    mProfileProc = proc;
13247                    mProfileType = profileType;
13248                    try {
13249                        fd = fd.dup();
13250                    } catch (IOException e) {
13251                        fd = null;
13252                    }
13253                    proc.thread.profilerControl(start, path, fd, profileType);
13254                    fd = null;
13255                    mProfileFd = null;
13256                } else {
13257                    stopProfilerLocked(proc, path, profileType);
13258                    if (fd != null) {
13259                        try {
13260                            fd.close();
13261                        } catch (IOException e) {
13262                        }
13263                    }
13264                }
13265
13266                return true;
13267            }
13268        } catch (RemoteException e) {
13269            throw new IllegalStateException("Process disappeared");
13270        } finally {
13271            if (fd != null) {
13272                try {
13273                    fd.close();
13274                } catch (IOException e) {
13275                }
13276            }
13277        }
13278    }
13279
13280    public boolean dumpHeap(String process, boolean managed,
13281            String path, ParcelFileDescriptor fd) throws RemoteException {
13282
13283        try {
13284            synchronized (this) {
13285                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13286                // its own permission (same as profileControl).
13287                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13288                        != PackageManager.PERMISSION_GRANTED) {
13289                    throw new SecurityException("Requires permission "
13290                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13291                }
13292
13293                if (fd == null) {
13294                    throw new IllegalArgumentException("null fd");
13295                }
13296
13297                ProcessRecord proc = null;
13298                try {
13299                    int pid = Integer.parseInt(process);
13300                    synchronized (mPidsSelfLocked) {
13301                        proc = mPidsSelfLocked.get(pid);
13302                    }
13303                } catch (NumberFormatException e) {
13304                }
13305
13306                if (proc == null) {
13307                    HashMap<String, SparseArray<ProcessRecord>> all
13308                            = mProcessNames.getMap();
13309                    SparseArray<ProcessRecord> procs = all.get(process);
13310                    if (procs != null && procs.size() > 0) {
13311                        proc = procs.valueAt(0);
13312                    }
13313                }
13314
13315                if (proc == null || proc.thread == null) {
13316                    throw new IllegalArgumentException("Unknown process: " + process);
13317                }
13318
13319                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13320                if (!isDebuggable) {
13321                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13322                        throw new SecurityException("Process not debuggable: " + proc);
13323                    }
13324                }
13325
13326                proc.thread.dumpHeap(managed, path, fd);
13327                fd = null;
13328                return true;
13329            }
13330        } catch (RemoteException e) {
13331            throw new IllegalStateException("Process disappeared");
13332        } finally {
13333            if (fd != null) {
13334                try {
13335                    fd.close();
13336                } catch (IOException e) {
13337                }
13338            }
13339        }
13340    }
13341
13342    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13343    public void monitor() {
13344        synchronized (this) { }
13345    }
13346
13347    void onCoreSettingsChange(Bundle settings) {
13348        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13349            ProcessRecord processRecord = mLruProcesses.get(i);
13350            try {
13351                if (processRecord.thread != null) {
13352                    processRecord.thread.setCoreSettings(settings);
13353                }
13354            } catch (RemoteException re) {
13355                /* ignore */
13356            }
13357        }
13358    }
13359
13360    // Multi-user methods
13361
13362    public boolean switchUser(int userId) {
13363        final int callingUid = Binder.getCallingUid();
13364        if (callingUid != 0 && callingUid != Process.myUid()) {
13365            Slog.e(TAG, "Trying to switch user from unauthorized app");
13366            return false;
13367        }
13368        if (mCurrentUserId == userId)
13369            return true;
13370
13371        synchronized (this) {
13372            // Check if user is already logged in, otherwise check if user exists first before
13373            // adding to the list of logged in users.
13374            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13375                if (!userExists(userId)) {
13376                    return false;
13377                }
13378                mLoggedInUsers.append(userId, userId);
13379            }
13380
13381            mCurrentUserId = userId;
13382            boolean haveActivities = mMainStack.switchUser(userId);
13383            if (!haveActivities) {
13384                startHomeActivityLocked(userId);
13385            }
13386
13387        }
13388
13389        // Inform of user switch
13390        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13391        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
13392        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
13393
13394        return true;
13395    }
13396
13397    @Override
13398    public UserInfo getCurrentUser() throws RemoteException {
13399        final int callingUid = Binder.getCallingUid();
13400        if (callingUid != 0 && callingUid != Process.myUid()) {
13401            Slog.e(TAG, "Trying to get user from unauthorized app");
13402            return null;
13403        }
13404        return getUserManager().getUserInfo(mCurrentUserId);
13405    }
13406
13407    private void onUserRemoved(Intent intent) {
13408        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
13409        if (extraUserId < 1) return;
13410
13411        // Kill all the processes for the user
13412        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13413        synchronized (this) {
13414            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13415            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13416                SparseArray<ProcessRecord> uids = uidMap.getValue();
13417                for (int i = 0; i < uids.size(); i++) {
13418                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
13419                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13420                    }
13421                }
13422            }
13423
13424            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13425                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13426                        false, false, true, true, extraUserId);
13427            }
13428        }
13429    }
13430
13431    private boolean userExists(int userId) {
13432        UserInfo user = getUserManager().getUserInfo(userId);
13433        return user != null;
13434    }
13435
13436    UserManager getUserManager() {
13437        if (mUserManager == null) {
13438            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13439        }
13440        return mUserManager;
13441    }
13442
13443    private void checkValidCaller(int uid, int userId) {
13444        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13445
13446        throw new SecurityException("Caller uid=" + uid
13447                + " is not privileged to communicate with user=" + userId);
13448    }
13449
13450    private int applyUserId(int uid, int userId) {
13451        return UserId.getUid(userId, uid);
13452    }
13453
13454    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13455        if (info == null) return null;
13456        ApplicationInfo newInfo = new ApplicationInfo(info);
13457        newInfo.uid = applyUserId(info.uid, userId);
13458        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13459                + info.packageName;
13460        return newInfo;
13461    }
13462
13463    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13464        if (aInfo == null
13465                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
13466            return aInfo;
13467        }
13468
13469        ActivityInfo info = new ActivityInfo(aInfo);
13470        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13471        return info;
13472    }
13473}
13474