ActivityManagerService.java revision 786b44046a79d6c4c9cd07f5989d491c7196ad80
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.wm.WindowManagerService;
31
32import dalvik.system.Zygote;
33
34import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
37import android.app.ActivityOptions;
38import android.app.ActivityThread;
39import android.app.AlertDialog;
40import android.app.AppGlobals;
41import android.app.ApplicationErrorReport;
42import android.app.Dialog;
43import android.app.IActivityController;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
46import android.app.INotificationManager;
47import android.app.IProcessObserver;
48import android.app.IServiceConnection;
49import android.app.IThumbnailReceiver;
50import android.app.Instrumentation;
51import android.app.Notification;
52import android.app.NotificationManager;
53import android.app.PendingIntent;
54import android.app.backup.IBackupManager;
55import android.content.ActivityNotFoundException;
56import android.content.BroadcastReceiver;
57import android.content.ClipData;
58import android.content.ComponentCallbacks2;
59import android.content.ComponentName;
60import android.content.ContentProvider;
61import android.content.ContentResolver;
62import android.content.Context;
63import android.content.DialogInterface;
64import android.content.IContentProvider;
65import android.content.IIntentReceiver;
66import android.content.IIntentSender;
67import android.content.Intent;
68import android.content.IntentFilter;
69import android.content.IntentSender;
70import android.content.pm.ActivityInfo;
71import android.content.pm.ApplicationInfo;
72import android.content.pm.ConfigurationInfo;
73import android.content.pm.IPackageDataObserver;
74import android.content.pm.IPackageManager;
75import android.content.pm.InstrumentationInfo;
76import android.content.pm.PackageInfo;
77import android.content.pm.PackageManager;
78import android.content.pm.UserInfo;
79import android.content.pm.PackageManager.NameNotFoundException;
80import android.content.pm.PathPermission;
81import android.content.pm.ProviderInfo;
82import android.content.pm.ResolveInfo;
83import android.content.pm.ServiceInfo;
84import android.content.res.CompatibilityInfo;
85import android.content.res.Configuration;
86import android.graphics.Bitmap;
87import android.net.Proxy;
88import android.net.ProxyProperties;
89import android.net.Uri;
90import android.os.Binder;
91import android.os.Build;
92import android.os.Bundle;
93import android.os.Debug;
94import android.os.DropBoxManager;
95import android.os.Environment;
96import android.os.FileObserver;
97import android.os.FileUtils;
98import android.os.Handler;
99import android.os.IBinder;
100import android.os.IPermissionController;
101import android.os.Looper;
102import android.os.Message;
103import android.os.Parcel;
104import android.os.ParcelFileDescriptor;
105import android.os.Process;
106import android.os.RemoteCallbackList;
107import android.os.RemoteException;
108import android.os.SELinux;
109import android.os.ServiceManager;
110import android.os.StrictMode;
111import android.os.SystemClock;
112import android.os.SystemProperties;
113import android.os.UserHandle;
114import android.os.UserManager;
115import android.provider.Settings;
116import android.text.format.Time;
117import android.util.EventLog;
118import android.util.Log;
119import android.util.Pair;
120import android.util.PrintWriterPrinter;
121import android.util.Slog;
122import android.util.SparseArray;
123import android.util.SparseIntArray;
124import android.util.TimeUtils;
125import android.view.Gravity;
126import android.view.LayoutInflater;
127import android.view.View;
128import android.view.WindowManager;
129import android.view.WindowManagerPolicy;
130
131import java.io.BufferedInputStream;
132import java.io.BufferedOutputStream;
133import java.io.BufferedReader;
134import java.io.DataInputStream;
135import java.io.DataOutputStream;
136import java.io.File;
137import java.io.FileDescriptor;
138import java.io.FileInputStream;
139import java.io.FileNotFoundException;
140import java.io.FileOutputStream;
141import java.io.IOException;
142import java.io.InputStreamReader;
143import java.io.PrintWriter;
144import java.io.StringWriter;
145import java.lang.ref.WeakReference;
146import java.util.ArrayList;
147import java.util.Collections;
148import java.util.Comparator;
149import java.util.HashMap;
150import java.util.HashSet;
151import java.util.Iterator;
152import java.util.List;
153import java.util.Locale;
154import java.util.Map;
155import java.util.Map.Entry;
156import java.util.Set;
157import java.util.concurrent.atomic.AtomicBoolean;
158import java.util.concurrent.atomic.AtomicLong;
159
160public final class ActivityManagerService extends ActivityManagerNative
161        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
162    private static final String USER_DATA_DIR = "/data/user/";
163    static final String TAG = "ActivityManager";
164    static final String TAG_MU = "ActivityManagerServiceMU";
165    static final boolean DEBUG = false;
166    static final boolean localLOGV = DEBUG;
167    static final boolean DEBUG_SWITCH = localLOGV || false;
168    static final boolean DEBUG_TASKS = localLOGV || false;
169    static final boolean DEBUG_PAUSE = localLOGV || false;
170    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
171    static final boolean DEBUG_TRANSITION = localLOGV || false;
172    static final boolean DEBUG_BROADCAST = localLOGV || false;
173    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_SERVICE = localLOGV || false;
176    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
177    static final boolean DEBUG_VISBILITY = localLOGV || false;
178    static final boolean DEBUG_PROCESSES = localLOGV || false;
179    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
180    static final boolean DEBUG_PROVIDER = localLOGV || false;
181    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
182    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
183    static final boolean DEBUG_RESULTS = localLOGV || false;
184    static final boolean DEBUG_BACKUP = localLOGV || false;
185    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
186    static final boolean DEBUG_POWER = localLOGV || false;
187    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
188    static final boolean DEBUG_MU = localLOGV || false;
189    static final boolean VALIDATE_TOKENS = false;
190    static final boolean SHOW_ACTIVITY_START_TIME = true;
191
192    // Control over CPU and battery monitoring.
193    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
194    static final boolean MONITOR_CPU_USAGE = true;
195    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
196    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
197    static final boolean MONITOR_THREAD_CPU_USAGE = false;
198
199    // The flags that are set for all calls we make to the package manager.
200    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
201
202    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
203
204    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
205
206    // Maximum number of recent tasks that we can remember.
207    static final int MAX_RECENT_TASKS = 20;
208
209    // Amount of time after a call to stopAppSwitches() during which we will
210    // prevent further untrusted switches from happening.
211    static final long APP_SWITCH_DELAY_TIME = 5*1000;
212
213    // How long we wait for a launched process to attach to the activity manager
214    // before we decide it's never going to come up for real.
215    static final int PROC_START_TIMEOUT = 10*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real, when the process was
219    // started with a wrapper for instrumentation (such as Valgrind) because it
220    // could take much longer than usual.
221    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
222
223    // How long to wait after going idle before forcing apps to GC.
224    static final int GC_TIMEOUT = 5*1000;
225
226    // The minimum amount of time between successive GC requests for a process.
227    static final int GC_MIN_INTERVAL = 60*1000;
228
229    // The rate at which we check for apps using excessive power -- 15 mins.
230    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
231
232    // The minimum sample duration we will allow before deciding we have
233    // enough data on wake locks to start killing things.
234    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on CPU usage to start killing things.
238    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // How long we allow a receiver to run before giving up on it.
241    static final int BROADCAST_FG_TIMEOUT = 10*1000;
242    static final int BROADCAST_BG_TIMEOUT = 60*1000;
243
244    // How long we wait until we timeout on key dispatching.
245    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
246
247    // How long we wait until we timeout on key dispatching during instrumentation.
248    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
249
250    static final int MY_PID = Process.myPid();
251
252    static final String[] EMPTY_STRING_ARRAY = new String[0];
253
254    public ActivityStack mMainStack;
255
256    private final boolean mHeadless;
257
258    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
259    // default actuion automatically.  Important for devices without direct input
260    // devices.
261    private boolean mShowDialogs = true;
262
263    /**
264     * Description of a request to start a new activity, which has been held
265     * due to app switches being disabled.
266     */
267    static class PendingActivityLaunch {
268        ActivityRecord r;
269        ActivityRecord sourceRecord;
270        int startFlags;
271    }
272
273    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274            = new ArrayList<PendingActivityLaunch>();
275
276
277    BroadcastQueue mFgBroadcastQueue;
278    BroadcastQueue mBgBroadcastQueue;
279    // Convenient for easy iteration over the queues. Foreground is first
280    // so that dispatch of foreground broadcasts gets precedence.
281    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
282
283    BroadcastQueue broadcastQueueForIntent(Intent intent) {
284        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
285        if (DEBUG_BACKGROUND_BROADCAST) {
286            Slog.i(TAG, "Broadcast intent " + intent + " on "
287                    + (isFg ? "foreground" : "background")
288                    + " queue");
289        }
290        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
291    }
292
293    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
294        for (BroadcastQueue queue : mBroadcastQueues) {
295            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
296            if (r != null) {
297                return r;
298            }
299        }
300        return null;
301    }
302
303    /**
304     * Activity we have told the window manager to have key focus.
305     */
306    ActivityRecord mFocusedActivity = null;
307    /**
308     * List of intents that were used to start the most recent tasks.
309     */
310    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
311
312    /**
313     * Process management.
314     */
315    final ProcessList mProcessList = new ProcessList();
316
317    /**
318     * All of the applications we currently have running organized by name.
319     * The keys are strings of the application package name (as
320     * returned by the package manager), and the keys are ApplicationRecord
321     * objects.
322     */
323    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
324
325    /**
326     * The currently running isolated processes.
327     */
328    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
329
330    /**
331     * Counter for assigning isolated process uids, to avoid frequently reusing the
332     * same ones.
333     */
334    int mNextIsolatedProcessUid = 0;
335
336    /**
337     * The currently running heavy-weight process, if any.
338     */
339    ProcessRecord mHeavyWeightProcess = null;
340
341    /**
342     * The last time that various processes have crashed.
343     */
344    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
345
346    /**
347     * Set of applications that we consider to be bad, and will reject
348     * incoming broadcasts from (which the user has no control over).
349     * Processes are added to this set when they have crashed twice within
350     * a minimum amount of time; they are removed from it when they are
351     * later restarted (hopefully due to some user action).  The value is the
352     * time it was added to the list.
353     */
354    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
355
356    /**
357     * All of the processes we currently have running organized by pid.
358     * The keys are the pid running the application.
359     *
360     * <p>NOTE: This object is protected by its own lock, NOT the global
361     * activity manager lock!
362     */
363    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
364
365    /**
366     * All of the processes that have been forced to be foreground.  The key
367     * is the pid of the caller who requested it (we hold a death
368     * link on it).
369     */
370    abstract class ForegroundToken implements IBinder.DeathRecipient {
371        int pid;
372        IBinder token;
373    }
374    final SparseArray<ForegroundToken> mForegroundProcesses
375            = new SparseArray<ForegroundToken>();
376
377    /**
378     * List of records for processes that someone had tried to start before the
379     * system was ready.  We don't start them at that point, but ensure they
380     * are started by the time booting is complete.
381     */
382    final ArrayList<ProcessRecord> mProcessesOnHold
383            = new ArrayList<ProcessRecord>();
384
385    /**
386     * List of persistent applications that are in the process
387     * of being started.
388     */
389    final ArrayList<ProcessRecord> mPersistentStartingProcesses
390            = new ArrayList<ProcessRecord>();
391
392    /**
393     * Processes that are being forcibly torn down.
394     */
395    final ArrayList<ProcessRecord> mRemovedProcesses
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of running applications, sorted by recent usage.
400     * The first entry in the list is the least recently used.
401     * It contains ApplicationRecord objects.  This list does NOT include
402     * any persistent application records (since we never want to exit them).
403     */
404    final ArrayList<ProcessRecord> mLruProcesses
405            = new ArrayList<ProcessRecord>();
406
407    /**
408     * List of processes that should gc as soon as things are idle.
409     */
410    final ArrayList<ProcessRecord> mProcessesToGc
411            = new ArrayList<ProcessRecord>();
412
413    /**
414     * This is the process holding what we currently consider to be
415     * the "home" activity.
416     */
417    ProcessRecord mHomeProcess;
418
419    /**
420     * This is the process holding the activity the user last visited that
421     * is in a different process from the one they are currently in.
422     */
423    ProcessRecord mPreviousProcess;
424
425    /**
426     * The time at which the previous process was last visible.
427     */
428    long mPreviousProcessVisibleTime;
429
430    /**
431     * Packages that the user has asked to have run in screen size
432     * compatibility mode instead of filling the screen.
433     */
434    final CompatModePackages mCompatModePackages;
435
436    /**
437     * Set of PendingResultRecord objects that are currently active.
438     */
439    final HashSet mPendingResultRecords = new HashSet();
440
441    /**
442     * Set of IntentSenderRecord objects that are currently active.
443     */
444    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
445            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
446
447    /**
448     * Fingerprints (hashCode()) of stack traces that we've
449     * already logged DropBox entries for.  Guarded by itself.  If
450     * something (rogue user app) forces this over
451     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
452     */
453    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
454    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
455
456    /**
457     * Strict Mode background batched logging state.
458     *
459     * The string buffer is guarded by itself, and its lock is also
460     * used to determine if another batched write is already
461     * in-flight.
462     */
463    private final StringBuilder mStrictModeBuffer = new StringBuilder();
464
465    /**
466     * Keeps track of all IIntentReceivers that have been registered for
467     * broadcasts.  Hash keys are the receiver IBinder, hash value is
468     * a ReceiverList.
469     */
470    final HashMap mRegisteredReceivers = new HashMap();
471
472    /**
473     * Resolver for broadcast intents to registered receivers.
474     * Holds BroadcastFilter (subclass of IntentFilter).
475     */
476    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
477            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
478        @Override
479        protected boolean allowFilterResult(
480                BroadcastFilter filter, List<BroadcastFilter> dest) {
481            IBinder target = filter.receiverList.receiver.asBinder();
482            for (int i=dest.size()-1; i>=0; i--) {
483                if (dest.get(i).receiverList.receiver.asBinder() == target) {
484                    return false;
485                }
486            }
487            return true;
488        }
489
490        @Override
491        protected BroadcastFilter[] newArray(int size) {
492            return new BroadcastFilter[size];
493        }
494
495        @Override
496        protected String packageForFilter(BroadcastFilter filter) {
497            return filter.packageName;
498        }
499    };
500
501    /**
502     * State of all active sticky broadcasts.  Keys are the action of the
503     * sticky Intent, values are an ArrayList of all broadcasted intents with
504     * that action (which should usually be one).
505     */
506    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
507            new HashMap<String, ArrayList<Intent>>();
508
509    final ActiveServices mServices;
510
511    /**
512     * Backup/restore process management
513     */
514    String mBackupAppName = null;
515    BackupRecord mBackupTarget = null;
516
517    /**
518     * List of PendingThumbnailsRecord objects of clients who are still
519     * waiting to receive all of the thumbnails for a task.
520     */
521    final ArrayList mPendingThumbnails = new ArrayList();
522
523    /**
524     * List of HistoryRecord objects that have been finished and must
525     * still report back to a pending thumbnail receiver.
526     */
527    final ArrayList mCancelledThumbnails = new ArrayList();
528
529    final ProviderMap mProviderMap = new ProviderMap();
530
531    /**
532     * List of content providers who have clients waiting for them.  The
533     * application is currently being launched and the provider will be
534     * removed from this list once it is published.
535     */
536    final ArrayList<ContentProviderRecord> mLaunchingProviders
537            = new ArrayList<ContentProviderRecord>();
538
539    /**
540     * Global set of specific Uri permissions that have been granted.
541     */
542    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
543            = new SparseArray<HashMap<Uri, UriPermission>>();
544
545    CoreSettingsObserver mCoreSettingsObserver;
546
547    /**
548     * Thread-local storage used to carry caller permissions over through
549     * indirect content-provider access.
550     * @see #ActivityManagerService.openContentUri()
551     */
552    private class Identity {
553        public int pid;
554        public int uid;
555
556        Identity(int _pid, int _uid) {
557            pid = _pid;
558            uid = _uid;
559        }
560    }
561
562    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
563
564    /**
565     * All information we have collected about the runtime performance of
566     * any user id that can impact battery performance.
567     */
568    final BatteryStatsService mBatteryStatsService;
569
570    /**
571     * information about component usage
572     */
573    final UsageStatsService mUsageStatsService;
574
575    /**
576     * Current configuration information.  HistoryRecord objects are given
577     * a reference to this object to indicate which configuration they are
578     * currently running in, so this object must be kept immutable.
579     */
580    Configuration mConfiguration = new Configuration();
581
582    /**
583     * Current sequencing integer of the configuration, for skipping old
584     * configurations.
585     */
586    int mConfigurationSeq = 0;
587
588    /**
589     * Hardware-reported OpenGLES version.
590     */
591    final int GL_ES_VERSION;
592
593    /**
594     * List of initialization arguments to pass to all processes when binding applications to them.
595     * For example, references to the commonly used services.
596     */
597    HashMap<String, IBinder> mAppBindArgs;
598
599    /**
600     * Temporary to avoid allocations.  Protected by main lock.
601     */
602    final StringBuilder mStringBuilder = new StringBuilder(256);
603
604    /**
605     * Used to control how we initialize the service.
606     */
607    boolean mStartRunning = false;
608    ComponentName mTopComponent;
609    String mTopAction;
610    String mTopData;
611    boolean mProcessesReady = false;
612    boolean mSystemReady = false;
613    boolean mBooting = false;
614    boolean mWaitingUpdate = false;
615    boolean mDidUpdate = false;
616    boolean mOnBattery = false;
617    boolean mLaunchWarningShown = false;
618
619    Context mContext;
620
621    int mFactoryTest;
622
623    boolean mCheckedForSetup;
624
625    /**
626     * The time at which we will allow normal application switches again,
627     * after a call to {@link #stopAppSwitches()}.
628     */
629    long mAppSwitchesAllowedTime;
630
631    /**
632     * This is set to true after the first switch after mAppSwitchesAllowedTime
633     * is set; any switches after that will clear the time.
634     */
635    boolean mDidAppSwitch;
636
637    /**
638     * Last time (in realtime) at which we checked for power usage.
639     */
640    long mLastPowerCheckRealtime;
641
642    /**
643     * Last time (in uptime) at which we checked for power usage.
644     */
645    long mLastPowerCheckUptime;
646
647    /**
648     * Set while we are wanting to sleep, to prevent any
649     * activities from being started/resumed.
650     */
651    boolean mSleeping = false;
652
653    /**
654     * State of external calls telling us if the device is asleep.
655     */
656    boolean mWentToSleep = false;
657
658    /**
659     * State of external call telling us if the lock screen is shown.
660     */
661    boolean mLockScreenShown = false;
662
663    /**
664     * Set if we are shutting down the system, similar to sleeping.
665     */
666    boolean mShuttingDown = false;
667
668    /**
669     * Task identifier that activities are currently being started
670     * in.  Incremented each time a new task is created.
671     * todo: Replace this with a TokenSpace class that generates non-repeating
672     * integers that won't wrap.
673     */
674    int mCurTask = 1;
675
676    /**
677     * Current sequence id for oom_adj computation traversal.
678     */
679    int mAdjSeq = 0;
680
681    /**
682     * Current sequence id for process LRU updating.
683     */
684    int mLruSeq = 0;
685
686    /**
687     * Keep track of the non-hidden/empty process we last found, to help
688     * determine how to distribute hidden/empty processes next time.
689     */
690    int mNumNonHiddenProcs = 0;
691
692    /**
693     * Keep track of the number of hidden procs, to balance oom adj
694     * distribution between those and empty procs.
695     */
696    int mNumHiddenProcs = 0;
697
698    /**
699     * Keep track of the number of service processes we last found, to
700     * determine on the next iteration which should be B services.
701     */
702    int mNumServiceProcs = 0;
703    int mNewNumServiceProcs = 0;
704
705    /**
706     * System monitoring: number of processes that died since the last
707     * N procs were started.
708     */
709    int[] mProcDeaths = new int[20];
710
711    /**
712     * This is set if we had to do a delayed dexopt of an app before launching
713     * it, to increasing the ANR timeouts in that case.
714     */
715    boolean mDidDexOpt;
716
717    String mDebugApp = null;
718    boolean mWaitForDebugger = false;
719    boolean mDebugTransient = false;
720    String mOrigDebugApp = null;
721    boolean mOrigWaitForDebugger = false;
722    boolean mAlwaysFinishActivities = false;
723    IActivityController mController = null;
724    String mProfileApp = null;
725    ProcessRecord mProfileProc = null;
726    String mProfileFile;
727    ParcelFileDescriptor mProfileFd;
728    int mProfileType = 0;
729    boolean mAutoStopProfiler = false;
730    String mOpenGlTraceApp = null;
731
732    static class ProcessChangeItem {
733        static final int CHANGE_ACTIVITIES = 1<<0;
734        static final int CHANGE_IMPORTANCE= 1<<1;
735        int changes;
736        int uid;
737        int pid;
738        int importance;
739        boolean foregroundActivities;
740    }
741
742    final RemoteCallbackList<IProcessObserver> mProcessObservers
743            = new RemoteCallbackList<IProcessObserver>();
744    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
745
746    final ArrayList<ProcessChangeItem> mPendingProcessChanges
747            = new ArrayList<ProcessChangeItem>();
748    final ArrayList<ProcessChangeItem> mAvailProcessChanges
749            = new ArrayList<ProcessChangeItem>();
750
751    /**
752     * Callback of last caller to {@link #requestPss}.
753     */
754    Runnable mRequestPssCallback;
755
756    /**
757     * Remaining processes for which we are waiting results from the last
758     * call to {@link #requestPss}.
759     */
760    final ArrayList<ProcessRecord> mRequestPssList
761            = new ArrayList<ProcessRecord>();
762
763    /**
764     * Runtime statistics collection thread.  This object's lock is used to
765     * protect all related state.
766     */
767    final Thread mProcessStatsThread;
768
769    /**
770     * Used to collect process stats when showing not responding dialog.
771     * Protected by mProcessStatsThread.
772     */
773    final ProcessStats mProcessStats = new ProcessStats(
774            MONITOR_THREAD_CPU_USAGE);
775    final AtomicLong mLastCpuTime = new AtomicLong(0);
776    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
777
778    long mLastWriteTime = 0;
779
780    /**
781     * Set to true after the system has finished booting.
782     */
783    boolean mBooted = false;
784
785    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
786    int mProcessLimitOverride = -1;
787
788    WindowManagerService mWindowManager;
789
790    static ActivityManagerService mSelf;
791    static ActivityThread mSystemThread;
792
793    private int mCurrentUserId;
794    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
795    private UserManager mUserManager;
796
797    private final class AppDeathRecipient implements IBinder.DeathRecipient {
798        final ProcessRecord mApp;
799        final int mPid;
800        final IApplicationThread mAppThread;
801
802        AppDeathRecipient(ProcessRecord app, int pid,
803                IApplicationThread thread) {
804            if (localLOGV) Slog.v(
805                TAG, "New death recipient " + this
806                + " for thread " + thread.asBinder());
807            mApp = app;
808            mPid = pid;
809            mAppThread = thread;
810        }
811
812        public void binderDied() {
813            if (localLOGV) Slog.v(
814                TAG, "Death received in " + this
815                + " for thread " + mAppThread.asBinder());
816            synchronized(ActivityManagerService.this) {
817                appDiedLocked(mApp, mPid, mAppThread);
818            }
819        }
820    }
821
822    static final int SHOW_ERROR_MSG = 1;
823    static final int SHOW_NOT_RESPONDING_MSG = 2;
824    static final int SHOW_FACTORY_ERROR_MSG = 3;
825    static final int UPDATE_CONFIGURATION_MSG = 4;
826    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
827    static final int WAIT_FOR_DEBUGGER_MSG = 6;
828    static final int SERVICE_TIMEOUT_MSG = 12;
829    static final int UPDATE_TIME_ZONE = 13;
830    static final int SHOW_UID_ERROR_MSG = 14;
831    static final int IM_FEELING_LUCKY_MSG = 15;
832    static final int PROC_START_TIMEOUT_MSG = 20;
833    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
834    static final int KILL_APPLICATION_MSG = 22;
835    static final int FINALIZE_PENDING_INTENT_MSG = 23;
836    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
837    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
838    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
839    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
840    static final int CLEAR_DNS_CACHE = 28;
841    static final int UPDATE_HTTP_PROXY = 29;
842    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
843    static final int DISPATCH_PROCESSES_CHANGED = 31;
844    static final int DISPATCH_PROCESS_DIED = 32;
845    static final int REPORT_MEM_USAGE = 33;
846
847    static final int FIRST_ACTIVITY_STACK_MSG = 100;
848    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
849    static final int FIRST_COMPAT_MODE_MSG = 300;
850
851    AlertDialog mUidAlert;
852    CompatModeDialog mCompatModeDialog;
853    long mLastMemUsageReportTime = 0;
854
855    final Handler mHandler = new Handler() {
856        //public Handler() {
857        //    if (localLOGV) Slog.v(TAG, "Handler started!");
858        //}
859
860        public void handleMessage(Message msg) {
861            switch (msg.what) {
862            case SHOW_ERROR_MSG: {
863                HashMap data = (HashMap) msg.obj;
864                synchronized (ActivityManagerService.this) {
865                    ProcessRecord proc = (ProcessRecord)data.get("app");
866                    if (proc != null && proc.crashDialog != null) {
867                        Slog.e(TAG, "App already has crash dialog: " + proc);
868                        return;
869                    }
870                    AppErrorResult res = (AppErrorResult) data.get("result");
871                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
872                        Dialog d = new AppErrorDialog(mContext, res, proc);
873                        d.show();
874                        proc.crashDialog = d;
875                    } else {
876                        // The device is asleep, so just pretend that the user
877                        // saw a crash dialog and hit "force quit".
878                        res.set(0);
879                    }
880                }
881
882                ensureBootCompleted();
883            } break;
884            case SHOW_NOT_RESPONDING_MSG: {
885                synchronized (ActivityManagerService.this) {
886                    HashMap data = (HashMap) msg.obj;
887                    ProcessRecord proc = (ProcessRecord)data.get("app");
888                    if (proc != null && proc.anrDialog != null) {
889                        Slog.e(TAG, "App already has anr dialog: " + proc);
890                        return;
891                    }
892
893                    Intent intent = new Intent("android.intent.action.ANR");
894                    if (!mProcessesReady) {
895                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
896                                | Intent.FLAG_RECEIVER_FOREGROUND);
897                    }
898                    broadcastIntentLocked(null, null, intent,
899                            null, null, 0, null, null, null,
900                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
901
902                    if (mShowDialogs) {
903                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
904                                mContext, proc, (ActivityRecord)data.get("activity"));
905                        d.show();
906                        proc.anrDialog = d;
907                    } else {
908                        // Just kill the app if there is no dialog to be shown.
909                        killAppAtUsersRequest(proc, null);
910                    }
911                }
912
913                ensureBootCompleted();
914            } break;
915            case SHOW_STRICT_MODE_VIOLATION_MSG: {
916                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
917                synchronized (ActivityManagerService.this) {
918                    ProcessRecord proc = (ProcessRecord) data.get("app");
919                    if (proc == null) {
920                        Slog.e(TAG, "App not found when showing strict mode dialog.");
921                        break;
922                    }
923                    if (proc.crashDialog != null) {
924                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
925                        return;
926                    }
927                    AppErrorResult res = (AppErrorResult) data.get("result");
928                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
929                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
930                        d.show();
931                        proc.crashDialog = d;
932                    } else {
933                        // The device is asleep, so just pretend that the user
934                        // saw a crash dialog and hit "force quit".
935                        res.set(0);
936                    }
937                }
938                ensureBootCompleted();
939            } break;
940            case SHOW_FACTORY_ERROR_MSG: {
941                Dialog d = new FactoryErrorDialog(
942                    mContext, msg.getData().getCharSequence("msg"));
943                d.show();
944                ensureBootCompleted();
945            } break;
946            case UPDATE_CONFIGURATION_MSG: {
947                final ContentResolver resolver = mContext.getContentResolver();
948                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
949            } break;
950            case GC_BACKGROUND_PROCESSES_MSG: {
951                synchronized (ActivityManagerService.this) {
952                    performAppGcsIfAppropriateLocked();
953                }
954            } break;
955            case WAIT_FOR_DEBUGGER_MSG: {
956                synchronized (ActivityManagerService.this) {
957                    ProcessRecord app = (ProcessRecord)msg.obj;
958                    if (msg.arg1 != 0) {
959                        if (!app.waitedForDebugger) {
960                            Dialog d = new AppWaitingForDebuggerDialog(
961                                    ActivityManagerService.this,
962                                    mContext, app);
963                            app.waitDialog = d;
964                            app.waitedForDebugger = true;
965                            d.show();
966                        }
967                    } else {
968                        if (app.waitDialog != null) {
969                            app.waitDialog.dismiss();
970                            app.waitDialog = null;
971                        }
972                    }
973                }
974            } break;
975            case SERVICE_TIMEOUT_MSG: {
976                if (mDidDexOpt) {
977                    mDidDexOpt = false;
978                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
979                    nmsg.obj = msg.obj;
980                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
981                    return;
982                }
983                mServices.serviceTimeout((ProcessRecord)msg.obj);
984            } break;
985            case UPDATE_TIME_ZONE: {
986                synchronized (ActivityManagerService.this) {
987                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
988                        ProcessRecord r = mLruProcesses.get(i);
989                        if (r.thread != null) {
990                            try {
991                                r.thread.updateTimeZone();
992                            } catch (RemoteException ex) {
993                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
994                            }
995                        }
996                    }
997                }
998            } break;
999            case CLEAR_DNS_CACHE: {
1000                synchronized (ActivityManagerService.this) {
1001                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002                        ProcessRecord r = mLruProcesses.get(i);
1003                        if (r.thread != null) {
1004                            try {
1005                                r.thread.clearDnsCache();
1006                            } catch (RemoteException ex) {
1007                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1008                            }
1009                        }
1010                    }
1011                }
1012            } break;
1013            case UPDATE_HTTP_PROXY: {
1014                ProxyProperties proxy = (ProxyProperties)msg.obj;
1015                String host = "";
1016                String port = "";
1017                String exclList = "";
1018                if (proxy != null) {
1019                    host = proxy.getHost();
1020                    port = Integer.toString(proxy.getPort());
1021                    exclList = proxy.getExclusionList();
1022                }
1023                synchronized (ActivityManagerService.this) {
1024                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1025                        ProcessRecord r = mLruProcesses.get(i);
1026                        if (r.thread != null) {
1027                            try {
1028                                r.thread.setHttpProxy(host, port, exclList);
1029                            } catch (RemoteException ex) {
1030                                Slog.w(TAG, "Failed to update http proxy for: " +
1031                                        r.info.processName);
1032                            }
1033                        }
1034                    }
1035                }
1036            } break;
1037            case SHOW_UID_ERROR_MSG: {
1038                String title = "System UIDs Inconsistent";
1039                String text = "UIDs on the system are inconsistent, you need to wipe your"
1040                        + " data partition or your device will be unstable.";
1041                Log.e(TAG, title + ": " + text);
1042                if (mShowDialogs) {
1043                    // XXX This is a temporary dialog, no need to localize.
1044                    AlertDialog d = new BaseErrorDialog(mContext);
1045                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1046                    d.setCancelable(false);
1047                    d.setTitle(title);
1048                    d.setMessage(text);
1049                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1050                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1051                    mUidAlert = d;
1052                    d.show();
1053                }
1054            } break;
1055            case IM_FEELING_LUCKY_MSG: {
1056                if (mUidAlert != null) {
1057                    mUidAlert.dismiss();
1058                    mUidAlert = null;
1059                }
1060            } break;
1061            case PROC_START_TIMEOUT_MSG: {
1062                if (mDidDexOpt) {
1063                    mDidDexOpt = false;
1064                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1065                    nmsg.obj = msg.obj;
1066                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1067                    return;
1068                }
1069                ProcessRecord app = (ProcessRecord)msg.obj;
1070                synchronized (ActivityManagerService.this) {
1071                    processStartTimedOutLocked(app);
1072                }
1073            } break;
1074            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1075                synchronized (ActivityManagerService.this) {
1076                    doPendingActivityLaunchesLocked(true);
1077                }
1078            } break;
1079            case KILL_APPLICATION_MSG: {
1080                synchronized (ActivityManagerService.this) {
1081                    int uid = msg.arg1;
1082                    boolean restart = (msg.arg2 == 1);
1083                    String pkg = (String) msg.obj;
1084                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1085                            UserHandle.getUserId(uid));
1086                }
1087            } break;
1088            case FINALIZE_PENDING_INTENT_MSG: {
1089                ((PendingIntentRecord)msg.obj).completeFinalize();
1090            } break;
1091            case POST_HEAVY_NOTIFICATION_MSG: {
1092                INotificationManager inm = NotificationManager.getService();
1093                if (inm == null) {
1094                    return;
1095                }
1096
1097                ActivityRecord root = (ActivityRecord)msg.obj;
1098                ProcessRecord process = root.app;
1099                if (process == null) {
1100                    return;
1101                }
1102
1103                try {
1104                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1105                    String text = mContext.getString(R.string.heavy_weight_notification,
1106                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1107                    Notification notification = new Notification();
1108                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1109                    notification.when = 0;
1110                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1111                    notification.tickerText = text;
1112                    notification.defaults = 0; // please be quiet
1113                    notification.sound = null;
1114                    notification.vibrate = null;
1115                    notification.setLatestEventInfo(context, text,
1116                            mContext.getText(R.string.heavy_weight_notification_detail),
1117                            PendingIntent.getActivity(mContext, 0, root.intent,
1118                                    PendingIntent.FLAG_CANCEL_CURRENT));
1119
1120                    try {
1121                        int[] outId = new int[1];
1122                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1123                                notification, outId);
1124                    } catch (RuntimeException e) {
1125                        Slog.w(ActivityManagerService.TAG,
1126                                "Error showing notification for heavy-weight app", e);
1127                    } catch (RemoteException e) {
1128                    }
1129                } catch (NameNotFoundException e) {
1130                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1131                }
1132            } break;
1133            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1134                INotificationManager inm = NotificationManager.getService();
1135                if (inm == null) {
1136                    return;
1137                }
1138                try {
1139                    inm.cancelNotification("android",
1140                            R.string.heavy_weight_notification);
1141                } catch (RuntimeException e) {
1142                    Slog.w(ActivityManagerService.TAG,
1143                            "Error canceling notification for service", e);
1144                } catch (RemoteException e) {
1145                }
1146            } break;
1147            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1148                synchronized (ActivityManagerService.this) {
1149                    checkExcessivePowerUsageLocked(true);
1150                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1151                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1152                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1153                }
1154            } break;
1155            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1156                synchronized (ActivityManagerService.this) {
1157                    ActivityRecord ar = (ActivityRecord)msg.obj;
1158                    if (mCompatModeDialog != null) {
1159                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1160                                ar.info.applicationInfo.packageName)) {
1161                            return;
1162                        }
1163                        mCompatModeDialog.dismiss();
1164                        mCompatModeDialog = null;
1165                    }
1166                    if (ar != null && false) {
1167                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1168                                ar.packageName)) {
1169                            int mode = mCompatModePackages.computeCompatModeLocked(
1170                                    ar.info.applicationInfo);
1171                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1172                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1173                                mCompatModeDialog = new CompatModeDialog(
1174                                        ActivityManagerService.this, mContext,
1175                                        ar.info.applicationInfo);
1176                                mCompatModeDialog.show();
1177                            }
1178                        }
1179                    }
1180                }
1181                break;
1182            }
1183            case DISPATCH_PROCESSES_CHANGED: {
1184                dispatchProcessesChanged();
1185                break;
1186            }
1187            case DISPATCH_PROCESS_DIED: {
1188                final int pid = msg.arg1;
1189                final int uid = msg.arg2;
1190                dispatchProcessDied(pid, uid);
1191                break;
1192            }
1193            case REPORT_MEM_USAGE: {
1194                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1195                if (!isDebuggable) {
1196                    return;
1197                }
1198                synchronized (ActivityManagerService.this) {
1199                    long now = SystemClock.uptimeMillis();
1200                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1201                        // Don't report more than every 5 minutes to somewhat
1202                        // avoid spamming.
1203                        return;
1204                    }
1205                    mLastMemUsageReportTime = now;
1206                }
1207                Thread thread = new Thread() {
1208                    @Override public void run() {
1209                        StringBuilder dropBuilder = new StringBuilder(1024);
1210                        StringBuilder logBuilder = new StringBuilder(1024);
1211                        StringWriter oomSw = new StringWriter();
1212                        PrintWriter oomPw = new PrintWriter(oomSw);
1213                        StringWriter catSw = new StringWriter();
1214                        PrintWriter catPw = new PrintWriter(catSw);
1215                        String[] emptyArgs = new String[] { };
1216                        StringBuilder tag = new StringBuilder(128);
1217                        StringBuilder stack = new StringBuilder(128);
1218                        tag.append("Low on memory -- ");
1219                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1220                                tag, stack);
1221                        dropBuilder.append(stack);
1222                        dropBuilder.append('\n');
1223                        dropBuilder.append('\n');
1224                        String oomString = oomSw.toString();
1225                        dropBuilder.append(oomString);
1226                        dropBuilder.append('\n');
1227                        logBuilder.append(oomString);
1228                        try {
1229                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1230                                    "procrank", });
1231                            final InputStreamReader converter = new InputStreamReader(
1232                                    proc.getInputStream());
1233                            BufferedReader in = new BufferedReader(converter);
1234                            String line;
1235                            while (true) {
1236                                line = in.readLine();
1237                                if (line == null) {
1238                                    break;
1239                                }
1240                                if (line.length() > 0) {
1241                                    logBuilder.append(line);
1242                                    logBuilder.append('\n');
1243                                }
1244                                dropBuilder.append(line);
1245                                dropBuilder.append('\n');
1246                            }
1247                            converter.close();
1248                        } catch (IOException e) {
1249                        }
1250                        synchronized (ActivityManagerService.this) {
1251                            catPw.println();
1252                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1253                            catPw.println();
1254                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1255                                    false, false, null);
1256                            catPw.println();
1257                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1258                        }
1259                        dropBuilder.append(catSw.toString());
1260                        addErrorToDropBox("lowmem", null, "system_server", null,
1261                                null, tag.toString(), dropBuilder.toString(), null, null);
1262                        Slog.i(TAG, logBuilder.toString());
1263                        synchronized (ActivityManagerService.this) {
1264                            long now = SystemClock.uptimeMillis();
1265                            if (mLastMemUsageReportTime < now) {
1266                                mLastMemUsageReportTime = now;
1267                            }
1268                        }
1269                    }
1270                };
1271                thread.start();
1272                break;
1273            }
1274            }
1275        }
1276    };
1277
1278    public static void setSystemProcess() {
1279        try {
1280            ActivityManagerService m = mSelf;
1281
1282            ServiceManager.addService("activity", m, true);
1283            ServiceManager.addService("meminfo", new MemBinder(m));
1284            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1285            ServiceManager.addService("dbinfo", new DbBinder(m));
1286            if (MONITOR_CPU_USAGE) {
1287                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1288            }
1289            ServiceManager.addService("permission", new PermissionController(m));
1290
1291            ApplicationInfo info =
1292                mSelf.mContext.getPackageManager().getApplicationInfo(
1293                            "android", STOCK_PM_FLAGS);
1294            mSystemThread.installSystemApplicationInfo(info);
1295
1296            synchronized (mSelf) {
1297                ProcessRecord app = mSelf.newProcessRecordLocked(
1298                        mSystemThread.getApplicationThread(), info,
1299                        info.processName, false);
1300                app.persistent = true;
1301                app.pid = MY_PID;
1302                app.maxAdj = ProcessList.SYSTEM_ADJ;
1303                mSelf.mProcessNames.put(app.processName, app.uid, app);
1304                synchronized (mSelf.mPidsSelfLocked) {
1305                    mSelf.mPidsSelfLocked.put(app.pid, app);
1306                }
1307                mSelf.updateLruProcessLocked(app, true, true);
1308            }
1309        } catch (PackageManager.NameNotFoundException e) {
1310            throw new RuntimeException(
1311                    "Unable to find android system package", e);
1312        }
1313    }
1314
1315    public void setWindowManager(WindowManagerService wm) {
1316        mWindowManager = wm;
1317    }
1318
1319    public static final Context main(int factoryTest) {
1320        AThread thr = new AThread();
1321        thr.start();
1322
1323        synchronized (thr) {
1324            while (thr.mService == null) {
1325                try {
1326                    thr.wait();
1327                } catch (InterruptedException e) {
1328                }
1329            }
1330        }
1331
1332        ActivityManagerService m = thr.mService;
1333        mSelf = m;
1334        ActivityThread at = ActivityThread.systemMain();
1335        mSystemThread = at;
1336        Context context = at.getSystemContext();
1337        context.setTheme(android.R.style.Theme_Holo);
1338        m.mContext = context;
1339        m.mFactoryTest = factoryTest;
1340        m.mMainStack = new ActivityStack(m, context, true);
1341
1342        m.mBatteryStatsService.publish(context);
1343        m.mUsageStatsService.publish(context);
1344
1345        synchronized (thr) {
1346            thr.mReady = true;
1347            thr.notifyAll();
1348        }
1349
1350        m.startRunning(null, null, null, null);
1351
1352        return context;
1353    }
1354
1355    public static ActivityManagerService self() {
1356        return mSelf;
1357    }
1358
1359    static class AThread extends Thread {
1360        ActivityManagerService mService;
1361        boolean mReady = false;
1362
1363        public AThread() {
1364            super("ActivityManager");
1365        }
1366
1367        public void run() {
1368            Looper.prepare();
1369
1370            android.os.Process.setThreadPriority(
1371                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1372            android.os.Process.setCanSelfBackground(false);
1373
1374            ActivityManagerService m = new ActivityManagerService();
1375
1376            synchronized (this) {
1377                mService = m;
1378                notifyAll();
1379            }
1380
1381            synchronized (this) {
1382                while (!mReady) {
1383                    try {
1384                        wait();
1385                    } catch (InterruptedException e) {
1386                    }
1387                }
1388            }
1389
1390            // For debug builds, log event loop stalls to dropbox for analysis.
1391            if (StrictMode.conditionallyEnableDebugLogging()) {
1392                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1393            }
1394
1395            Looper.loop();
1396        }
1397    }
1398
1399    static class MemBinder extends Binder {
1400        ActivityManagerService mActivityManagerService;
1401        MemBinder(ActivityManagerService activityManagerService) {
1402            mActivityManagerService = activityManagerService;
1403        }
1404
1405        @Override
1406        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1407            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1408                    != PackageManager.PERMISSION_GRANTED) {
1409                pw.println("Permission Denial: can't dump meminfo from from pid="
1410                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1411                        + " without permission " + android.Manifest.permission.DUMP);
1412                return;
1413            }
1414
1415            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1416                    false, null, null, null);
1417        }
1418    }
1419
1420    static class GraphicsBinder extends Binder {
1421        ActivityManagerService mActivityManagerService;
1422        GraphicsBinder(ActivityManagerService activityManagerService) {
1423            mActivityManagerService = activityManagerService;
1424        }
1425
1426        @Override
1427        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1428            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1429                    != PackageManager.PERMISSION_GRANTED) {
1430                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1431                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1432                        + " without permission " + android.Manifest.permission.DUMP);
1433                return;
1434            }
1435
1436            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1437        }
1438    }
1439
1440    static class DbBinder extends Binder {
1441        ActivityManagerService mActivityManagerService;
1442        DbBinder(ActivityManagerService activityManagerService) {
1443            mActivityManagerService = activityManagerService;
1444        }
1445
1446        @Override
1447        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1448            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1449                    != PackageManager.PERMISSION_GRANTED) {
1450                pw.println("Permission Denial: can't dump dbinfo from from pid="
1451                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1452                        + " without permission " + android.Manifest.permission.DUMP);
1453                return;
1454            }
1455
1456            mActivityManagerService.dumpDbInfo(fd, pw, args);
1457        }
1458    }
1459
1460    static class CpuBinder extends Binder {
1461        ActivityManagerService mActivityManagerService;
1462        CpuBinder(ActivityManagerService activityManagerService) {
1463            mActivityManagerService = activityManagerService;
1464        }
1465
1466        @Override
1467        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1468            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1469                    != PackageManager.PERMISSION_GRANTED) {
1470                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1471                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1472                        + " without permission " + android.Manifest.permission.DUMP);
1473                return;
1474            }
1475
1476            synchronized (mActivityManagerService.mProcessStatsThread) {
1477                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1478                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1479                        SystemClock.uptimeMillis()));
1480            }
1481        }
1482    }
1483
1484    private ActivityManagerService() {
1485        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1486
1487        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1488        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1489        mBroadcastQueues[0] = mFgBroadcastQueue;
1490        mBroadcastQueues[1] = mBgBroadcastQueue;
1491
1492        mServices = new ActiveServices(this);
1493
1494        File dataDir = Environment.getDataDirectory();
1495        File systemDir = new File(dataDir, "system");
1496        systemDir.mkdirs();
1497        mBatteryStatsService = new BatteryStatsService(new File(
1498                systemDir, "batterystats.bin").toString());
1499        mBatteryStatsService.getActiveStatistics().readLocked();
1500        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1501        mOnBattery = DEBUG_POWER ? true
1502                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1503        mBatteryStatsService.getActiveStatistics().setCallback(this);
1504
1505        mUsageStatsService = new UsageStatsService(new File(
1506                systemDir, "usagestats").toString());
1507        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1508
1509        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1510            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1511
1512        mConfiguration.setToDefaults();
1513        mConfiguration.locale = Locale.getDefault();
1514        mConfigurationSeq = mConfiguration.seq = 1;
1515        mProcessStats.init();
1516
1517        mCompatModePackages = new CompatModePackages(this, systemDir);
1518
1519        // Add ourself to the Watchdog monitors.
1520        Watchdog.getInstance().addMonitor(this);
1521
1522        mProcessStatsThread = new Thread("ProcessStats") {
1523            public void run() {
1524                while (true) {
1525                    try {
1526                        try {
1527                            synchronized(this) {
1528                                final long now = SystemClock.uptimeMillis();
1529                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1530                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1531                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1532                                //        + ", write delay=" + nextWriteDelay);
1533                                if (nextWriteDelay < nextCpuDelay) {
1534                                    nextCpuDelay = nextWriteDelay;
1535                                }
1536                                if (nextCpuDelay > 0) {
1537                                    mProcessStatsMutexFree.set(true);
1538                                    this.wait(nextCpuDelay);
1539                                }
1540                            }
1541                        } catch (InterruptedException e) {
1542                        }
1543                        updateCpuStatsNow();
1544                    } catch (Exception e) {
1545                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1546                    }
1547                }
1548            }
1549        };
1550        mProcessStatsThread.start();
1551    }
1552
1553    @Override
1554    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1555            throws RemoteException {
1556        if (code == SYSPROPS_TRANSACTION) {
1557            // We need to tell all apps about the system property change.
1558            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1559            synchronized(this) {
1560                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1561                    final int NA = apps.size();
1562                    for (int ia=0; ia<NA; ia++) {
1563                        ProcessRecord app = apps.valueAt(ia);
1564                        if (app.thread != null) {
1565                            procs.add(app.thread.asBinder());
1566                        }
1567                    }
1568                }
1569            }
1570
1571            int N = procs.size();
1572            for (int i=0; i<N; i++) {
1573                Parcel data2 = Parcel.obtain();
1574                try {
1575                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1576                } catch (RemoteException e) {
1577                }
1578                data2.recycle();
1579            }
1580        }
1581        try {
1582            return super.onTransact(code, data, reply, flags);
1583        } catch (RuntimeException e) {
1584            // The activity manager only throws security exceptions, so let's
1585            // log all others.
1586            if (!(e instanceof SecurityException)) {
1587                Slog.e(TAG, "Activity Manager Crash", e);
1588            }
1589            throw e;
1590        }
1591    }
1592
1593    void updateCpuStats() {
1594        final long now = SystemClock.uptimeMillis();
1595        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1596            return;
1597        }
1598        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1599            synchronized (mProcessStatsThread) {
1600                mProcessStatsThread.notify();
1601            }
1602        }
1603    }
1604
1605    void updateCpuStatsNow() {
1606        synchronized (mProcessStatsThread) {
1607            mProcessStatsMutexFree.set(false);
1608            final long now = SystemClock.uptimeMillis();
1609            boolean haveNewCpuStats = false;
1610
1611            if (MONITOR_CPU_USAGE &&
1612                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1613                mLastCpuTime.set(now);
1614                haveNewCpuStats = true;
1615                mProcessStats.update();
1616                //Slog.i(TAG, mProcessStats.printCurrentState());
1617                //Slog.i(TAG, "Total CPU usage: "
1618                //        + mProcessStats.getTotalCpuPercent() + "%");
1619
1620                // Slog the cpu usage if the property is set.
1621                if ("true".equals(SystemProperties.get("events.cpu"))) {
1622                    int user = mProcessStats.getLastUserTime();
1623                    int system = mProcessStats.getLastSystemTime();
1624                    int iowait = mProcessStats.getLastIoWaitTime();
1625                    int irq = mProcessStats.getLastIrqTime();
1626                    int softIrq = mProcessStats.getLastSoftIrqTime();
1627                    int idle = mProcessStats.getLastIdleTime();
1628
1629                    int total = user + system + iowait + irq + softIrq + idle;
1630                    if (total == 0) total = 1;
1631
1632                    EventLog.writeEvent(EventLogTags.CPU,
1633                            ((user+system+iowait+irq+softIrq) * 100) / total,
1634                            (user * 100) / total,
1635                            (system * 100) / total,
1636                            (iowait * 100) / total,
1637                            (irq * 100) / total,
1638                            (softIrq * 100) / total);
1639                }
1640            }
1641
1642            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1643            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1644            synchronized(bstats) {
1645                synchronized(mPidsSelfLocked) {
1646                    if (haveNewCpuStats) {
1647                        if (mOnBattery) {
1648                            int perc = bstats.startAddingCpuLocked();
1649                            int totalUTime = 0;
1650                            int totalSTime = 0;
1651                            final int N = mProcessStats.countStats();
1652                            for (int i=0; i<N; i++) {
1653                                ProcessStats.Stats st = mProcessStats.getStats(i);
1654                                if (!st.working) {
1655                                    continue;
1656                                }
1657                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1658                                int otherUTime = (st.rel_utime*perc)/100;
1659                                int otherSTime = (st.rel_stime*perc)/100;
1660                                totalUTime += otherUTime;
1661                                totalSTime += otherSTime;
1662                                if (pr != null) {
1663                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1664                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1665                                            st.rel_stime-otherSTime);
1666                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1667                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1668                                } else {
1669                                    BatteryStatsImpl.Uid.Proc ps =
1670                                            bstats.getProcessStatsLocked(st.name, st.pid);
1671                                    if (ps != null) {
1672                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1673                                                st.rel_stime-otherSTime);
1674                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1675                                    }
1676                                }
1677                            }
1678                            bstats.finishAddingCpuLocked(perc, totalUTime,
1679                                    totalSTime, cpuSpeedTimes);
1680                        }
1681                    }
1682                }
1683
1684                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1685                    mLastWriteTime = now;
1686                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1687                }
1688            }
1689        }
1690    }
1691
1692    @Override
1693    public void batteryNeedsCpuUpdate() {
1694        updateCpuStatsNow();
1695    }
1696
1697    @Override
1698    public void batteryPowerChanged(boolean onBattery) {
1699        // When plugging in, update the CPU stats first before changing
1700        // the plug state.
1701        updateCpuStatsNow();
1702        synchronized (this) {
1703            synchronized(mPidsSelfLocked) {
1704                mOnBattery = DEBUG_POWER ? true : onBattery;
1705            }
1706        }
1707    }
1708
1709    /**
1710     * Initialize the application bind args. These are passed to each
1711     * process when the bindApplication() IPC is sent to the process. They're
1712     * lazily setup to make sure the services are running when they're asked for.
1713     */
1714    private HashMap<String, IBinder> getCommonServicesLocked() {
1715        if (mAppBindArgs == null) {
1716            mAppBindArgs = new HashMap<String, IBinder>();
1717
1718            // Setup the application init args
1719            mAppBindArgs.put("package", ServiceManager.getService("package"));
1720            mAppBindArgs.put("window", ServiceManager.getService("window"));
1721            mAppBindArgs.put(Context.ALARM_SERVICE,
1722                    ServiceManager.getService(Context.ALARM_SERVICE));
1723        }
1724        return mAppBindArgs;
1725    }
1726
1727    final void setFocusedActivityLocked(ActivityRecord r) {
1728        if (mFocusedActivity != r) {
1729            mFocusedActivity = r;
1730            if (r != null) {
1731                mWindowManager.setFocusedApp(r.appToken, true);
1732            }
1733        }
1734    }
1735
1736    private final void updateLruProcessInternalLocked(ProcessRecord app,
1737            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1738        // put it on the LRU to keep track of when it should be exited.
1739        int lrui = mLruProcesses.indexOf(app);
1740        if (lrui >= 0) mLruProcesses.remove(lrui);
1741
1742        int i = mLruProcesses.size()-1;
1743        int skipTop = 0;
1744
1745        app.lruSeq = mLruSeq;
1746
1747        // compute the new weight for this process.
1748        if (updateActivityTime) {
1749            app.lastActivityTime = SystemClock.uptimeMillis();
1750        }
1751        if (app.activities.size() > 0) {
1752            // If this process has activities, we more strongly want to keep
1753            // it around.
1754            app.lruWeight = app.lastActivityTime;
1755        } else if (app.pubProviders.size() > 0) {
1756            // If this process contains content providers, we want to keep
1757            // it a little more strongly.
1758            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1759            // Also don't let it kick out the first few "real" hidden processes.
1760            skipTop = ProcessList.MIN_HIDDEN_APPS;
1761        } else {
1762            // If this process doesn't have activities, we less strongly
1763            // want to keep it around, and generally want to avoid getting
1764            // in front of any very recently used activities.
1765            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1766            // Also don't let it kick out the first few "real" hidden processes.
1767            skipTop = ProcessList.MIN_HIDDEN_APPS;
1768        }
1769
1770        while (i >= 0) {
1771            ProcessRecord p = mLruProcesses.get(i);
1772            // If this app shouldn't be in front of the first N background
1773            // apps, then skip over that many that are currently hidden.
1774            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1775                skipTop--;
1776            }
1777            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1778                mLruProcesses.add(i+1, app);
1779                break;
1780            }
1781            i--;
1782        }
1783        if (i < 0) {
1784            mLruProcesses.add(0, app);
1785        }
1786
1787        // If the app is currently using a content provider or service,
1788        // bump those processes as well.
1789        if (app.connections.size() > 0) {
1790            for (ConnectionRecord cr : app.connections) {
1791                if (cr.binding != null && cr.binding.service != null
1792                        && cr.binding.service.app != null
1793                        && cr.binding.service.app.lruSeq != mLruSeq) {
1794                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1795                            updateActivityTime, i+1);
1796                }
1797            }
1798        }
1799        for (int j=app.conProviders.size()-1; j>=0; j--) {
1800            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1801            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1802                updateLruProcessInternalLocked(cpr.proc, false,
1803                        updateActivityTime, i+1);
1804            }
1805        }
1806
1807        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1808        if (oomAdj) {
1809            updateOomAdjLocked();
1810        }
1811    }
1812
1813    final void updateLruProcessLocked(ProcessRecord app,
1814            boolean oomAdj, boolean updateActivityTime) {
1815        mLruSeq++;
1816        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1817    }
1818
1819    final ProcessRecord getProcessRecordLocked(
1820            String processName, int uid) {
1821        if (uid == Process.SYSTEM_UID) {
1822            // The system gets to run in any process.  If there are multiple
1823            // processes with the same uid, just pick the first (this
1824            // should never happen).
1825            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1826                    processName);
1827            if (procs == null) return null;
1828            final int N = procs.size();
1829            for (int i = 0; i < N; i++) {
1830                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1831            }
1832        }
1833        ProcessRecord proc = mProcessNames.get(processName, uid);
1834        return proc;
1835    }
1836
1837    void ensurePackageDexOpt(String packageName) {
1838        IPackageManager pm = AppGlobals.getPackageManager();
1839        try {
1840            if (pm.performDexOpt(packageName)) {
1841                mDidDexOpt = true;
1842            }
1843        } catch (RemoteException e) {
1844        }
1845    }
1846
1847    boolean isNextTransitionForward() {
1848        int transit = mWindowManager.getPendingAppTransition();
1849        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1850                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1851                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1852    }
1853
1854    final ProcessRecord startProcessLocked(String processName,
1855            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1856            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1857            boolean isolated) {
1858        ProcessRecord app;
1859        if (!isolated) {
1860            app = getProcessRecordLocked(processName, info.uid);
1861        } else {
1862            // If this is an isolated process, it can't re-use an existing process.
1863            app = null;
1864        }
1865        // We don't have to do anything more if:
1866        // (1) There is an existing application record; and
1867        // (2) The caller doesn't think it is dead, OR there is no thread
1868        //     object attached to it so we know it couldn't have crashed; and
1869        // (3) There is a pid assigned to it, so it is either starting or
1870        //     already running.
1871        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1872                + " app=" + app + " knownToBeDead=" + knownToBeDead
1873                + " thread=" + (app != null ? app.thread : null)
1874                + " pid=" + (app != null ? app.pid : -1));
1875        if (app != null && app.pid > 0) {
1876            if (!knownToBeDead || app.thread == null) {
1877                // We already have the app running, or are waiting for it to
1878                // come up (we have a pid but not yet its thread), so keep it.
1879                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1880                // If this is a new package in the process, add the package to the list
1881                app.addPackage(info.packageName);
1882                return app;
1883            } else {
1884                // An application record is attached to a previous process,
1885                // clean it up now.
1886                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1887                handleAppDiedLocked(app, true, true);
1888            }
1889        }
1890
1891        String hostingNameStr = hostingName != null
1892                ? hostingName.flattenToShortString() : null;
1893
1894        if (!isolated) {
1895            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1896                // If we are in the background, then check to see if this process
1897                // is bad.  If so, we will just silently fail.
1898                if (mBadProcesses.get(info.processName, info.uid) != null) {
1899                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1900                            + "/" + info.processName);
1901                    return null;
1902                }
1903            } else {
1904                // When the user is explicitly starting a process, then clear its
1905                // crash count so that we won't make it bad until they see at
1906                // least one crash dialog again, and make the process good again
1907                // if it had been bad.
1908                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1909                        + "/" + info.processName);
1910                mProcessCrashTimes.remove(info.processName, info.uid);
1911                if (mBadProcesses.get(info.processName, info.uid) != null) {
1912                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1913                            info.processName);
1914                    mBadProcesses.remove(info.processName, info.uid);
1915                    if (app != null) {
1916                        app.bad = false;
1917                    }
1918                }
1919            }
1920        }
1921
1922        if (app == null) {
1923            app = newProcessRecordLocked(null, info, processName, isolated);
1924            if (app == null) {
1925                Slog.w(TAG, "Failed making new process record for "
1926                        + processName + "/" + info.uid + " isolated=" + isolated);
1927                return null;
1928            }
1929            mProcessNames.put(processName, app.uid, app);
1930            if (isolated) {
1931                mIsolatedProcesses.put(app.uid, app);
1932            }
1933        } else {
1934            // If this is a new package in the process, add the package to the list
1935            app.addPackage(info.packageName);
1936        }
1937
1938        // If the system is not ready yet, then hold off on starting this
1939        // process until it is.
1940        if (!mProcessesReady
1941                && !isAllowedWhileBooting(info)
1942                && !allowWhileBooting) {
1943            if (!mProcessesOnHold.contains(app)) {
1944                mProcessesOnHold.add(app);
1945            }
1946            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1947            return app;
1948        }
1949
1950        startProcessLocked(app, hostingType, hostingNameStr);
1951        return (app.pid != 0) ? app : null;
1952    }
1953
1954    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1955        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1956    }
1957
1958    private final void startProcessLocked(ProcessRecord app,
1959            String hostingType, String hostingNameStr) {
1960        if (app.pid > 0 && app.pid != MY_PID) {
1961            synchronized (mPidsSelfLocked) {
1962                mPidsSelfLocked.remove(app.pid);
1963                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1964            }
1965            app.setPid(0);
1966        }
1967
1968        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1969                "startProcessLocked removing on hold: " + app);
1970        mProcessesOnHold.remove(app);
1971
1972        updateCpuStats();
1973
1974        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1975        mProcDeaths[0] = 0;
1976
1977        try {
1978            int uid = app.uid;
1979
1980            int[] gids = null;
1981            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1982            if (!app.isolated) {
1983                try {
1984                    final PackageManager pm = mContext.getPackageManager();
1985                    gids = pm.getPackageGids(app.info.packageName);
1986                } catch (PackageManager.NameNotFoundException e) {
1987                    Slog.w(TAG, "Unable to retrieve gids", e);
1988                }
1989
1990                if (Environment.isExternalStorageEmulated()) {
1991                    mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
1992                }
1993            }
1994            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1995                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1996                        && mTopComponent != null
1997                        && app.processName.equals(mTopComponent.getPackageName())) {
1998                    uid = 0;
1999                }
2000                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2001                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2002                    uid = 0;
2003                }
2004            }
2005            int debugFlags = 0;
2006            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2007                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2008                // Also turn on CheckJNI for debuggable apps. It's quite
2009                // awkward to turn on otherwise.
2010                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2011            }
2012            // Run the app in safe mode if its manifest requests so or the
2013            // system is booted in safe mode.
2014            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2015                Zygote.systemInSafeMode == true) {
2016                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2017            }
2018            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2019                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2020            }
2021            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2022                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2023            }
2024            if ("1".equals(SystemProperties.get("debug.assert"))) {
2025                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2026            }
2027
2028            // Start the process.  It will either succeed and return a result containing
2029            // the PID of the new process, or else throw a RuntimeException.
2030            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2031                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2032                    app.info.targetSdkVersion, null, null);
2033
2034            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2035            synchronized (bs) {
2036                if (bs.isOnBattery()) {
2037                    app.batteryStats.incStartsLocked();
2038                }
2039            }
2040
2041            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2042                    app.processName, hostingType,
2043                    hostingNameStr != null ? hostingNameStr : "");
2044
2045            if (app.persistent) {
2046                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2047            }
2048
2049            StringBuilder buf = mStringBuilder;
2050            buf.setLength(0);
2051            buf.append("Start proc ");
2052            buf.append(app.processName);
2053            buf.append(" for ");
2054            buf.append(hostingType);
2055            if (hostingNameStr != null) {
2056                buf.append(" ");
2057                buf.append(hostingNameStr);
2058            }
2059            buf.append(": pid=");
2060            buf.append(startResult.pid);
2061            buf.append(" uid=");
2062            buf.append(uid);
2063            buf.append(" gids={");
2064            if (gids != null) {
2065                for (int gi=0; gi<gids.length; gi++) {
2066                    if (gi != 0) buf.append(", ");
2067                    buf.append(gids[gi]);
2068
2069                }
2070            }
2071            buf.append("}");
2072            Slog.i(TAG, buf.toString());
2073            app.setPid(startResult.pid);
2074            app.usingWrapper = startResult.usingWrapper;
2075            app.removed = false;
2076            synchronized (mPidsSelfLocked) {
2077                this.mPidsSelfLocked.put(startResult.pid, app);
2078                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2079                msg.obj = app;
2080                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2081                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2082            }
2083        } catch (RuntimeException e) {
2084            // XXX do better error recovery.
2085            app.setPid(0);
2086            Slog.e(TAG, "Failure starting process " + app.processName, e);
2087        }
2088    }
2089
2090    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2091        if (resumed) {
2092            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2093        } else {
2094            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2095        }
2096    }
2097
2098    boolean startHomeActivityLocked(int userId) {
2099        if (mHeadless) {
2100            // Added because none of the other calls to ensureBootCompleted seem to fire
2101            // when running headless.
2102            ensureBootCompleted();
2103            return false;
2104        }
2105
2106        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2107                && mTopAction == null) {
2108            // We are running in factory test mode, but unable to find
2109            // the factory test app, so just sit around displaying the
2110            // error message and don't try to start anything.
2111            return false;
2112        }
2113        Intent intent = new Intent(
2114            mTopAction,
2115            mTopData != null ? Uri.parse(mTopData) : null);
2116        intent.setComponent(mTopComponent);
2117        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2118            intent.addCategory(Intent.CATEGORY_HOME);
2119        }
2120        ActivityInfo aInfo =
2121            intent.resolveActivityInfo(mContext.getPackageManager(),
2122                    STOCK_PM_FLAGS);
2123        if (aInfo != null) {
2124            intent.setComponent(new ComponentName(
2125                    aInfo.applicationInfo.packageName, aInfo.name));
2126            // Don't do this if the home app is currently being
2127            // instrumented.
2128            aInfo = new ActivityInfo(aInfo);
2129            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2130            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2131                    aInfo.applicationInfo.uid);
2132            if (app == null || app.instrumentationClass == null) {
2133                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2134                mMainStack.startActivityLocked(null, intent, null, aInfo,
2135                        null, null, 0, 0, 0, 0, null, false, null);
2136            }
2137        }
2138
2139        return true;
2140    }
2141
2142    /**
2143     * Starts the "new version setup screen" if appropriate.
2144     */
2145    void startSetupActivityLocked() {
2146        // Only do this once per boot.
2147        if (mCheckedForSetup) {
2148            return;
2149        }
2150
2151        // We will show this screen if the current one is a different
2152        // version than the last one shown, and we are not running in
2153        // low-level factory test mode.
2154        final ContentResolver resolver = mContext.getContentResolver();
2155        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2156                Settings.Secure.getInt(resolver,
2157                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2158            mCheckedForSetup = true;
2159
2160            // See if we should be showing the platform update setup UI.
2161            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2162            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2163                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2164
2165            // We don't allow third party apps to replace this.
2166            ResolveInfo ri = null;
2167            for (int i=0; ris != null && i<ris.size(); i++) {
2168                if ((ris.get(i).activityInfo.applicationInfo.flags
2169                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2170                    ri = ris.get(i);
2171                    break;
2172                }
2173            }
2174
2175            if (ri != null) {
2176                String vers = ri.activityInfo.metaData != null
2177                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2178                        : null;
2179                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2180                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2181                            Intent.METADATA_SETUP_VERSION);
2182                }
2183                String lastVers = Settings.Secure.getString(
2184                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2185                if (vers != null && !vers.equals(lastVers)) {
2186                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2187                    intent.setComponent(new ComponentName(
2188                            ri.activityInfo.packageName, ri.activityInfo.name));
2189                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2190                            null, null, 0, 0, 0, 0, null, false, null);
2191                }
2192            }
2193        }
2194    }
2195
2196    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2197        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2198    }
2199
2200    void enforceNotIsolatedCaller(String caller) {
2201        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2202            throw new SecurityException("Isolated process not allowed to call " + caller);
2203        }
2204    }
2205
2206    public int getFrontActivityScreenCompatMode() {
2207        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2208        synchronized (this) {
2209            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2210        }
2211    }
2212
2213    public void setFrontActivityScreenCompatMode(int mode) {
2214        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2215                "setFrontActivityScreenCompatMode");
2216        synchronized (this) {
2217            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2218        }
2219    }
2220
2221    public int getPackageScreenCompatMode(String packageName) {
2222        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2223        synchronized (this) {
2224            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2225        }
2226    }
2227
2228    public void setPackageScreenCompatMode(String packageName, int mode) {
2229        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2230                "setPackageScreenCompatMode");
2231        synchronized (this) {
2232            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2233        }
2234    }
2235
2236    public boolean getPackageAskScreenCompat(String packageName) {
2237        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2238        synchronized (this) {
2239            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2240        }
2241    }
2242
2243    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2244        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2245                "setPackageAskScreenCompat");
2246        synchronized (this) {
2247            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2248        }
2249    }
2250
2251    void reportResumedActivityLocked(ActivityRecord r) {
2252        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2253        updateUsageStats(r, true);
2254    }
2255
2256    private void dispatchProcessesChanged() {
2257        int N;
2258        synchronized (this) {
2259            N = mPendingProcessChanges.size();
2260            if (mActiveProcessChanges.length < N) {
2261                mActiveProcessChanges = new ProcessChangeItem[N];
2262            }
2263            mPendingProcessChanges.toArray(mActiveProcessChanges);
2264            mAvailProcessChanges.addAll(mPendingProcessChanges);
2265            mPendingProcessChanges.clear();
2266            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2267        }
2268        int i = mProcessObservers.beginBroadcast();
2269        while (i > 0) {
2270            i--;
2271            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2272            if (observer != null) {
2273                try {
2274                    for (int j=0; j<N; j++) {
2275                        ProcessChangeItem item = mActiveProcessChanges[j];
2276                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2277                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2278                                    + item.pid + " uid=" + item.uid + ": "
2279                                    + item.foregroundActivities);
2280                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2281                                    item.foregroundActivities);
2282                        }
2283                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2284                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2285                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2286                            observer.onImportanceChanged(item.pid, item.uid,
2287                                    item.importance);
2288                        }
2289                    }
2290                } catch (RemoteException e) {
2291                }
2292            }
2293        }
2294        mProcessObservers.finishBroadcast();
2295    }
2296
2297    private void dispatchProcessDied(int pid, int uid) {
2298        int i = mProcessObservers.beginBroadcast();
2299        while (i > 0) {
2300            i--;
2301            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2302            if (observer != null) {
2303                try {
2304                    observer.onProcessDied(pid, uid);
2305                } catch (RemoteException e) {
2306                }
2307            }
2308        }
2309        mProcessObservers.finishBroadcast();
2310    }
2311
2312    final void doPendingActivityLaunchesLocked(boolean doResume) {
2313        final int N = mPendingActivityLaunches.size();
2314        if (N <= 0) {
2315            return;
2316        }
2317        for (int i=0; i<N; i++) {
2318            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2319            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2320                    pal.startFlags, doResume && i == (N-1), null);
2321        }
2322        mPendingActivityLaunches.clear();
2323    }
2324
2325    public final int startActivity(IApplicationThread caller,
2326            Intent intent, String resolvedType, IBinder resultTo,
2327            String resultWho, int requestCode, int startFlags,
2328            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2329        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2330                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2331    }
2332
2333    public final int startActivityAsUser(IApplicationThread caller,
2334            Intent intent, String resolvedType, IBinder resultTo,
2335            String resultWho, int requestCode, int startFlags,
2336            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2337        enforceNotIsolatedCaller("startActivity");
2338        if (userId != UserHandle.getCallingUserId()) {
2339            // Requesting a different user, make sure that they have the permission
2340            if (checkComponentPermission(
2341                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2342                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2343                    == PackageManager.PERMISSION_GRANTED) {
2344                // Translate to the current user id, if caller wasn't aware
2345                if (userId == UserHandle.USER_CURRENT) {
2346                    userId = mCurrentUserId;
2347                }
2348            } else {
2349                String msg = "Permission Denial: "
2350                        + "Request to startActivity as user " + userId
2351                        + " but is calling from user " + UserHandle.getCallingUserId()
2352                        + "; this requires "
2353                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2354                Slog.w(TAG, msg);
2355                throw new SecurityException(msg);
2356            }
2357        } else {
2358            if (intent.getCategories() != null
2359                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2360                // Requesting home, set the identity to the current user
2361                // HACK!
2362                userId = mCurrentUserId;
2363            } else {
2364                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2365                // the current user's userId
2366                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2367                    userId = 0;
2368                } else {
2369                    userId = Binder.getOrigCallingUser();
2370                }
2371            }
2372        }
2373        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2374                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2375                null, null, options, userId);
2376    }
2377
2378    public final WaitResult startActivityAndWait(IApplicationThread caller,
2379            Intent intent, String resolvedType, IBinder resultTo,
2380            String resultWho, int requestCode, int startFlags, String profileFile,
2381            ParcelFileDescriptor profileFd, Bundle options) {
2382        enforceNotIsolatedCaller("startActivityAndWait");
2383        WaitResult res = new WaitResult();
2384        int userId = Binder.getOrigCallingUser();
2385        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2386                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2387                res, null, options, userId);
2388        return res;
2389    }
2390
2391    public final int startActivityWithConfig(IApplicationThread caller,
2392            Intent intent, String resolvedType, IBinder resultTo,
2393            String resultWho, int requestCode, int startFlags, Configuration config,
2394            Bundle options) {
2395        enforceNotIsolatedCaller("startActivityWithConfig");
2396        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2397                resultTo, resultWho, requestCode, startFlags,
2398                null, null, null, config, options, Binder.getOrigCallingUser());
2399        return ret;
2400    }
2401
2402    public int startActivityIntentSender(IApplicationThread caller,
2403            IntentSender intent, Intent fillInIntent, String resolvedType,
2404            IBinder resultTo, String resultWho, int requestCode,
2405            int flagsMask, int flagsValues, Bundle options) {
2406        enforceNotIsolatedCaller("startActivityIntentSender");
2407        // Refuse possible leaked file descriptors
2408        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2409            throw new IllegalArgumentException("File descriptors passed in Intent");
2410        }
2411
2412        IIntentSender sender = intent.getTarget();
2413        if (!(sender instanceof PendingIntentRecord)) {
2414            throw new IllegalArgumentException("Bad PendingIntent object");
2415        }
2416
2417        PendingIntentRecord pir = (PendingIntentRecord)sender;
2418
2419        synchronized (this) {
2420            // If this is coming from the currently resumed activity, it is
2421            // effectively saying that app switches are allowed at this point.
2422            if (mMainStack.mResumedActivity != null
2423                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2424                            Binder.getCallingUid()) {
2425                mAppSwitchesAllowedTime = 0;
2426            }
2427        }
2428        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2429                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2430        return ret;
2431    }
2432
2433    public boolean startNextMatchingActivity(IBinder callingActivity,
2434            Intent intent, Bundle options) {
2435        // Refuse possible leaked file descriptors
2436        if (intent != null && intent.hasFileDescriptors() == true) {
2437            throw new IllegalArgumentException("File descriptors passed in Intent");
2438        }
2439
2440        synchronized (this) {
2441            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2442            if (r == null) {
2443                ActivityOptions.abort(options);
2444                return false;
2445            }
2446            if (r.app == null || r.app.thread == null) {
2447                // The caller is not running...  d'oh!
2448                ActivityOptions.abort(options);
2449                return false;
2450            }
2451            intent = new Intent(intent);
2452            // The caller is not allowed to change the data.
2453            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2454            // And we are resetting to find the next component...
2455            intent.setComponent(null);
2456
2457            ActivityInfo aInfo = null;
2458            try {
2459                List<ResolveInfo> resolves =
2460                    AppGlobals.getPackageManager().queryIntentActivities(
2461                            intent, r.resolvedType,
2462                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2463                            UserHandle.getCallingUserId());
2464
2465                // Look for the original activity in the list...
2466                final int N = resolves != null ? resolves.size() : 0;
2467                for (int i=0; i<N; i++) {
2468                    ResolveInfo rInfo = resolves.get(i);
2469                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2470                            && rInfo.activityInfo.name.equals(r.info.name)) {
2471                        // We found the current one...  the next matching is
2472                        // after it.
2473                        i++;
2474                        if (i<N) {
2475                            aInfo = resolves.get(i).activityInfo;
2476                        }
2477                        break;
2478                    }
2479                }
2480            } catch (RemoteException e) {
2481            }
2482
2483            if (aInfo == null) {
2484                // Nobody who is next!
2485                ActivityOptions.abort(options);
2486                return false;
2487            }
2488
2489            intent.setComponent(new ComponentName(
2490                    aInfo.applicationInfo.packageName, aInfo.name));
2491            intent.setFlags(intent.getFlags()&~(
2492                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2493                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2494                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2495                    Intent.FLAG_ACTIVITY_NEW_TASK));
2496
2497            // Okay now we need to start the new activity, replacing the
2498            // currently running activity.  This is a little tricky because
2499            // we want to start the new one as if the current one is finished,
2500            // but not finish the current one first so that there is no flicker.
2501            // And thus...
2502            final boolean wasFinishing = r.finishing;
2503            r.finishing = true;
2504
2505            // Propagate reply information over to the new activity.
2506            final ActivityRecord resultTo = r.resultTo;
2507            final String resultWho = r.resultWho;
2508            final int requestCode = r.requestCode;
2509            r.resultTo = null;
2510            if (resultTo != null) {
2511                resultTo.removeResultsLocked(r, resultWho, requestCode);
2512            }
2513
2514            final long origId = Binder.clearCallingIdentity();
2515            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2516                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2517                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2518                    options, false, null);
2519            Binder.restoreCallingIdentity(origId);
2520
2521            r.finishing = wasFinishing;
2522            if (res != ActivityManager.START_SUCCESS) {
2523                return false;
2524            }
2525            return true;
2526        }
2527    }
2528
2529    public final int startActivityInPackage(int uid,
2530            Intent intent, String resolvedType, IBinder resultTo,
2531            String resultWho, int requestCode, int startFlags, Bundle options) {
2532
2533        // This is so super not safe, that only the system (or okay root)
2534        // can do it.
2535        final int callingUid = Binder.getCallingUid();
2536        if (callingUid != 0 && callingUid != Process.myUid()) {
2537            throw new SecurityException(
2538                    "startActivityInPackage only available to the system");
2539        }
2540
2541        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2542                resultTo, resultWho, requestCode, startFlags,
2543                null, null, null, null, options, UserHandle.getUserId(uid));
2544        return ret;
2545    }
2546
2547    public final int startActivities(IApplicationThread caller,
2548            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2549        enforceNotIsolatedCaller("startActivities");
2550        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2551                options, Binder.getOrigCallingUser());
2552        return ret;
2553    }
2554
2555    public final int startActivitiesInPackage(int uid,
2556            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2557            Bundle options) {
2558
2559        // This is so super not safe, that only the system (or okay root)
2560        // can do it.
2561        final int callingUid = Binder.getCallingUid();
2562        if (callingUid != 0 && callingUid != Process.myUid()) {
2563            throw new SecurityException(
2564                    "startActivityInPackage only available to the system");
2565        }
2566        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2567                options, UserHandle.getUserId(uid));
2568        return ret;
2569    }
2570
2571    final void addRecentTaskLocked(TaskRecord task) {
2572        int N = mRecentTasks.size();
2573        // Quick case: check if the top-most recent task is the same.
2574        if (N > 0 && mRecentTasks.get(0) == task) {
2575            return;
2576        }
2577        // Remove any existing entries that are the same kind of task.
2578        for (int i=0; i<N; i++) {
2579            TaskRecord tr = mRecentTasks.get(i);
2580            if (task.userId == tr.userId
2581                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2582                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2583                mRecentTasks.remove(i);
2584                i--;
2585                N--;
2586                if (task.intent == null) {
2587                    // If the new recent task we are adding is not fully
2588                    // specified, then replace it with the existing recent task.
2589                    task = tr;
2590                }
2591            }
2592        }
2593        if (N >= MAX_RECENT_TASKS) {
2594            mRecentTasks.remove(N-1);
2595        }
2596        mRecentTasks.add(0, task);
2597    }
2598
2599    public void setRequestedOrientation(IBinder token,
2600            int requestedOrientation) {
2601        synchronized (this) {
2602            ActivityRecord r = mMainStack.isInStackLocked(token);
2603            if (r == null) {
2604                return;
2605            }
2606            final long origId = Binder.clearCallingIdentity();
2607            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2608            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2609                    mConfiguration,
2610                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2611            if (config != null) {
2612                r.frozenBeforeDestroy = true;
2613                if (!updateConfigurationLocked(config, r, false, false)) {
2614                    mMainStack.resumeTopActivityLocked(null);
2615                }
2616            }
2617            Binder.restoreCallingIdentity(origId);
2618        }
2619    }
2620
2621    public int getRequestedOrientation(IBinder token) {
2622        synchronized (this) {
2623            ActivityRecord r = mMainStack.isInStackLocked(token);
2624            if (r == null) {
2625                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2626            }
2627            return mWindowManager.getAppOrientation(r.appToken);
2628        }
2629    }
2630
2631    /**
2632     * This is the internal entry point for handling Activity.finish().
2633     *
2634     * @param token The Binder token referencing the Activity we want to finish.
2635     * @param resultCode Result code, if any, from this Activity.
2636     * @param resultData Result data (Intent), if any, from this Activity.
2637     *
2638     * @return Returns true if the activity successfully finished, or false if it is still running.
2639     */
2640    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2641        // Refuse possible leaked file descriptors
2642        if (resultData != null && resultData.hasFileDescriptors() == true) {
2643            throw new IllegalArgumentException("File descriptors passed in Intent");
2644        }
2645
2646        synchronized(this) {
2647            if (mController != null) {
2648                // Find the first activity that is not finishing.
2649                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2650                if (next != null) {
2651                    // ask watcher if this is allowed
2652                    boolean resumeOK = true;
2653                    try {
2654                        resumeOK = mController.activityResuming(next.packageName);
2655                    } catch (RemoteException e) {
2656                        mController = null;
2657                    }
2658
2659                    if (!resumeOK) {
2660                        return false;
2661                    }
2662                }
2663            }
2664            final long origId = Binder.clearCallingIdentity();
2665            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2666                    resultData, "app-request");
2667            Binder.restoreCallingIdentity(origId);
2668            return res;
2669        }
2670    }
2671
2672    public final void finishHeavyWeightApp() {
2673        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2674                != PackageManager.PERMISSION_GRANTED) {
2675            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2676                    + Binder.getCallingPid()
2677                    + ", uid=" + Binder.getCallingUid()
2678                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2679            Slog.w(TAG, msg);
2680            throw new SecurityException(msg);
2681        }
2682
2683        synchronized(this) {
2684            if (mHeavyWeightProcess == null) {
2685                return;
2686            }
2687
2688            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2689                    mHeavyWeightProcess.activities);
2690            for (int i=0; i<activities.size(); i++) {
2691                ActivityRecord r = activities.get(i);
2692                if (!r.finishing) {
2693                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2694                    if (index >= 0) {
2695                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2696                                null, "finish-heavy");
2697                    }
2698                }
2699            }
2700
2701            mHeavyWeightProcess = null;
2702            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2703        }
2704    }
2705
2706    public void crashApplication(int uid, int initialPid, String packageName,
2707            String message) {
2708        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2709                != PackageManager.PERMISSION_GRANTED) {
2710            String msg = "Permission Denial: crashApplication() from pid="
2711                    + Binder.getCallingPid()
2712                    + ", uid=" + Binder.getCallingUid()
2713                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2714            Slog.w(TAG, msg);
2715            throw new SecurityException(msg);
2716        }
2717
2718        synchronized(this) {
2719            ProcessRecord proc = null;
2720
2721            // Figure out which process to kill.  We don't trust that initialPid
2722            // still has any relation to current pids, so must scan through the
2723            // list.
2724            synchronized (mPidsSelfLocked) {
2725                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2726                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2727                    if (p.uid != uid) {
2728                        continue;
2729                    }
2730                    if (p.pid == initialPid) {
2731                        proc = p;
2732                        break;
2733                    }
2734                    for (String str : p.pkgList) {
2735                        if (str.equals(packageName)) {
2736                            proc = p;
2737                        }
2738                    }
2739                }
2740            }
2741
2742            if (proc == null) {
2743                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2744                        + " initialPid=" + initialPid
2745                        + " packageName=" + packageName);
2746                return;
2747            }
2748
2749            if (proc.thread != null) {
2750                if (proc.pid == Process.myPid()) {
2751                    Log.w(TAG, "crashApplication: trying to crash self!");
2752                    return;
2753                }
2754                long ident = Binder.clearCallingIdentity();
2755                try {
2756                    proc.thread.scheduleCrash(message);
2757                } catch (RemoteException e) {
2758                }
2759                Binder.restoreCallingIdentity(ident);
2760            }
2761        }
2762    }
2763
2764    public final void finishSubActivity(IBinder token, String resultWho,
2765            int requestCode) {
2766        synchronized(this) {
2767            final long origId = Binder.clearCallingIdentity();
2768            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2769            Binder.restoreCallingIdentity(origId);
2770        }
2771    }
2772
2773    public boolean finishActivityAffinity(IBinder token) {
2774        synchronized(this) {
2775            final long origId = Binder.clearCallingIdentity();
2776            boolean res = mMainStack.finishActivityAffinityLocked(token);
2777            Binder.restoreCallingIdentity(origId);
2778            return res;
2779        }
2780    }
2781
2782    public boolean willActivityBeVisible(IBinder token) {
2783        synchronized(this) {
2784            int i;
2785            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2786                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2787                if (r.appToken == token) {
2788                    return true;
2789                }
2790                if (r.fullscreen && !r.finishing) {
2791                    return false;
2792                }
2793            }
2794            return true;
2795        }
2796    }
2797
2798    public void overridePendingTransition(IBinder token, String packageName,
2799            int enterAnim, int exitAnim) {
2800        synchronized(this) {
2801            ActivityRecord self = mMainStack.isInStackLocked(token);
2802            if (self == null) {
2803                return;
2804            }
2805
2806            final long origId = Binder.clearCallingIdentity();
2807
2808            if (self.state == ActivityState.RESUMED
2809                    || self.state == ActivityState.PAUSING) {
2810                mWindowManager.overridePendingAppTransition(packageName,
2811                        enterAnim, exitAnim, null);
2812            }
2813
2814            Binder.restoreCallingIdentity(origId);
2815        }
2816    }
2817
2818    /**
2819     * Main function for removing an existing process from the activity manager
2820     * as a result of that process going away.  Clears out all connections
2821     * to the process.
2822     */
2823    private final void handleAppDiedLocked(ProcessRecord app,
2824            boolean restarting, boolean allowRestart) {
2825        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2826        if (!restarting) {
2827            mLruProcesses.remove(app);
2828        }
2829
2830        if (mProfileProc == app) {
2831            clearProfilerLocked();
2832        }
2833
2834        // Just in case...
2835        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2836            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2837            mMainStack.mPausingActivity = null;
2838        }
2839        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2840            mMainStack.mLastPausedActivity = null;
2841        }
2842
2843        // Remove this application's activities from active lists.
2844        mMainStack.removeHistoryRecordsForAppLocked(app);
2845
2846        boolean atTop = true;
2847        boolean hasVisibleActivities = false;
2848
2849        // Clean out the history list.
2850        int i = mMainStack.mHistory.size();
2851        if (localLOGV) Slog.v(
2852            TAG, "Removing app " + app + " from history with " + i + " entries");
2853        while (i > 0) {
2854            i--;
2855            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2856            if (localLOGV) Slog.v(
2857                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2858            if (r.app == app) {
2859                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2860                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2861                        RuntimeException here = new RuntimeException("here");
2862                        here.fillInStackTrace();
2863                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2864                                + ": haveState=" + r.haveState
2865                                + " stateNotNeeded=" + r.stateNotNeeded
2866                                + " finishing=" + r.finishing
2867                                + " state=" + r.state, here);
2868                    }
2869                    if (!r.finishing) {
2870                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2871                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2872                                System.identityHashCode(r),
2873                                r.task.taskId, r.shortComponentName,
2874                                "proc died without state saved");
2875                    }
2876                    mMainStack.removeActivityFromHistoryLocked(r);
2877
2878                } else {
2879                    // We have the current state for this activity, so
2880                    // it can be restarted later when needed.
2881                    if (localLOGV) Slog.v(
2882                        TAG, "Keeping entry, setting app to null");
2883                    if (r.visible) {
2884                        hasVisibleActivities = true;
2885                    }
2886                    r.app = null;
2887                    r.nowVisible = false;
2888                    if (!r.haveState) {
2889                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2890                                "App died, clearing saved state of " + r);
2891                        r.icicle = null;
2892                    }
2893                }
2894
2895                r.stack.cleanUpActivityLocked(r, true, true);
2896            }
2897            atTop = false;
2898        }
2899
2900        app.activities.clear();
2901
2902        if (app.instrumentationClass != null) {
2903            Slog.w(TAG, "Crash of app " + app.processName
2904                  + " running instrumentation " + app.instrumentationClass);
2905            Bundle info = new Bundle();
2906            info.putString("shortMsg", "Process crashed.");
2907            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2908        }
2909
2910        if (!restarting) {
2911            if (!mMainStack.resumeTopActivityLocked(null)) {
2912                // If there was nothing to resume, and we are not already
2913                // restarting this process, but there is a visible activity that
2914                // is hosted by the process...  then make sure all visible
2915                // activities are running, taking care of restarting this
2916                // process.
2917                if (hasVisibleActivities) {
2918                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2919                }
2920            }
2921        }
2922    }
2923
2924    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2925        IBinder threadBinder = thread.asBinder();
2926        // Find the application record.
2927        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2928            ProcessRecord rec = mLruProcesses.get(i);
2929            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2930                return i;
2931            }
2932        }
2933        return -1;
2934    }
2935
2936    final ProcessRecord getRecordForAppLocked(
2937            IApplicationThread thread) {
2938        if (thread == null) {
2939            return null;
2940        }
2941
2942        int appIndex = getLRURecordIndexForAppLocked(thread);
2943        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2944    }
2945
2946    final void appDiedLocked(ProcessRecord app, int pid,
2947            IApplicationThread thread) {
2948
2949        mProcDeaths[0]++;
2950
2951        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2952        synchronized (stats) {
2953            stats.noteProcessDiedLocked(app.info.uid, pid);
2954        }
2955
2956        // Clean up already done if the process has been re-started.
2957        if (app.pid == pid && app.thread != null &&
2958                app.thread.asBinder() == thread.asBinder()) {
2959            if (!app.killedBackground) {
2960                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2961                        + ") has died.");
2962            }
2963            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2964            if (localLOGV) Slog.v(
2965                TAG, "Dying app: " + app + ", pid: " + pid
2966                + ", thread: " + thread.asBinder());
2967            boolean doLowMem = app.instrumentationClass == null;
2968            handleAppDiedLocked(app, false, true);
2969
2970            if (doLowMem) {
2971                // If there are no longer any background processes running,
2972                // and the app that died was not running instrumentation,
2973                // then tell everyone we are now low on memory.
2974                boolean haveBg = false;
2975                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2976                    ProcessRecord rec = mLruProcesses.get(i);
2977                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2978                        haveBg = true;
2979                        break;
2980                    }
2981                }
2982
2983                if (!haveBg) {
2984                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2985                    long now = SystemClock.uptimeMillis();
2986                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2987                        ProcessRecord rec = mLruProcesses.get(i);
2988                        if (rec != app && rec.thread != null &&
2989                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2990                            // The low memory report is overriding any current
2991                            // state for a GC request.  Make sure to do
2992                            // heavy/important/visible/foreground processes first.
2993                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2994                                rec.lastRequestedGc = 0;
2995                            } else {
2996                                rec.lastRequestedGc = rec.lastLowMemory;
2997                            }
2998                            rec.reportLowMemory = true;
2999                            rec.lastLowMemory = now;
3000                            mProcessesToGc.remove(rec);
3001                            addProcessToGcListLocked(rec);
3002                        }
3003                    }
3004                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3005                    scheduleAppGcsLocked();
3006                }
3007            }
3008        } else if (app.pid != pid) {
3009            // A new process has already been started.
3010            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3011                    + ") has died and restarted (pid " + app.pid + ").");
3012            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3013        } else if (DEBUG_PROCESSES) {
3014            Slog.d(TAG, "Received spurious death notification for thread "
3015                    + thread.asBinder());
3016        }
3017    }
3018
3019    /**
3020     * If a stack trace dump file is configured, dump process stack traces.
3021     * @param clearTraces causes the dump file to be erased prior to the new
3022     *    traces being written, if true; when false, the new traces will be
3023     *    appended to any existing file content.
3024     * @param firstPids of dalvik VM processes to dump stack traces for first
3025     * @param lastPids of dalvik VM processes to dump stack traces for last
3026     * @param nativeProcs optional list of native process names to dump stack crawls
3027     * @return file containing stack traces, or null if no dump file is configured
3028     */
3029    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3030            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3031        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3032        if (tracesPath == null || tracesPath.length() == 0) {
3033            return null;
3034        }
3035
3036        File tracesFile = new File(tracesPath);
3037        try {
3038            File tracesDir = tracesFile.getParentFile();
3039            if (!tracesDir.exists()) {
3040                tracesFile.mkdirs();
3041                if (!SELinux.restorecon(tracesDir)) {
3042                    return null;
3043                }
3044            }
3045            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3046
3047            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3048            tracesFile.createNewFile();
3049            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3050        } catch (IOException e) {
3051            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3052            return null;
3053        }
3054
3055        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3056        return tracesFile;
3057    }
3058
3059    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3060            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3061        // Use a FileObserver to detect when traces finish writing.
3062        // The order of traces is considered important to maintain for legibility.
3063        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3064            public synchronized void onEvent(int event, String path) { notify(); }
3065        };
3066
3067        try {
3068            observer.startWatching();
3069
3070            // First collect all of the stacks of the most important pids.
3071            if (firstPids != null) {
3072                try {
3073                    int num = firstPids.size();
3074                    for (int i = 0; i < num; i++) {
3075                        synchronized (observer) {
3076                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3077                            observer.wait(200);  // Wait for write-close, give up after 200msec
3078                        }
3079                    }
3080                } catch (InterruptedException e) {
3081                    Log.wtf(TAG, e);
3082                }
3083            }
3084
3085            // Next measure CPU usage.
3086            if (processStats != null) {
3087                processStats.init();
3088                System.gc();
3089                processStats.update();
3090                try {
3091                    synchronized (processStats) {
3092                        processStats.wait(500); // measure over 1/2 second.
3093                    }
3094                } catch (InterruptedException e) {
3095                }
3096                processStats.update();
3097
3098                // We'll take the stack crawls of just the top apps using CPU.
3099                final int N = processStats.countWorkingStats();
3100                int numProcs = 0;
3101                for (int i=0; i<N && numProcs<5; i++) {
3102                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3103                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3104                        numProcs++;
3105                        try {
3106                            synchronized (observer) {
3107                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3108                                observer.wait(200);  // Wait for write-close, give up after 200msec
3109                            }
3110                        } catch (InterruptedException e) {
3111                            Log.wtf(TAG, e);
3112                        }
3113
3114                    }
3115                }
3116            }
3117
3118        } finally {
3119            observer.stopWatching();
3120        }
3121
3122        if (nativeProcs != null) {
3123            int[] pids = Process.getPidsForCommands(nativeProcs);
3124            if (pids != null) {
3125                for (int pid : pids) {
3126                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3127                }
3128            }
3129        }
3130    }
3131
3132    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3133        if (true || IS_USER_BUILD) {
3134            return;
3135        }
3136        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3137        if (tracesPath == null || tracesPath.length() == 0) {
3138            return;
3139        }
3140
3141        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3142        StrictMode.allowThreadDiskWrites();
3143        try {
3144            final File tracesFile = new File(tracesPath);
3145            final File tracesDir = tracesFile.getParentFile();
3146            final File tracesTmp = new File(tracesDir, "__tmp__");
3147            try {
3148                if (!tracesDir.exists()) {
3149                    tracesFile.mkdirs();
3150                    if (!SELinux.restorecon(tracesDir.getPath())) {
3151                        return;
3152                    }
3153                }
3154                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3155
3156                if (tracesFile.exists()) {
3157                    tracesTmp.delete();
3158                    tracesFile.renameTo(tracesTmp);
3159                }
3160                StringBuilder sb = new StringBuilder();
3161                Time tobj = new Time();
3162                tobj.set(System.currentTimeMillis());
3163                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3164                sb.append(": ");
3165                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3166                sb.append(" since ");
3167                sb.append(msg);
3168                FileOutputStream fos = new FileOutputStream(tracesFile);
3169                fos.write(sb.toString().getBytes());
3170                if (app == null) {
3171                    fos.write("\n*** No application process!".getBytes());
3172                }
3173                fos.close();
3174                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3175            } catch (IOException e) {
3176                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3177                return;
3178            }
3179
3180            if (app != null) {
3181                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3182                firstPids.add(app.pid);
3183                dumpStackTraces(tracesPath, firstPids, null, null, null);
3184            }
3185
3186            File lastTracesFile = null;
3187            File curTracesFile = null;
3188            for (int i=9; i>=0; i--) {
3189                String name = String.format("slow%02d.txt", i);
3190                curTracesFile = new File(tracesDir, name);
3191                if (curTracesFile.exists()) {
3192                    if (lastTracesFile != null) {
3193                        curTracesFile.renameTo(lastTracesFile);
3194                    } else {
3195                        curTracesFile.delete();
3196                    }
3197                }
3198                lastTracesFile = curTracesFile;
3199            }
3200            tracesFile.renameTo(curTracesFile);
3201            if (tracesTmp.exists()) {
3202                tracesTmp.renameTo(tracesFile);
3203            }
3204        } finally {
3205            StrictMode.setThreadPolicy(oldPolicy);
3206        }
3207    }
3208
3209    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3210            ActivityRecord parent, final String annotation) {
3211        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3212        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3213
3214        if (mController != null) {
3215            try {
3216                // 0 == continue, -1 = kill process immediately
3217                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3218                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3219            } catch (RemoteException e) {
3220                mController = null;
3221            }
3222        }
3223
3224        long anrTime = SystemClock.uptimeMillis();
3225        if (MONITOR_CPU_USAGE) {
3226            updateCpuStatsNow();
3227        }
3228
3229        synchronized (this) {
3230            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3231            if (mShuttingDown) {
3232                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3233                return;
3234            } else if (app.notResponding) {
3235                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3236                return;
3237            } else if (app.crashing) {
3238                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3239                return;
3240            }
3241
3242            // In case we come through here for the same app before completing
3243            // this one, mark as anring now so we will bail out.
3244            app.notResponding = true;
3245
3246            // Log the ANR to the event log.
3247            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3248                    annotation);
3249
3250            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3251            firstPids.add(app.pid);
3252
3253            int parentPid = app.pid;
3254            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3255            if (parentPid != app.pid) firstPids.add(parentPid);
3256
3257            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3258
3259            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3260                ProcessRecord r = mLruProcesses.get(i);
3261                if (r != null && r.thread != null) {
3262                    int pid = r.pid;
3263                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3264                        if (r.persistent) {
3265                            firstPids.add(pid);
3266                        } else {
3267                            lastPids.put(pid, Boolean.TRUE);
3268                        }
3269                    }
3270                }
3271            }
3272        }
3273
3274        // Log the ANR to the main log.
3275        StringBuilder info = new StringBuilder();
3276        info.setLength(0);
3277        info.append("ANR in ").append(app.processName);
3278        if (activity != null && activity.shortComponentName != null) {
3279            info.append(" (").append(activity.shortComponentName).append(")");
3280        }
3281        info.append("\n");
3282        if (annotation != null) {
3283            info.append("Reason: ").append(annotation).append("\n");
3284        }
3285        if (parent != null && parent != activity) {
3286            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3287        }
3288
3289        final ProcessStats processStats = new ProcessStats(true);
3290
3291        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3292
3293        String cpuInfo = null;
3294        if (MONITOR_CPU_USAGE) {
3295            updateCpuStatsNow();
3296            synchronized (mProcessStatsThread) {
3297                cpuInfo = mProcessStats.printCurrentState(anrTime);
3298            }
3299            info.append(processStats.printCurrentLoad());
3300            info.append(cpuInfo);
3301        }
3302
3303        info.append(processStats.printCurrentState(anrTime));
3304
3305        Slog.e(TAG, info.toString());
3306        if (tracesFile == null) {
3307            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3308            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3309        }
3310
3311        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3312                cpuInfo, tracesFile, null);
3313
3314        if (mController != null) {
3315            try {
3316                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3317                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3318                if (res != 0) {
3319                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3320                    return;
3321                }
3322            } catch (RemoteException e) {
3323                mController = null;
3324            }
3325        }
3326
3327        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3328        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3329                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3330
3331        synchronized (this) {
3332            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3333                Slog.w(TAG, "Killing " + app + ": background ANR");
3334                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3335                        app.processName, app.setAdj, "background ANR");
3336                Process.killProcessQuiet(app.pid);
3337                return;
3338            }
3339
3340            // Set the app's notResponding state, and look up the errorReportReceiver
3341            makeAppNotRespondingLocked(app,
3342                    activity != null ? activity.shortComponentName : null,
3343                    annotation != null ? "ANR " + annotation : "ANR",
3344                    info.toString());
3345
3346            // Bring up the infamous App Not Responding dialog
3347            Message msg = Message.obtain();
3348            HashMap map = new HashMap();
3349            msg.what = SHOW_NOT_RESPONDING_MSG;
3350            msg.obj = map;
3351            map.put("app", app);
3352            if (activity != null) {
3353                map.put("activity", activity);
3354            }
3355
3356            mHandler.sendMessage(msg);
3357        }
3358    }
3359
3360    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3361        if (!mLaunchWarningShown) {
3362            mLaunchWarningShown = true;
3363            mHandler.post(new Runnable() {
3364                @Override
3365                public void run() {
3366                    synchronized (ActivityManagerService.this) {
3367                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3368                        d.show();
3369                        mHandler.postDelayed(new Runnable() {
3370                            @Override
3371                            public void run() {
3372                                synchronized (ActivityManagerService.this) {
3373                                    d.dismiss();
3374                                    mLaunchWarningShown = false;
3375                                }
3376                            }
3377                        }, 4000);
3378                    }
3379                }
3380            });
3381        }
3382    }
3383
3384    public boolean clearApplicationUserData(final String packageName,
3385            final IPackageDataObserver observer, final int userId) {
3386        enforceNotIsolatedCaller("clearApplicationUserData");
3387        int uid = Binder.getCallingUid();
3388        int pid = Binder.getCallingPid();
3389        long callingId = Binder.clearCallingIdentity();
3390        try {
3391            IPackageManager pm = AppGlobals.getPackageManager();
3392            int pkgUid = -1;
3393            synchronized(this) {
3394                try {
3395                    pkgUid = pm.getPackageUid(packageName, userId);
3396                } catch (RemoteException e) {
3397                }
3398                if (pkgUid == -1) {
3399                    Slog.w(TAG, "Invalid packageName:" + packageName);
3400                    return false;
3401                }
3402                if (uid == pkgUid || checkComponentPermission(
3403                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3404                        pid, uid, -1, true)
3405                        == PackageManager.PERMISSION_GRANTED) {
3406                    forceStopPackageLocked(packageName, pkgUid);
3407                } else {
3408                    throw new SecurityException(pid+" does not have permission:"+
3409                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3410                                    "for process:"+packageName);
3411                }
3412            }
3413
3414            try {
3415                //clear application user data
3416                pm.clearApplicationUserData(packageName, observer, userId);
3417                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3418                        Uri.fromParts("package", packageName, null));
3419                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3420                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3421                        null, null, 0, null, null, null, false, false, userId);
3422            } catch (RemoteException e) {
3423            }
3424        } finally {
3425            Binder.restoreCallingIdentity(callingId);
3426        }
3427        return true;
3428    }
3429
3430    public void killBackgroundProcesses(final String packageName) {
3431        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3432                != PackageManager.PERMISSION_GRANTED &&
3433                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3434                        != PackageManager.PERMISSION_GRANTED) {
3435            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3436                    + Binder.getCallingPid()
3437                    + ", uid=" + Binder.getCallingUid()
3438                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3439            Slog.w(TAG, msg);
3440            throw new SecurityException(msg);
3441        }
3442
3443        int userId = UserHandle.getCallingUserId();
3444        long callingId = Binder.clearCallingIdentity();
3445        try {
3446            IPackageManager pm = AppGlobals.getPackageManager();
3447            int pkgUid = -1;
3448            synchronized(this) {
3449                try {
3450                    pkgUid = pm.getPackageUid(packageName, userId);
3451                } catch (RemoteException e) {
3452                }
3453                if (pkgUid == -1) {
3454                    Slog.w(TAG, "Invalid packageName: " + packageName);
3455                    return;
3456                }
3457                killPackageProcessesLocked(packageName, pkgUid,
3458                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3459            }
3460        } finally {
3461            Binder.restoreCallingIdentity(callingId);
3462        }
3463    }
3464
3465    public void killAllBackgroundProcesses() {
3466        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3467                != PackageManager.PERMISSION_GRANTED) {
3468            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3469                    + Binder.getCallingPid()
3470                    + ", uid=" + Binder.getCallingUid()
3471                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3472            Slog.w(TAG, msg);
3473            throw new SecurityException(msg);
3474        }
3475
3476        long callingId = Binder.clearCallingIdentity();
3477        try {
3478            synchronized(this) {
3479                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3480                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3481                    final int NA = apps.size();
3482                    for (int ia=0; ia<NA; ia++) {
3483                        ProcessRecord app = apps.valueAt(ia);
3484                        if (app.persistent) {
3485                            // we don't kill persistent processes
3486                            continue;
3487                        }
3488                        if (app.removed) {
3489                            procs.add(app);
3490                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3491                            app.removed = true;
3492                            procs.add(app);
3493                        }
3494                    }
3495                }
3496
3497                int N = procs.size();
3498                for (int i=0; i<N; i++) {
3499                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3500                }
3501            }
3502        } finally {
3503            Binder.restoreCallingIdentity(callingId);
3504        }
3505    }
3506
3507    public void forceStopPackage(final String packageName) {
3508        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3509                != PackageManager.PERMISSION_GRANTED) {
3510            String msg = "Permission Denial: forceStopPackage() from pid="
3511                    + Binder.getCallingPid()
3512                    + ", uid=" + Binder.getCallingUid()
3513                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3514            Slog.w(TAG, msg);
3515            throw new SecurityException(msg);
3516        }
3517        final int userId = UserHandle.getCallingUserId();
3518        long callingId = Binder.clearCallingIdentity();
3519        try {
3520            IPackageManager pm = AppGlobals.getPackageManager();
3521            int pkgUid = -1;
3522            synchronized(this) {
3523                try {
3524                    pkgUid = pm.getPackageUid(packageName, userId);
3525                } catch (RemoteException e) {
3526                }
3527                if (pkgUid == -1) {
3528                    Slog.w(TAG, "Invalid packageName: " + packageName);
3529                    return;
3530                }
3531                forceStopPackageLocked(packageName, pkgUid);
3532                try {
3533                    pm.setPackageStoppedState(packageName, true, userId);
3534                } catch (RemoteException e) {
3535                } catch (IllegalArgumentException e) {
3536                    Slog.w(TAG, "Failed trying to unstop package "
3537                            + packageName + ": " + e);
3538                }
3539            }
3540        } finally {
3541            Binder.restoreCallingIdentity(callingId);
3542        }
3543    }
3544
3545    /*
3546     * The pkg name and uid have to be specified.
3547     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3548     */
3549    public void killApplicationWithUid(String pkg, int uid) {
3550        if (pkg == null) {
3551            return;
3552        }
3553        // Make sure the uid is valid.
3554        if (uid < 0) {
3555            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3556            return;
3557        }
3558        int callerUid = Binder.getCallingUid();
3559        // Only the system server can kill an application
3560        if (callerUid == Process.SYSTEM_UID) {
3561            // Post an aysnc message to kill the application
3562            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3563            msg.arg1 = uid;
3564            msg.arg2 = 0;
3565            msg.obj = pkg;
3566            mHandler.sendMessage(msg);
3567        } else {
3568            throw new SecurityException(callerUid + " cannot kill pkg: " +
3569                    pkg);
3570        }
3571    }
3572
3573    public void closeSystemDialogs(String reason) {
3574        enforceNotIsolatedCaller("closeSystemDialogs");
3575
3576        final int uid = Binder.getCallingUid();
3577        final long origId = Binder.clearCallingIdentity();
3578        synchronized (this) {
3579            closeSystemDialogsLocked(uid, reason);
3580        }
3581        Binder.restoreCallingIdentity(origId);
3582    }
3583
3584    void closeSystemDialogsLocked(int callingUid, String reason) {
3585        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3586        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3587        if (reason != null) {
3588            intent.putExtra("reason", reason);
3589        }
3590        mWindowManager.closeSystemDialogs(reason);
3591
3592        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3593            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3594            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3595                r.stack.finishActivityLocked(r, i,
3596                        Activity.RESULT_CANCELED, null, "close-sys");
3597            }
3598        }
3599
3600        broadcastIntentLocked(null, null, intent, null,
3601                null, 0, null, null, null, false, false, -1,
3602                callingUid, 0 /* TODO: Verify */);
3603    }
3604
3605    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3606            throws RemoteException {
3607        enforceNotIsolatedCaller("getProcessMemoryInfo");
3608        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3609        for (int i=pids.length-1; i>=0; i--) {
3610            infos[i] = new Debug.MemoryInfo();
3611            Debug.getMemoryInfo(pids[i], infos[i]);
3612        }
3613        return infos;
3614    }
3615
3616    public long[] getProcessPss(int[] pids) throws RemoteException {
3617        enforceNotIsolatedCaller("getProcessPss");
3618        long[] pss = new long[pids.length];
3619        for (int i=pids.length-1; i>=0; i--) {
3620            pss[i] = Debug.getPss(pids[i]);
3621        }
3622        return pss;
3623    }
3624
3625    public void killApplicationProcess(String processName, int uid) {
3626        if (processName == null) {
3627            return;
3628        }
3629
3630        int callerUid = Binder.getCallingUid();
3631        // Only the system server can kill an application
3632        if (callerUid == Process.SYSTEM_UID) {
3633            synchronized (this) {
3634                ProcessRecord app = getProcessRecordLocked(processName, uid);
3635                if (app != null && app.thread != null) {
3636                    try {
3637                        app.thread.scheduleSuicide();
3638                    } catch (RemoteException e) {
3639                        // If the other end already died, then our work here is done.
3640                    }
3641                } else {
3642                    Slog.w(TAG, "Process/uid not found attempting kill of "
3643                            + processName + " / " + uid);
3644                }
3645            }
3646        } else {
3647            throw new SecurityException(callerUid + " cannot kill app process: " +
3648                    processName);
3649        }
3650    }
3651
3652    private void forceStopPackageLocked(final String packageName, int uid) {
3653        forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
3654        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3655                Uri.fromParts("package", packageName, null));
3656        if (!mProcessesReady) {
3657            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3658        }
3659        intent.putExtra(Intent.EXTRA_UID, uid);
3660        broadcastIntentLocked(null, null, intent,
3661                null, null, 0, null, null, null,
3662                false, false,
3663                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3664    }
3665
3666    private final boolean killPackageProcessesLocked(String packageName, int uid,
3667            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3668            boolean evenPersistent, String reason) {
3669        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3670
3671        // Remove all processes this package may have touched: all with the
3672        // same UID (except for the system or root user), and all whose name
3673        // matches the package name.
3674        final String procNamePrefix = packageName + ":";
3675        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3676            final int NA = apps.size();
3677            for (int ia=0; ia<NA; ia++) {
3678                ProcessRecord app = apps.valueAt(ia);
3679                if (app.persistent && !evenPersistent) {
3680                    // we don't kill persistent processes
3681                    continue;
3682                }
3683                if (app.removed) {
3684                    if (doit) {
3685                        procs.add(app);
3686                    }
3687                // If uid is specified and the uid and process name match
3688                // Or, the uid is not specified and the process name matches
3689                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3690                            || ((app.processName.equals(packageName)
3691                                 || app.processName.startsWith(procNamePrefix))
3692                                && uid < 0))) {
3693                    if (app.setAdj >= minOomAdj) {
3694                        if (!doit) {
3695                            return true;
3696                        }
3697                        app.removed = true;
3698                        procs.add(app);
3699                    }
3700                }
3701            }
3702        }
3703
3704        int N = procs.size();
3705        for (int i=0; i<N; i++) {
3706            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3707        }
3708        return N > 0;
3709    }
3710
3711    private final boolean forceStopPackageLocked(String name, int uid,
3712            boolean callerWillRestart, boolean purgeCache, boolean doit,
3713            boolean evenPersistent, int userId) {
3714        int i;
3715        int N;
3716
3717        if (uid < 0) {
3718            try {
3719                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3720            } catch (RemoteException e) {
3721            }
3722        }
3723
3724        if (doit) {
3725            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3726
3727            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3728            while (badApps.hasNext()) {
3729                SparseArray<Long> ba = badApps.next();
3730                if (ba.get(uid) != null) {
3731                    badApps.remove();
3732                }
3733            }
3734        }
3735
3736        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3737                callerWillRestart, false, doit, evenPersistent, "force stop");
3738
3739        TaskRecord lastTask = null;
3740        for (i=0; i<mMainStack.mHistory.size(); i++) {
3741            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3742            final boolean samePackage = r.packageName.equals(name);
3743            if (r.userId == userId
3744                    && (samePackage || r.task == lastTask)
3745                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3746                if (!doit) {
3747                    if (r.finishing) {
3748                        // If this activity is just finishing, then it is not
3749                        // interesting as far as something to stop.
3750                        continue;
3751                    }
3752                    return true;
3753                }
3754                didSomething = true;
3755                Slog.i(TAG, "  Force finishing activity " + r);
3756                if (samePackage) {
3757                    if (r.app != null) {
3758                        r.app.removed = true;
3759                    }
3760                    r.app = null;
3761                }
3762                lastTask = r.task;
3763                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3764                        null, "force-stop", true)) {
3765                    i--;
3766                }
3767            }
3768        }
3769
3770        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3771            if (!doit) {
3772                return true;
3773            }
3774            didSomething = true;
3775        }
3776
3777        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3778        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3779            if (provider.info.packageName.equals(name)
3780                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3781                if (!doit) {
3782                    return true;
3783                }
3784                didSomething = true;
3785                providers.add(provider);
3786            }
3787        }
3788
3789        N = providers.size();
3790        for (i=0; i<N; i++) {
3791            removeDyingProviderLocked(null, providers.get(i), true);
3792        }
3793
3794        if (doit) {
3795            if (purgeCache) {
3796                AttributeCache ac = AttributeCache.instance();
3797                if (ac != null) {
3798                    ac.removePackage(name);
3799                }
3800            }
3801            if (mBooted) {
3802                mMainStack.resumeTopActivityLocked(null);
3803                mMainStack.scheduleIdleLocked();
3804            }
3805        }
3806
3807        return didSomething;
3808    }
3809
3810    private final boolean removeProcessLocked(ProcessRecord app,
3811            boolean callerWillRestart, boolean allowRestart, String reason) {
3812        final String name = app.processName;
3813        final int uid = app.uid;
3814        if (DEBUG_PROCESSES) Slog.d(
3815            TAG, "Force removing proc " + app.toShortString() + " (" + name
3816            + "/" + uid + ")");
3817
3818        mProcessNames.remove(name, uid);
3819        mIsolatedProcesses.remove(app.uid);
3820        if (mHeavyWeightProcess == app) {
3821            mHeavyWeightProcess = null;
3822            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3823        }
3824        boolean needRestart = false;
3825        if (app.pid > 0 && app.pid != MY_PID) {
3826            int pid = app.pid;
3827            synchronized (mPidsSelfLocked) {
3828                mPidsSelfLocked.remove(pid);
3829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3830            }
3831            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3832            handleAppDiedLocked(app, true, allowRestart);
3833            mLruProcesses.remove(app);
3834            Process.killProcessQuiet(pid);
3835
3836            if (app.persistent && !app.isolated) {
3837                if (!callerWillRestart) {
3838                    addAppLocked(app.info, false);
3839                } else {
3840                    needRestart = true;
3841                }
3842            }
3843        } else {
3844            mRemovedProcesses.add(app);
3845        }
3846
3847        return needRestart;
3848    }
3849
3850    private final void processStartTimedOutLocked(ProcessRecord app) {
3851        final int pid = app.pid;
3852        boolean gone = false;
3853        synchronized (mPidsSelfLocked) {
3854            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3855            if (knownApp != null && knownApp.thread == null) {
3856                mPidsSelfLocked.remove(pid);
3857                gone = true;
3858            }
3859        }
3860
3861        if (gone) {
3862            Slog.w(TAG, "Process " + app + " failed to attach");
3863            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3864                    app.processName);
3865            mProcessNames.remove(app.processName, app.uid);
3866            mIsolatedProcesses.remove(app.uid);
3867            if (mHeavyWeightProcess == app) {
3868                mHeavyWeightProcess = null;
3869                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3870            }
3871            // Take care of any launching providers waiting for this process.
3872            checkAppInLaunchingProvidersLocked(app, true);
3873            // Take care of any services that are waiting for the process.
3874            mServices.processStartTimedOutLocked(app);
3875            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3876                    app.processName, app.setAdj, "start timeout");
3877            Process.killProcessQuiet(pid);
3878            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3879                Slog.w(TAG, "Unattached app died before backup, skipping");
3880                try {
3881                    IBackupManager bm = IBackupManager.Stub.asInterface(
3882                            ServiceManager.getService(Context.BACKUP_SERVICE));
3883                    bm.agentDisconnected(app.info.packageName);
3884                } catch (RemoteException e) {
3885                    // Can't happen; the backup manager is local
3886                }
3887            }
3888            if (isPendingBroadcastProcessLocked(pid)) {
3889                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3890                skipPendingBroadcastLocked(pid);
3891            }
3892        } else {
3893            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3894        }
3895    }
3896
3897    private final boolean attachApplicationLocked(IApplicationThread thread,
3898            int pid) {
3899
3900        // Find the application record that is being attached...  either via
3901        // the pid if we are running in multiple processes, or just pull the
3902        // next app record if we are emulating process with anonymous threads.
3903        ProcessRecord app;
3904        if (pid != MY_PID && pid >= 0) {
3905            synchronized (mPidsSelfLocked) {
3906                app = mPidsSelfLocked.get(pid);
3907            }
3908        } else {
3909            app = null;
3910        }
3911
3912        if (app == null) {
3913            Slog.w(TAG, "No pending application record for pid " + pid
3914                    + " (IApplicationThread " + thread + "); dropping process");
3915            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3916            if (pid > 0 && pid != MY_PID) {
3917                Process.killProcessQuiet(pid);
3918            } else {
3919                try {
3920                    thread.scheduleExit();
3921                } catch (Exception e) {
3922                    // Ignore exceptions.
3923                }
3924            }
3925            return false;
3926        }
3927
3928        // If this application record is still attached to a previous
3929        // process, clean it up now.
3930        if (app.thread != null) {
3931            handleAppDiedLocked(app, true, true);
3932        }
3933
3934        // Tell the process all about itself.
3935
3936        if (localLOGV) Slog.v(
3937                TAG, "Binding process pid " + pid + " to record " + app);
3938
3939        String processName = app.processName;
3940        try {
3941            AppDeathRecipient adr = new AppDeathRecipient(
3942                    app, pid, thread);
3943            thread.asBinder().linkToDeath(adr, 0);
3944            app.deathRecipient = adr;
3945        } catch (RemoteException e) {
3946            app.resetPackageList();
3947            startProcessLocked(app, "link fail", processName);
3948            return false;
3949        }
3950
3951        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3952
3953        app.thread = thread;
3954        app.curAdj = app.setAdj = -100;
3955        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3956        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3957        app.forcingToForeground = null;
3958        app.foregroundServices = false;
3959        app.hasShownUi = false;
3960        app.debugging = false;
3961
3962        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3963
3964        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3965        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3966
3967        if (!normalMode) {
3968            Slog.i(TAG, "Launching preboot mode app: " + app);
3969        }
3970
3971        if (localLOGV) Slog.v(
3972            TAG, "New app record " + app
3973            + " thread=" + thread.asBinder() + " pid=" + pid);
3974        try {
3975            int testMode = IApplicationThread.DEBUG_OFF;
3976            if (mDebugApp != null && mDebugApp.equals(processName)) {
3977                testMode = mWaitForDebugger
3978                    ? IApplicationThread.DEBUG_WAIT
3979                    : IApplicationThread.DEBUG_ON;
3980                app.debugging = true;
3981                if (mDebugTransient) {
3982                    mDebugApp = mOrigDebugApp;
3983                    mWaitForDebugger = mOrigWaitForDebugger;
3984                }
3985            }
3986            String profileFile = app.instrumentationProfileFile;
3987            ParcelFileDescriptor profileFd = null;
3988            boolean profileAutoStop = false;
3989            if (mProfileApp != null && mProfileApp.equals(processName)) {
3990                mProfileProc = app;
3991                profileFile = mProfileFile;
3992                profileFd = mProfileFd;
3993                profileAutoStop = mAutoStopProfiler;
3994            }
3995            boolean enableOpenGlTrace = false;
3996            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3997                enableOpenGlTrace = true;
3998                mOpenGlTraceApp = null;
3999            }
4000
4001            // If the app is being launched for restore or full backup, set it up specially
4002            boolean isRestrictedBackupMode = false;
4003            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4004                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4005                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4006                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4007            }
4008
4009            ensurePackageDexOpt(app.instrumentationInfo != null
4010                    ? app.instrumentationInfo.packageName
4011                    : app.info.packageName);
4012            if (app.instrumentationClass != null) {
4013                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4014            }
4015            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4016                    + processName + " with config " + mConfiguration);
4017            ApplicationInfo appInfo = app.instrumentationInfo != null
4018                    ? app.instrumentationInfo : app.info;
4019            app.compat = compatibilityInfoForPackageLocked(appInfo);
4020            if (profileFd != null) {
4021                profileFd = profileFd.dup();
4022            }
4023            thread.bindApplication(processName, appInfo, providers,
4024                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4025                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4026                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4027                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4028                    mCoreSettingsObserver.getCoreSettingsLocked());
4029            updateLruProcessLocked(app, false, true);
4030            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4031        } catch (Exception e) {
4032            // todo: Yikes!  What should we do?  For now we will try to
4033            // start another process, but that could easily get us in
4034            // an infinite loop of restarting processes...
4035            Slog.w(TAG, "Exception thrown during bind!", e);
4036
4037            app.resetPackageList();
4038            app.unlinkDeathRecipient();
4039            startProcessLocked(app, "bind fail", processName);
4040            return false;
4041        }
4042
4043        // Remove this record from the list of starting applications.
4044        mPersistentStartingProcesses.remove(app);
4045        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4046                "Attach application locked removing on hold: " + app);
4047        mProcessesOnHold.remove(app);
4048
4049        boolean badApp = false;
4050        boolean didSomething = false;
4051
4052        // See if the top visible activity is waiting to run in this process...
4053        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4054        if (hr != null && normalMode) {
4055            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4056                    && processName.equals(hr.processName)) {
4057                try {
4058                    if (mHeadless) {
4059                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4060                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4061                        didSomething = true;
4062                    }
4063                } catch (Exception e) {
4064                    Slog.w(TAG, "Exception in new application when starting activity "
4065                          + hr.intent.getComponent().flattenToShortString(), e);
4066                    badApp = true;
4067                }
4068            } else {
4069                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4070            }
4071        }
4072
4073        // Find any services that should be running in this process...
4074        if (!badApp) {
4075            try {
4076                didSomething |= mServices.attachApplicationLocked(app, processName);
4077            } catch (Exception e) {
4078                badApp = true;
4079            }
4080        }
4081
4082        // Check if a next-broadcast receiver is in this process...
4083        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4084            try {
4085                didSomething = sendPendingBroadcastsLocked(app);
4086            } catch (Exception e) {
4087                // If the app died trying to launch the receiver we declare it 'bad'
4088                badApp = true;
4089            }
4090        }
4091
4092        // Check whether the next backup agent is in this process...
4093        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4094            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4095            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4096            try {
4097                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4098                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4099                        mBackupTarget.backupMode);
4100            } catch (Exception e) {
4101                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4102                e.printStackTrace();
4103            }
4104        }
4105
4106        if (badApp) {
4107            // todo: Also need to kill application to deal with all
4108            // kinds of exceptions.
4109            handleAppDiedLocked(app, false, true);
4110            return false;
4111        }
4112
4113        if (!didSomething) {
4114            updateOomAdjLocked();
4115        }
4116
4117        return true;
4118    }
4119
4120    public final void attachApplication(IApplicationThread thread) {
4121        synchronized (this) {
4122            int callingPid = Binder.getCallingPid();
4123            final long origId = Binder.clearCallingIdentity();
4124            attachApplicationLocked(thread, callingPid);
4125            Binder.restoreCallingIdentity(origId);
4126        }
4127    }
4128
4129    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4130        final long origId = Binder.clearCallingIdentity();
4131        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4132        if (stopProfiling) {
4133            synchronized (this) {
4134                if (mProfileProc == r.app) {
4135                    if (mProfileFd != null) {
4136                        try {
4137                            mProfileFd.close();
4138                        } catch (IOException e) {
4139                        }
4140                        clearProfilerLocked();
4141                    }
4142                }
4143            }
4144        }
4145        Binder.restoreCallingIdentity(origId);
4146    }
4147
4148    void enableScreenAfterBoot() {
4149        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4150                SystemClock.uptimeMillis());
4151        mWindowManager.enableScreenAfterBoot();
4152
4153        synchronized (this) {
4154            updateEventDispatchingLocked();
4155        }
4156    }
4157
4158    public void showBootMessage(final CharSequence msg, final boolean always) {
4159        enforceNotIsolatedCaller("showBootMessage");
4160        mWindowManager.showBootMessage(msg, always);
4161    }
4162
4163    public void dismissKeyguardOnNextActivity() {
4164        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4165        final long token = Binder.clearCallingIdentity();
4166        try {
4167            synchronized (this) {
4168                if (mLockScreenShown) {
4169                    mLockScreenShown = false;
4170                    comeOutOfSleepIfNeededLocked();
4171                }
4172                mMainStack.dismissKeyguardOnNextActivityLocked();
4173            }
4174        } finally {
4175            Binder.restoreCallingIdentity(token);
4176        }
4177    }
4178
4179    final void finishBooting() {
4180        IntentFilter pkgFilter = new IntentFilter();
4181        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4182        pkgFilter.addDataScheme("package");
4183        mContext.registerReceiver(new BroadcastReceiver() {
4184            @Override
4185            public void onReceive(Context context, Intent intent) {
4186                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4187                if (pkgs != null) {
4188                    for (String pkg : pkgs) {
4189                        synchronized (ActivityManagerService.this) {
4190                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4191                                setResultCode(Activity.RESULT_OK);
4192                                return;
4193                            }
4194                        }
4195                    }
4196                }
4197            }
4198        }, pkgFilter);
4199
4200        IntentFilter userFilter = new IntentFilter();
4201        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4202        mContext.registerReceiver(new BroadcastReceiver() {
4203            @Override
4204            public void onReceive(Context context, Intent intent) {
4205                onUserRemoved(intent);
4206            }
4207        }, userFilter);
4208
4209        synchronized (this) {
4210            // Ensure that any processes we had put on hold are now started
4211            // up.
4212            final int NP = mProcessesOnHold.size();
4213            if (NP > 0) {
4214                ArrayList<ProcessRecord> procs =
4215                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4216                for (int ip=0; ip<NP; ip++) {
4217                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4218                            + procs.get(ip));
4219                    startProcessLocked(procs.get(ip), "on-hold", null);
4220                }
4221            }
4222
4223            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4224                // Start looking for apps that are abusing wake locks.
4225                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4226                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4227                // Tell anyone interested that we are done booting!
4228                SystemProperties.set("sys.boot_completed", "1");
4229                SystemProperties.set("dev.bootcomplete", "1");
4230                List<UserInfo> users = getUserManager().getUsers();
4231                for (UserInfo user : users) {
4232                    broadcastIntentLocked(null, null,
4233                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4234                            null, null, 0, null, null,
4235                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4236                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4237                }
4238            }
4239        }
4240    }
4241
4242    final void ensureBootCompleted() {
4243        boolean booting;
4244        boolean enableScreen;
4245        synchronized (this) {
4246            booting = mBooting;
4247            mBooting = false;
4248            enableScreen = !mBooted;
4249            mBooted = true;
4250        }
4251
4252        if (booting) {
4253            finishBooting();
4254        }
4255
4256        if (enableScreen) {
4257            enableScreenAfterBoot();
4258        }
4259    }
4260
4261    public final void activityPaused(IBinder token) {
4262        final long origId = Binder.clearCallingIdentity();
4263        mMainStack.activityPaused(token, false);
4264        Binder.restoreCallingIdentity(origId);
4265    }
4266
4267    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4268            CharSequence description) {
4269        if (localLOGV) Slog.v(
4270            TAG, "Activity stopped: token=" + token);
4271
4272        // Refuse possible leaked file descriptors
4273        if (icicle != null && icicle.hasFileDescriptors()) {
4274            throw new IllegalArgumentException("File descriptors passed in Bundle");
4275        }
4276
4277        ActivityRecord r = null;
4278
4279        final long origId = Binder.clearCallingIdentity();
4280
4281        synchronized (this) {
4282            r = mMainStack.isInStackLocked(token);
4283            if (r != null) {
4284                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4285            }
4286        }
4287
4288        if (r != null) {
4289            sendPendingThumbnail(r, null, null, null, false);
4290        }
4291
4292        trimApplications();
4293
4294        Binder.restoreCallingIdentity(origId);
4295    }
4296
4297    public final void activityDestroyed(IBinder token) {
4298        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4299        mMainStack.activityDestroyed(token);
4300    }
4301
4302    public String getCallingPackage(IBinder token) {
4303        synchronized (this) {
4304            ActivityRecord r = getCallingRecordLocked(token);
4305            return r != null && r.app != null ? r.info.packageName : null;
4306        }
4307    }
4308
4309    public ComponentName getCallingActivity(IBinder token) {
4310        synchronized (this) {
4311            ActivityRecord r = getCallingRecordLocked(token);
4312            return r != null ? r.intent.getComponent() : null;
4313        }
4314    }
4315
4316    private ActivityRecord getCallingRecordLocked(IBinder token) {
4317        ActivityRecord r = mMainStack.isInStackLocked(token);
4318        if (r == null) {
4319            return null;
4320        }
4321        return r.resultTo;
4322    }
4323
4324    public ComponentName getActivityClassForToken(IBinder token) {
4325        synchronized(this) {
4326            ActivityRecord r = mMainStack.isInStackLocked(token);
4327            if (r == null) {
4328                return null;
4329            }
4330            return r.intent.getComponent();
4331        }
4332    }
4333
4334    public String getPackageForToken(IBinder token) {
4335        synchronized(this) {
4336            ActivityRecord r = mMainStack.isInStackLocked(token);
4337            if (r == null) {
4338                return null;
4339            }
4340            return r.packageName;
4341        }
4342    }
4343
4344    public IIntentSender getIntentSender(int type,
4345            String packageName, IBinder token, String resultWho,
4346            int requestCode, Intent[] intents, String[] resolvedTypes,
4347            int flags, Bundle options) {
4348        enforceNotIsolatedCaller("getIntentSender");
4349        // Refuse possible leaked file descriptors
4350        if (intents != null) {
4351            if (intents.length < 1) {
4352                throw new IllegalArgumentException("Intents array length must be >= 1");
4353            }
4354            for (int i=0; i<intents.length; i++) {
4355                Intent intent = intents[i];
4356                if (intent != null) {
4357                    if (intent.hasFileDescriptors()) {
4358                        throw new IllegalArgumentException("File descriptors passed in Intent");
4359                    }
4360                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4361                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4362                        throw new IllegalArgumentException(
4363                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4364                    }
4365                    intents[i] = new Intent(intent);
4366                }
4367            }
4368            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4369                throw new IllegalArgumentException(
4370                        "Intent array length does not match resolvedTypes length");
4371            }
4372        }
4373        if (options != null) {
4374            if (options.hasFileDescriptors()) {
4375                throw new IllegalArgumentException("File descriptors passed in options");
4376            }
4377        }
4378
4379        synchronized(this) {
4380            int callingUid = Binder.getCallingUid();
4381            try {
4382                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4383                    int uid = AppGlobals.getPackageManager()
4384                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4385                    if (!UserHandle.isSameApp(callingUid, uid)) {
4386                        String msg = "Permission Denial: getIntentSender() from pid="
4387                            + Binder.getCallingPid()
4388                            + ", uid=" + Binder.getCallingUid()
4389                            + ", (need uid=" + uid + ")"
4390                            + " is not allowed to send as package " + packageName;
4391                        Slog.w(TAG, msg);
4392                        throw new SecurityException(msg);
4393                    }
4394                }
4395
4396                if (DEBUG_MU)
4397                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4398                            + Binder.getOrigCallingUid());
4399                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4400                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4401
4402            } catch (RemoteException e) {
4403                throw new SecurityException(e);
4404            }
4405        }
4406    }
4407
4408    IIntentSender getIntentSenderLocked(int type,
4409            String packageName, int callingUid, IBinder token, String resultWho,
4410            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4411            Bundle options) {
4412        if (DEBUG_MU)
4413            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4414        ActivityRecord activity = null;
4415        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4416            activity = mMainStack.isInStackLocked(token);
4417            if (activity == null) {
4418                return null;
4419            }
4420            if (activity.finishing) {
4421                return null;
4422            }
4423        }
4424
4425        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4426        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4427        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4428        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4429                |PendingIntent.FLAG_UPDATE_CURRENT);
4430
4431        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4432                type, packageName, activity, resultWho,
4433                requestCode, intents, resolvedTypes, flags, options);
4434        WeakReference<PendingIntentRecord> ref;
4435        ref = mIntentSenderRecords.get(key);
4436        PendingIntentRecord rec = ref != null ? ref.get() : null;
4437        if (rec != null) {
4438            if (!cancelCurrent) {
4439                if (updateCurrent) {
4440                    if (rec.key.requestIntent != null) {
4441                        rec.key.requestIntent.replaceExtras(intents != null ?
4442                                intents[intents.length - 1] : null);
4443                    }
4444                    if (intents != null) {
4445                        intents[intents.length-1] = rec.key.requestIntent;
4446                        rec.key.allIntents = intents;
4447                        rec.key.allResolvedTypes = resolvedTypes;
4448                    } else {
4449                        rec.key.allIntents = null;
4450                        rec.key.allResolvedTypes = null;
4451                    }
4452                }
4453                return rec;
4454            }
4455            rec.canceled = true;
4456            mIntentSenderRecords.remove(key);
4457        }
4458        if (noCreate) {
4459            return rec;
4460        }
4461        rec = new PendingIntentRecord(this, key, callingUid);
4462        mIntentSenderRecords.put(key, rec.ref);
4463        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4464            if (activity.pendingResults == null) {
4465                activity.pendingResults
4466                        = new HashSet<WeakReference<PendingIntentRecord>>();
4467            }
4468            activity.pendingResults.add(rec.ref);
4469        }
4470        return rec;
4471    }
4472
4473    public void cancelIntentSender(IIntentSender sender) {
4474        if (!(sender instanceof PendingIntentRecord)) {
4475            return;
4476        }
4477        synchronized(this) {
4478            PendingIntentRecord rec = (PendingIntentRecord)sender;
4479            try {
4480                int uid = AppGlobals.getPackageManager()
4481                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4482                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4483                    String msg = "Permission Denial: cancelIntentSender() from pid="
4484                        + Binder.getCallingPid()
4485                        + ", uid=" + Binder.getCallingUid()
4486                        + " is not allowed to cancel packges "
4487                        + rec.key.packageName;
4488                    Slog.w(TAG, msg);
4489                    throw new SecurityException(msg);
4490                }
4491            } catch (RemoteException e) {
4492                throw new SecurityException(e);
4493            }
4494            cancelIntentSenderLocked(rec, true);
4495        }
4496    }
4497
4498    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4499        rec.canceled = true;
4500        mIntentSenderRecords.remove(rec.key);
4501        if (cleanActivity && rec.key.activity != null) {
4502            rec.key.activity.pendingResults.remove(rec.ref);
4503        }
4504    }
4505
4506    public String getPackageForIntentSender(IIntentSender pendingResult) {
4507        if (!(pendingResult instanceof PendingIntentRecord)) {
4508            return null;
4509        }
4510        try {
4511            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4512            return res.key.packageName;
4513        } catch (ClassCastException e) {
4514        }
4515        return null;
4516    }
4517
4518    public int getUidForIntentSender(IIntentSender sender) {
4519        if (sender instanceof PendingIntentRecord) {
4520            try {
4521                PendingIntentRecord res = (PendingIntentRecord)sender;
4522                return res.uid;
4523            } catch (ClassCastException e) {
4524            }
4525        }
4526        return -1;
4527    }
4528
4529    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4530        if (!(pendingResult instanceof PendingIntentRecord)) {
4531            return false;
4532        }
4533        try {
4534            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4535            if (res.key.allIntents == null) {
4536                return false;
4537            }
4538            for (int i=0; i<res.key.allIntents.length; i++) {
4539                Intent intent = res.key.allIntents[i];
4540                if (intent.getPackage() != null && intent.getComponent() != null) {
4541                    return false;
4542                }
4543            }
4544            return true;
4545        } catch (ClassCastException e) {
4546        }
4547        return false;
4548    }
4549
4550    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4551        if (!(pendingResult instanceof PendingIntentRecord)) {
4552            return false;
4553        }
4554        try {
4555            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4556            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4557                return true;
4558            }
4559            return false;
4560        } catch (ClassCastException e) {
4561        }
4562        return false;
4563    }
4564
4565    public void setProcessLimit(int max) {
4566        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4567                "setProcessLimit()");
4568        synchronized (this) {
4569            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4570            mProcessLimitOverride = max;
4571        }
4572        trimApplications();
4573    }
4574
4575    public int getProcessLimit() {
4576        synchronized (this) {
4577            return mProcessLimitOverride;
4578        }
4579    }
4580
4581    void foregroundTokenDied(ForegroundToken token) {
4582        synchronized (ActivityManagerService.this) {
4583            synchronized (mPidsSelfLocked) {
4584                ForegroundToken cur
4585                    = mForegroundProcesses.get(token.pid);
4586                if (cur != token) {
4587                    return;
4588                }
4589                mForegroundProcesses.remove(token.pid);
4590                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4591                if (pr == null) {
4592                    return;
4593                }
4594                pr.forcingToForeground = null;
4595                pr.foregroundServices = false;
4596            }
4597            updateOomAdjLocked();
4598        }
4599    }
4600
4601    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4602        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4603                "setProcessForeground()");
4604        synchronized(this) {
4605            boolean changed = false;
4606
4607            synchronized (mPidsSelfLocked) {
4608                ProcessRecord pr = mPidsSelfLocked.get(pid);
4609                if (pr == null && isForeground) {
4610                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4611                    return;
4612                }
4613                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4614                if (oldToken != null) {
4615                    oldToken.token.unlinkToDeath(oldToken, 0);
4616                    mForegroundProcesses.remove(pid);
4617                    if (pr != null) {
4618                        pr.forcingToForeground = null;
4619                    }
4620                    changed = true;
4621                }
4622                if (isForeground && token != null) {
4623                    ForegroundToken newToken = new ForegroundToken() {
4624                        public void binderDied() {
4625                            foregroundTokenDied(this);
4626                        }
4627                    };
4628                    newToken.pid = pid;
4629                    newToken.token = token;
4630                    try {
4631                        token.linkToDeath(newToken, 0);
4632                        mForegroundProcesses.put(pid, newToken);
4633                        pr.forcingToForeground = token;
4634                        changed = true;
4635                    } catch (RemoteException e) {
4636                        // If the process died while doing this, we will later
4637                        // do the cleanup with the process death link.
4638                    }
4639                }
4640            }
4641
4642            if (changed) {
4643                updateOomAdjLocked();
4644            }
4645        }
4646    }
4647
4648    // =========================================================
4649    // PERMISSIONS
4650    // =========================================================
4651
4652    static class PermissionController extends IPermissionController.Stub {
4653        ActivityManagerService mActivityManagerService;
4654        PermissionController(ActivityManagerService activityManagerService) {
4655            mActivityManagerService = activityManagerService;
4656        }
4657
4658        public boolean checkPermission(String permission, int pid, int uid) {
4659            return mActivityManagerService.checkPermission(permission, pid,
4660                    uid) == PackageManager.PERMISSION_GRANTED;
4661        }
4662    }
4663
4664    /**
4665     * This can be called with or without the global lock held.
4666     */
4667    int checkComponentPermission(String permission, int pid, int uid,
4668            int owningUid, boolean exported) {
4669        // We might be performing an operation on behalf of an indirect binder
4670        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4671        // client identity accordingly before proceeding.
4672        Identity tlsIdentity = sCallerIdentity.get();
4673        if (tlsIdentity != null) {
4674            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4675                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4676            uid = tlsIdentity.uid;
4677            pid = tlsIdentity.pid;
4678        }
4679
4680        if (pid == MY_PID) {
4681            return PackageManager.PERMISSION_GRANTED;
4682        }
4683
4684        return ActivityManager.checkComponentPermission(permission, uid,
4685                owningUid, exported);
4686    }
4687
4688    /**
4689     * As the only public entry point for permissions checking, this method
4690     * can enforce the semantic that requesting a check on a null global
4691     * permission is automatically denied.  (Internally a null permission
4692     * string is used when calling {@link #checkComponentPermission} in cases
4693     * when only uid-based security is needed.)
4694     *
4695     * This can be called with or without the global lock held.
4696     */
4697    public int checkPermission(String permission, int pid, int uid) {
4698        if (permission == null) {
4699            return PackageManager.PERMISSION_DENIED;
4700        }
4701        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4702    }
4703
4704    /**
4705     * Binder IPC calls go through the public entry point.
4706     * This can be called with or without the global lock held.
4707     */
4708    int checkCallingPermission(String permission) {
4709        return checkPermission(permission,
4710                Binder.getCallingPid(),
4711                UserHandle.getAppId(Binder.getCallingUid()));
4712    }
4713
4714    /**
4715     * This can be called with or without the global lock held.
4716     */
4717    void enforceCallingPermission(String permission, String func) {
4718        if (checkCallingPermission(permission)
4719                == PackageManager.PERMISSION_GRANTED) {
4720            return;
4721        }
4722
4723        String msg = "Permission Denial: " + func + " from pid="
4724                + Binder.getCallingPid()
4725                + ", uid=" + Binder.getCallingUid()
4726                + " requires " + permission;
4727        Slog.w(TAG, msg);
4728        throw new SecurityException(msg);
4729    }
4730
4731    /**
4732     * Determine if UID is holding permissions required to access {@link Uri} in
4733     * the given {@link ProviderInfo}. Final permission checking is always done
4734     * in {@link ContentProvider}.
4735     */
4736    private final boolean checkHoldingPermissionsLocked(
4737            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4738        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4739                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4740
4741        if (pi.applicationInfo.uid == uid) {
4742            return true;
4743        } else if (!pi.exported) {
4744            return false;
4745        }
4746
4747        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4748        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4749        try {
4750            // check if target holds top-level <provider> permissions
4751            if (!readMet && pi.readPermission != null
4752                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4753                readMet = true;
4754            }
4755            if (!writeMet && pi.writePermission != null
4756                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4757                writeMet = true;
4758            }
4759
4760            // track if unprotected read/write is allowed; any denied
4761            // <path-permission> below removes this ability
4762            boolean allowDefaultRead = pi.readPermission == null;
4763            boolean allowDefaultWrite = pi.writePermission == null;
4764
4765            // check if target holds any <path-permission> that match uri
4766            final PathPermission[] pps = pi.pathPermissions;
4767            if (pps != null) {
4768                final String path = uri.getPath();
4769                int i = pps.length;
4770                while (i > 0 && (!readMet || !writeMet)) {
4771                    i--;
4772                    PathPermission pp = pps[i];
4773                    if (pp.match(path)) {
4774                        if (!readMet) {
4775                            final String pprperm = pp.getReadPermission();
4776                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4777                                    + pprperm + " for " + pp.getPath()
4778                                    + ": match=" + pp.match(path)
4779                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4780                            if (pprperm != null) {
4781                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4782                                    readMet = true;
4783                                } else {
4784                                    allowDefaultRead = false;
4785                                }
4786                            }
4787                        }
4788                        if (!writeMet) {
4789                            final String ppwperm = pp.getWritePermission();
4790                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4791                                    + ppwperm + " for " + pp.getPath()
4792                                    + ": match=" + pp.match(path)
4793                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4794                            if (ppwperm != null) {
4795                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4796                                    writeMet = true;
4797                                } else {
4798                                    allowDefaultWrite = false;
4799                                }
4800                            }
4801                        }
4802                    }
4803                }
4804            }
4805
4806            // grant unprotected <provider> read/write, if not blocked by
4807            // <path-permission> above
4808            if (allowDefaultRead) readMet = true;
4809            if (allowDefaultWrite) writeMet = true;
4810
4811        } catch (RemoteException e) {
4812            return false;
4813        }
4814
4815        return readMet && writeMet;
4816    }
4817
4818    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4819            int modeFlags) {
4820        // Root gets to do everything.
4821        if (uid == 0) {
4822            return true;
4823        }
4824        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4825        if (perms == null) return false;
4826        UriPermission perm = perms.get(uri);
4827        if (perm == null) return false;
4828        return (modeFlags&perm.modeFlags) == modeFlags;
4829    }
4830
4831    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4832        enforceNotIsolatedCaller("checkUriPermission");
4833
4834        // Another redirected-binder-call permissions check as in
4835        // {@link checkComponentPermission}.
4836        Identity tlsIdentity = sCallerIdentity.get();
4837        if (tlsIdentity != null) {
4838            uid = tlsIdentity.uid;
4839            pid = tlsIdentity.pid;
4840        }
4841
4842        uid = UserHandle.getAppId(uid);
4843        // Our own process gets to do everything.
4844        if (pid == MY_PID) {
4845            return PackageManager.PERMISSION_GRANTED;
4846        }
4847        synchronized(this) {
4848            return checkUriPermissionLocked(uri, uid, modeFlags)
4849                    ? PackageManager.PERMISSION_GRANTED
4850                    : PackageManager.PERMISSION_DENIED;
4851        }
4852    }
4853
4854    /**
4855     * Check if the targetPkg can be granted permission to access uri by
4856     * the callingUid using the given modeFlags.  Throws a security exception
4857     * if callingUid is not allowed to do this.  Returns the uid of the target
4858     * if the URI permission grant should be performed; returns -1 if it is not
4859     * needed (for example targetPkg already has permission to access the URI).
4860     * If you already know the uid of the target, you can supply it in
4861     * lastTargetUid else set that to -1.
4862     */
4863    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4864            Uri uri, int modeFlags, int lastTargetUid) {
4865        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4866                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4867        if (modeFlags == 0) {
4868            return -1;
4869        }
4870
4871        if (targetPkg != null) {
4872            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4873                    "Checking grant " + targetPkg + " permission to " + uri);
4874        }
4875
4876        final IPackageManager pm = AppGlobals.getPackageManager();
4877
4878        // If this is not a content: uri, we can't do anything with it.
4879        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4880            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4881                    "Can't grant URI permission for non-content URI: " + uri);
4882            return -1;
4883        }
4884
4885        String name = uri.getAuthority();
4886        ProviderInfo pi = null;
4887        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4888                UserHandle.getUserId(callingUid));
4889        if (cpr != null) {
4890            pi = cpr.info;
4891        } else {
4892            try {
4893                pi = pm.resolveContentProvider(name,
4894                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4895            } catch (RemoteException ex) {
4896            }
4897        }
4898        if (pi == null) {
4899            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4900            return -1;
4901        }
4902
4903        int targetUid = lastTargetUid;
4904        if (targetUid < 0 && targetPkg != null) {
4905            try {
4906                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4907                if (targetUid < 0) {
4908                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4909                            "Can't grant URI permission no uid for: " + targetPkg);
4910                    return -1;
4911                }
4912            } catch (RemoteException ex) {
4913                return -1;
4914            }
4915        }
4916
4917        if (targetUid >= 0) {
4918            // First...  does the target actually need this permission?
4919            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4920                // No need to grant the target this permission.
4921                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4922                        "Target " + targetPkg + " already has full permission to " + uri);
4923                return -1;
4924            }
4925        } else {
4926            // First...  there is no target package, so can anyone access it?
4927            boolean allowed = pi.exported;
4928            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4929                if (pi.readPermission != null) {
4930                    allowed = false;
4931                }
4932            }
4933            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4934                if (pi.writePermission != null) {
4935                    allowed = false;
4936                }
4937            }
4938            if (allowed) {
4939                return -1;
4940            }
4941        }
4942
4943        // Second...  is the provider allowing granting of URI permissions?
4944        if (!pi.grantUriPermissions) {
4945            throw new SecurityException("Provider " + pi.packageName
4946                    + "/" + pi.name
4947                    + " does not allow granting of Uri permissions (uri "
4948                    + uri + ")");
4949        }
4950        if (pi.uriPermissionPatterns != null) {
4951            final int N = pi.uriPermissionPatterns.length;
4952            boolean allowed = false;
4953            for (int i=0; i<N; i++) {
4954                if (pi.uriPermissionPatterns[i] != null
4955                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4956                    allowed = true;
4957                    break;
4958                }
4959            }
4960            if (!allowed) {
4961                throw new SecurityException("Provider " + pi.packageName
4962                        + "/" + pi.name
4963                        + " does not allow granting of permission to path of Uri "
4964                        + uri);
4965            }
4966        }
4967
4968        // Third...  does the caller itself have permission to access
4969        // this uri?
4970        if (callingUid != Process.myUid()) {
4971            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4972                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4973                    throw new SecurityException("Uid " + callingUid
4974                            + " does not have permission to uri " + uri);
4975                }
4976            }
4977        }
4978
4979        return targetUid;
4980    }
4981
4982    public int checkGrantUriPermission(int callingUid, String targetPkg,
4983            Uri uri, int modeFlags) {
4984        enforceNotIsolatedCaller("checkGrantUriPermission");
4985        synchronized(this) {
4986            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4987        }
4988    }
4989
4990    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4991            Uri uri, int modeFlags, UriPermissionOwner owner) {
4992        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4993                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4994        if (modeFlags == 0) {
4995            return;
4996        }
4997
4998        // So here we are: the caller has the assumed permission
4999        // to the uri, and the target doesn't.  Let's now give this to
5000        // the target.
5001
5002        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5003                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5004
5005        HashMap<Uri, UriPermission> targetUris
5006                = mGrantedUriPermissions.get(targetUid);
5007        if (targetUris == null) {
5008            targetUris = new HashMap<Uri, UriPermission>();
5009            mGrantedUriPermissions.put(targetUid, targetUris);
5010        }
5011
5012        UriPermission perm = targetUris.get(uri);
5013        if (perm == null) {
5014            perm = new UriPermission(targetUid, uri);
5015            targetUris.put(uri, perm);
5016        }
5017
5018        perm.modeFlags |= modeFlags;
5019        if (owner == null) {
5020            perm.globalModeFlags |= modeFlags;
5021        } else {
5022            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5023                 perm.readOwners.add(owner);
5024                 owner.addReadPermission(perm);
5025            }
5026            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5027                 perm.writeOwners.add(owner);
5028                 owner.addWritePermission(perm);
5029            }
5030        }
5031    }
5032
5033    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5034            int modeFlags, UriPermissionOwner owner) {
5035        if (targetPkg == null) {
5036            throw new NullPointerException("targetPkg");
5037        }
5038
5039        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5040        if (targetUid < 0) {
5041            return;
5042        }
5043
5044        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5045    }
5046
5047    static class NeededUriGrants extends ArrayList<Uri> {
5048        final String targetPkg;
5049        final int targetUid;
5050        final int flags;
5051
5052        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5053            targetPkg = _targetPkg;
5054            targetUid = _targetUid;
5055            flags = _flags;
5056        }
5057    }
5058
5059    /**
5060     * Like checkGrantUriPermissionLocked, but takes an Intent.
5061     */
5062    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5063            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5064        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5065                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5066                + " clip=" + (intent != null ? intent.getClipData() : null)
5067                + " from " + intent + "; flags=0x"
5068                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5069
5070        if (targetPkg == null) {
5071            throw new NullPointerException("targetPkg");
5072        }
5073
5074        if (intent == null) {
5075            return null;
5076        }
5077        Uri data = intent.getData();
5078        ClipData clip = intent.getClipData();
5079        if (data == null && clip == null) {
5080            return null;
5081        }
5082        if (data != null) {
5083            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5084                mode, needed != null ? needed.targetUid : -1);
5085            if (target > 0) {
5086                if (needed == null) {
5087                    needed = new NeededUriGrants(targetPkg, target, mode);
5088                }
5089                needed.add(data);
5090            }
5091        }
5092        if (clip != null) {
5093            for (int i=0; i<clip.getItemCount(); i++) {
5094                Uri uri = clip.getItemAt(i).getUri();
5095                if (uri != null) {
5096                    int target = -1;
5097                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5098                            mode, needed != null ? needed.targetUid : -1);
5099                    if (target > 0) {
5100                        if (needed == null) {
5101                            needed = new NeededUriGrants(targetPkg, target, mode);
5102                        }
5103                        needed.add(uri);
5104                    }
5105                } else {
5106                    Intent clipIntent = clip.getItemAt(i).getIntent();
5107                    if (clipIntent != null) {
5108                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5109                                callingUid, targetPkg, clipIntent, mode, needed);
5110                        if (newNeeded != null) {
5111                            needed = newNeeded;
5112                        }
5113                    }
5114                }
5115            }
5116        }
5117
5118        return needed;
5119    }
5120
5121    /**
5122     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5123     */
5124    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5125            UriPermissionOwner owner) {
5126        if (needed != null) {
5127            for (int i=0; i<needed.size(); i++) {
5128                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5129                        needed.get(i), needed.flags, owner);
5130            }
5131        }
5132    }
5133
5134    void grantUriPermissionFromIntentLocked(int callingUid,
5135            String targetPkg, Intent intent, UriPermissionOwner owner) {
5136        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5137                intent, intent != null ? intent.getFlags() : 0, null);
5138        if (needed == null) {
5139            return;
5140        }
5141
5142        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5143    }
5144
5145    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5146            Uri uri, int modeFlags) {
5147        enforceNotIsolatedCaller("grantUriPermission");
5148        synchronized(this) {
5149            final ProcessRecord r = getRecordForAppLocked(caller);
5150            if (r == null) {
5151                throw new SecurityException("Unable to find app for caller "
5152                        + caller
5153                        + " when granting permission to uri " + uri);
5154            }
5155            if (targetPkg == null) {
5156                throw new IllegalArgumentException("null target");
5157            }
5158            if (uri == null) {
5159                throw new IllegalArgumentException("null uri");
5160            }
5161
5162            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5163                    null);
5164        }
5165    }
5166
5167    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5168        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5169                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5170            HashMap<Uri, UriPermission> perms
5171                    = mGrantedUriPermissions.get(perm.uid);
5172            if (perms != null) {
5173                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5174                        "Removing " + perm.uid + " permission to " + perm.uri);
5175                perms.remove(perm.uri);
5176                if (perms.size() == 0) {
5177                    mGrantedUriPermissions.remove(perm.uid);
5178                }
5179            }
5180        }
5181    }
5182
5183    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5184            int modeFlags) {
5185        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5186                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5187        if (modeFlags == 0) {
5188            return;
5189        }
5190
5191        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5192                "Revoking all granted permissions to " + uri);
5193
5194        final IPackageManager pm = AppGlobals.getPackageManager();
5195
5196        final String authority = uri.getAuthority();
5197        ProviderInfo pi = null;
5198        int userId = UserHandle.getUserId(callingUid);
5199        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5200        if (cpr != null) {
5201            pi = cpr.info;
5202        } else {
5203            try {
5204                pi = pm.resolveContentProvider(authority,
5205                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5206            } catch (RemoteException ex) {
5207            }
5208        }
5209        if (pi == null) {
5210            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5211            return;
5212        }
5213
5214        // Does the caller have this permission on the URI?
5215        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5216            // Right now, if you are not the original owner of the permission,
5217            // you are not allowed to revoke it.
5218            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5219                throw new SecurityException("Uid " + callingUid
5220                        + " does not have permission to uri " + uri);
5221            //}
5222        }
5223
5224        // Go through all of the permissions and remove any that match.
5225        final List<String> SEGMENTS = uri.getPathSegments();
5226        if (SEGMENTS != null) {
5227            final int NS = SEGMENTS.size();
5228            int N = mGrantedUriPermissions.size();
5229            for (int i=0; i<N; i++) {
5230                HashMap<Uri, UriPermission> perms
5231                        = mGrantedUriPermissions.valueAt(i);
5232                Iterator<UriPermission> it = perms.values().iterator();
5233            toploop:
5234                while (it.hasNext()) {
5235                    UriPermission perm = it.next();
5236                    Uri targetUri = perm.uri;
5237                    if (!authority.equals(targetUri.getAuthority())) {
5238                        continue;
5239                    }
5240                    List<String> targetSegments = targetUri.getPathSegments();
5241                    if (targetSegments == null) {
5242                        continue;
5243                    }
5244                    if (targetSegments.size() < NS) {
5245                        continue;
5246                    }
5247                    for (int j=0; j<NS; j++) {
5248                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5249                            continue toploop;
5250                        }
5251                    }
5252                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5253                            "Revoking " + perm.uid + " permission to " + perm.uri);
5254                    perm.clearModes(modeFlags);
5255                    if (perm.modeFlags == 0) {
5256                        it.remove();
5257                    }
5258                }
5259                if (perms.size() == 0) {
5260                    mGrantedUriPermissions.remove(
5261                            mGrantedUriPermissions.keyAt(i));
5262                    N--;
5263                    i--;
5264                }
5265            }
5266        }
5267    }
5268
5269    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5270            int modeFlags) {
5271        enforceNotIsolatedCaller("revokeUriPermission");
5272        synchronized(this) {
5273            final ProcessRecord r = getRecordForAppLocked(caller);
5274            if (r == null) {
5275                throw new SecurityException("Unable to find app for caller "
5276                        + caller
5277                        + " when revoking permission to uri " + uri);
5278            }
5279            if (uri == null) {
5280                Slog.w(TAG, "revokeUriPermission: null uri");
5281                return;
5282            }
5283
5284            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5285                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5286            if (modeFlags == 0) {
5287                return;
5288            }
5289
5290            final IPackageManager pm = AppGlobals.getPackageManager();
5291
5292            final String authority = uri.getAuthority();
5293            ProviderInfo pi = null;
5294            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5295            if (cpr != null) {
5296                pi = cpr.info;
5297            } else {
5298                try {
5299                    pi = pm.resolveContentProvider(authority,
5300                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5301                } catch (RemoteException ex) {
5302                }
5303            }
5304            if (pi == null) {
5305                Slog.w(TAG, "No content provider found for permission revoke: "
5306                        + uri.toSafeString());
5307                return;
5308            }
5309
5310            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5311        }
5312    }
5313
5314    @Override
5315    public IBinder newUriPermissionOwner(String name) {
5316        enforceNotIsolatedCaller("newUriPermissionOwner");
5317        synchronized(this) {
5318            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5319            return owner.getExternalTokenLocked();
5320        }
5321    }
5322
5323    @Override
5324    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5325            Uri uri, int modeFlags) {
5326        synchronized(this) {
5327            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5328            if (owner == null) {
5329                throw new IllegalArgumentException("Unknown owner: " + token);
5330            }
5331            if (fromUid != Binder.getCallingUid()) {
5332                if (Binder.getCallingUid() != Process.myUid()) {
5333                    // Only system code can grant URI permissions on behalf
5334                    // of other users.
5335                    throw new SecurityException("nice try");
5336                }
5337            }
5338            if (targetPkg == null) {
5339                throw new IllegalArgumentException("null target");
5340            }
5341            if (uri == null) {
5342                throw new IllegalArgumentException("null uri");
5343            }
5344
5345            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5346        }
5347    }
5348
5349    @Override
5350    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5351        synchronized(this) {
5352            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5353            if (owner == null) {
5354                throw new IllegalArgumentException("Unknown owner: " + token);
5355            }
5356
5357            if (uri == null) {
5358                owner.removeUriPermissionsLocked(mode);
5359            } else {
5360                owner.removeUriPermissionLocked(uri, mode);
5361            }
5362        }
5363    }
5364
5365    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5366        synchronized (this) {
5367            ProcessRecord app =
5368                who != null ? getRecordForAppLocked(who) : null;
5369            if (app == null) return;
5370
5371            Message msg = Message.obtain();
5372            msg.what = WAIT_FOR_DEBUGGER_MSG;
5373            msg.obj = app;
5374            msg.arg1 = waiting ? 1 : 0;
5375            mHandler.sendMessage(msg);
5376        }
5377    }
5378
5379    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5380        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5381        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5382        outInfo.availMem = Process.getFreeMemory();
5383        outInfo.totalMem = Process.getTotalMemory();
5384        outInfo.threshold = homeAppMem;
5385        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5386        outInfo.hiddenAppThreshold = hiddenAppMem;
5387        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5388                ProcessList.SERVICE_ADJ);
5389        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5390                ProcessList.VISIBLE_APP_ADJ);
5391        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5392                ProcessList.FOREGROUND_APP_ADJ);
5393    }
5394
5395    // =========================================================
5396    // TASK MANAGEMENT
5397    // =========================================================
5398
5399    public List getTasks(int maxNum, int flags,
5400                         IThumbnailReceiver receiver) {
5401        ArrayList list = new ArrayList();
5402
5403        PendingThumbnailsRecord pending = null;
5404        IApplicationThread topThumbnail = null;
5405        ActivityRecord topRecord = null;
5406
5407        synchronized(this) {
5408            if (localLOGV) Slog.v(
5409                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5410                + ", receiver=" + receiver);
5411
5412            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5413                    != PackageManager.PERMISSION_GRANTED) {
5414                if (receiver != null) {
5415                    // If the caller wants to wait for pending thumbnails,
5416                    // it ain't gonna get them.
5417                    try {
5418                        receiver.finished();
5419                    } catch (RemoteException ex) {
5420                    }
5421                }
5422                String msg = "Permission Denial: getTasks() from pid="
5423                        + Binder.getCallingPid()
5424                        + ", uid=" + Binder.getCallingUid()
5425                        + " requires " + android.Manifest.permission.GET_TASKS;
5426                Slog.w(TAG, msg);
5427                throw new SecurityException(msg);
5428            }
5429
5430            int pos = mMainStack.mHistory.size()-1;
5431            ActivityRecord next =
5432                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5433            ActivityRecord top = null;
5434            TaskRecord curTask = null;
5435            int numActivities = 0;
5436            int numRunning = 0;
5437            while (pos >= 0 && maxNum > 0) {
5438                final ActivityRecord r = next;
5439                pos--;
5440                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5441
5442                // Initialize state for next task if needed.
5443                if (top == null ||
5444                        (top.state == ActivityState.INITIALIZING
5445                            && top.task == r.task)) {
5446                    top = r;
5447                    curTask = r.task;
5448                    numActivities = numRunning = 0;
5449                }
5450
5451                // Add 'r' into the current task.
5452                numActivities++;
5453                if (r.app != null && r.app.thread != null) {
5454                    numRunning++;
5455                }
5456
5457                if (localLOGV) Slog.v(
5458                    TAG, r.intent.getComponent().flattenToShortString()
5459                    + ": task=" + r.task);
5460
5461                // If the next one is a different task, generate a new
5462                // TaskInfo entry for what we have.
5463                if (next == null || next.task != curTask) {
5464                    ActivityManager.RunningTaskInfo ci
5465                            = new ActivityManager.RunningTaskInfo();
5466                    ci.id = curTask.taskId;
5467                    ci.baseActivity = r.intent.getComponent();
5468                    ci.topActivity = top.intent.getComponent();
5469                    if (top.thumbHolder != null) {
5470                        ci.description = top.thumbHolder.lastDescription;
5471                    }
5472                    ci.numActivities = numActivities;
5473                    ci.numRunning = numRunning;
5474                    //System.out.println(
5475                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5476                    if (ci.thumbnail == null && receiver != null) {
5477                        if (localLOGV) Slog.v(
5478                            TAG, "State=" + top.state + "Idle=" + top.idle
5479                            + " app=" + top.app
5480                            + " thr=" + (top.app != null ? top.app.thread : null));
5481                        if (top.state == ActivityState.RESUMED
5482                                || top.state == ActivityState.PAUSING) {
5483                            if (top.idle && top.app != null
5484                                && top.app.thread != null) {
5485                                topRecord = top;
5486                                topThumbnail = top.app.thread;
5487                            } else {
5488                                top.thumbnailNeeded = true;
5489                            }
5490                        }
5491                        if (pending == null) {
5492                            pending = new PendingThumbnailsRecord(receiver);
5493                        }
5494                        pending.pendingRecords.add(top);
5495                    }
5496                    list.add(ci);
5497                    maxNum--;
5498                    top = null;
5499                }
5500            }
5501
5502            if (pending != null) {
5503                mPendingThumbnails.add(pending);
5504            }
5505        }
5506
5507        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5508
5509        if (topThumbnail != null) {
5510            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5511            try {
5512                topThumbnail.requestThumbnail(topRecord.appToken);
5513            } catch (Exception e) {
5514                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5515                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5516            }
5517        }
5518
5519        if (pending == null && receiver != null) {
5520            // In this case all thumbnails were available and the client
5521            // is being asked to be told when the remaining ones come in...
5522            // which is unusually, since the top-most currently running
5523            // activity should never have a canned thumbnail!  Oh well.
5524            try {
5525                receiver.finished();
5526            } catch (RemoteException ex) {
5527            }
5528        }
5529
5530        return list;
5531    }
5532
5533    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5534            int flags, int userId) {
5535        final int callingUid = Binder.getCallingUid();
5536        if (userId != UserHandle.getCallingUserId()) {
5537            // Check if the caller is holding permissions for cross-user requests.
5538            if (checkComponentPermission(
5539                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5540                    Binder.getCallingPid(), callingUid, -1, true)
5541                    != PackageManager.PERMISSION_GRANTED) {
5542                String msg = "Permission Denial: "
5543                        + "Request to get recent tasks for user " + userId
5544                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5545                        + "; this requires "
5546                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5547                Slog.w(TAG, msg);
5548                throw new SecurityException(msg);
5549            } else {
5550                if (userId == UserHandle.USER_CURRENT) {
5551                    userId = mCurrentUserId;
5552                }
5553            }
5554        }
5555
5556        synchronized (this) {
5557            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5558                    "getRecentTasks()");
5559            final boolean detailed = checkCallingPermission(
5560                    android.Manifest.permission.GET_DETAILED_TASKS)
5561                    == PackageManager.PERMISSION_GRANTED;
5562
5563            IPackageManager pm = AppGlobals.getPackageManager();
5564
5565            final int N = mRecentTasks.size();
5566            ArrayList<ActivityManager.RecentTaskInfo> res
5567                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5568                            maxNum < N ? maxNum : N);
5569            for (int i=0; i<N && maxNum > 0; i++) {
5570                TaskRecord tr = mRecentTasks.get(i);
5571                // Only add calling user's recent tasks
5572                if (tr.userId != userId) continue;
5573                // Return the entry if desired by the caller.  We always return
5574                // the first entry, because callers always expect this to be the
5575                // foreground app.  We may filter others if the caller has
5576                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5577                // we should exclude the entry.
5578
5579                if (i == 0
5580                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5581                        || (tr.intent == null)
5582                        || ((tr.intent.getFlags()
5583                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5584                    ActivityManager.RecentTaskInfo rti
5585                            = new ActivityManager.RecentTaskInfo();
5586                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5587                    rti.persistentId = tr.taskId;
5588                    rti.baseIntent = new Intent(
5589                            tr.intent != null ? tr.intent : tr.affinityIntent);
5590                    if (!detailed) {
5591                        rti.baseIntent.replaceExtras((Bundle)null);
5592                    }
5593                    rti.origActivity = tr.origActivity;
5594                    rti.description = tr.lastDescription;
5595
5596                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5597                        // Check whether this activity is currently available.
5598                        try {
5599                            if (rti.origActivity != null) {
5600                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5601                                        == null) {
5602                                    continue;
5603                                }
5604                            } else if (rti.baseIntent != null) {
5605                                if (pm.queryIntentActivities(rti.baseIntent,
5606                                        null, 0, userId) == null) {
5607                                    continue;
5608                                }
5609                            }
5610                        } catch (RemoteException e) {
5611                            // Will never happen.
5612                        }
5613                    }
5614
5615                    res.add(rti);
5616                    maxNum--;
5617                }
5618            }
5619            return res;
5620        }
5621    }
5622
5623    private TaskRecord taskForIdLocked(int id) {
5624        final int N = mRecentTasks.size();
5625        for (int i=0; i<N; i++) {
5626            TaskRecord tr = mRecentTasks.get(i);
5627            if (tr.taskId == id) {
5628                return tr;
5629            }
5630        }
5631        return null;
5632    }
5633
5634    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5635        synchronized (this) {
5636            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5637                    "getTaskThumbnails()");
5638            TaskRecord tr = taskForIdLocked(id);
5639            if (tr != null) {
5640                return mMainStack.getTaskThumbnailsLocked(tr);
5641            }
5642        }
5643        return null;
5644    }
5645
5646    public boolean removeSubTask(int taskId, int subTaskIndex) {
5647        synchronized (this) {
5648            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5649                    "removeSubTask()");
5650            long ident = Binder.clearCallingIdentity();
5651            try {
5652                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5653                        true) != null;
5654            } finally {
5655                Binder.restoreCallingIdentity(ident);
5656            }
5657        }
5658    }
5659
5660    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5661        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5662        Intent baseIntent = new Intent(
5663                tr.intent != null ? tr.intent : tr.affinityIntent);
5664        ComponentName component = baseIntent.getComponent();
5665        if (component == null) {
5666            Slog.w(TAG, "Now component for base intent of task: " + tr);
5667            return;
5668        }
5669
5670        // Find any running services associated with this app.
5671        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5672
5673        if (killProcesses) {
5674            // Find any running processes associated with this app.
5675            final String pkg = component.getPackageName();
5676            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5677            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5678            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5679                for (int i=0; i<uids.size(); i++) {
5680                    ProcessRecord proc = uids.valueAt(i);
5681                    if (proc.userId != tr.userId) {
5682                        continue;
5683                    }
5684                    if (!proc.pkgList.contains(pkg)) {
5685                        continue;
5686                    }
5687                    procs.add(proc);
5688                }
5689            }
5690
5691            // Kill the running processes.
5692            for (int i=0; i<procs.size(); i++) {
5693                ProcessRecord pr = procs.get(i);
5694                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5695                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5696                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5697                            pr.processName, pr.setAdj, "remove task");
5698                    pr.killedBackground = true;
5699                    Process.killProcessQuiet(pr.pid);
5700                } else {
5701                    pr.waitingToKill = "remove task";
5702                }
5703            }
5704        }
5705    }
5706
5707    public boolean removeTask(int taskId, int flags) {
5708        synchronized (this) {
5709            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5710                    "removeTask()");
5711            long ident = Binder.clearCallingIdentity();
5712            try {
5713                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5714                        false);
5715                if (r != null) {
5716                    mRecentTasks.remove(r.task);
5717                    cleanUpRemovedTaskLocked(r.task, flags);
5718                    return true;
5719                } else {
5720                    TaskRecord tr = null;
5721                    int i=0;
5722                    while (i < mRecentTasks.size()) {
5723                        TaskRecord t = mRecentTasks.get(i);
5724                        if (t.taskId == taskId) {
5725                            tr = t;
5726                            break;
5727                        }
5728                        i++;
5729                    }
5730                    if (tr != null) {
5731                        if (tr.numActivities <= 0) {
5732                            // Caller is just removing a recent task that is
5733                            // not actively running.  That is easy!
5734                            mRecentTasks.remove(i);
5735                            cleanUpRemovedTaskLocked(tr, flags);
5736                            return true;
5737                        } else {
5738                            Slog.w(TAG, "removeTask: task " + taskId
5739                                    + " does not have activities to remove, "
5740                                    + " but numActivities=" + tr.numActivities
5741                                    + ": " + tr);
5742                        }
5743                    }
5744                }
5745            } finally {
5746                Binder.restoreCallingIdentity(ident);
5747            }
5748        }
5749        return false;
5750    }
5751
5752    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5753        int j;
5754        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5755        TaskRecord jt = startTask;
5756
5757        // First look backwards
5758        for (j=startIndex-1; j>=0; j--) {
5759            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5760            if (r.task != jt) {
5761                jt = r.task;
5762                if (affinity.equals(jt.affinity)) {
5763                    return j;
5764                }
5765            }
5766        }
5767
5768        // Now look forwards
5769        final int N = mMainStack.mHistory.size();
5770        jt = startTask;
5771        for (j=startIndex+1; j<N; j++) {
5772            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5773            if (r.task != jt) {
5774                if (affinity.equals(jt.affinity)) {
5775                    return j;
5776                }
5777                jt = r.task;
5778            }
5779        }
5780
5781        // Might it be at the top?
5782        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5783            return N-1;
5784        }
5785
5786        return -1;
5787    }
5788
5789    /**
5790     * TODO: Add mController hook
5791     */
5792    public void moveTaskToFront(int task, int flags, Bundle options) {
5793        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5794                "moveTaskToFront()");
5795
5796        synchronized(this) {
5797            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5798                    Binder.getCallingUid(), "Task to front")) {
5799                ActivityOptions.abort(options);
5800                return;
5801            }
5802            final long origId = Binder.clearCallingIdentity();
5803            try {
5804                TaskRecord tr = taskForIdLocked(task);
5805                if (tr != null) {
5806                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5807                        mMainStack.mUserLeaving = true;
5808                    }
5809                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5810                        // Caller wants the home activity moved with it.  To accomplish this,
5811                        // we'll just move the home task to the top first.
5812                        mMainStack.moveHomeToFrontLocked();
5813                    }
5814                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5815                    return;
5816                }
5817                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5818                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5819                    if (hr.task.taskId == task) {
5820                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5821                            mMainStack.mUserLeaving = true;
5822                        }
5823                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5824                            // Caller wants the home activity moved with it.  To accomplish this,
5825                            // we'll just move the home task to the top first.
5826                            mMainStack.moveHomeToFrontLocked();
5827                        }
5828                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5829                        return;
5830                    }
5831                }
5832            } finally {
5833                Binder.restoreCallingIdentity(origId);
5834            }
5835            ActivityOptions.abort(options);
5836        }
5837    }
5838
5839    public void moveTaskToBack(int task) {
5840        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5841                "moveTaskToBack()");
5842
5843        synchronized(this) {
5844            if (mMainStack.mResumedActivity != null
5845                    && mMainStack.mResumedActivity.task.taskId == task) {
5846                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5847                        Binder.getCallingUid(), "Task to back")) {
5848                    return;
5849                }
5850            }
5851            final long origId = Binder.clearCallingIdentity();
5852            mMainStack.moveTaskToBackLocked(task, null);
5853            Binder.restoreCallingIdentity(origId);
5854        }
5855    }
5856
5857    /**
5858     * Moves an activity, and all of the other activities within the same task, to the bottom
5859     * of the history stack.  The activity's order within the task is unchanged.
5860     *
5861     * @param token A reference to the activity we wish to move
5862     * @param nonRoot If false then this only works if the activity is the root
5863     *                of a task; if true it will work for any activity in a task.
5864     * @return Returns true if the move completed, false if not.
5865     */
5866    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5867        enforceNotIsolatedCaller("moveActivityTaskToBack");
5868        synchronized(this) {
5869            final long origId = Binder.clearCallingIdentity();
5870            int taskId = getTaskForActivityLocked(token, !nonRoot);
5871            if (taskId >= 0) {
5872                return mMainStack.moveTaskToBackLocked(taskId, null);
5873            }
5874            Binder.restoreCallingIdentity(origId);
5875        }
5876        return false;
5877    }
5878
5879    public void moveTaskBackwards(int task) {
5880        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5881                "moveTaskBackwards()");
5882
5883        synchronized(this) {
5884            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5885                    Binder.getCallingUid(), "Task backwards")) {
5886                return;
5887            }
5888            final long origId = Binder.clearCallingIdentity();
5889            moveTaskBackwardsLocked(task);
5890            Binder.restoreCallingIdentity(origId);
5891        }
5892    }
5893
5894    private final void moveTaskBackwardsLocked(int task) {
5895        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5896    }
5897
5898    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5899        synchronized(this) {
5900            return getTaskForActivityLocked(token, onlyRoot);
5901        }
5902    }
5903
5904    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5905        final int N = mMainStack.mHistory.size();
5906        TaskRecord lastTask = null;
5907        for (int i=0; i<N; i++) {
5908            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5909            if (r.appToken == token) {
5910                if (!onlyRoot || lastTask != r.task) {
5911                    return r.task.taskId;
5912                }
5913                return -1;
5914            }
5915            lastTask = r.task;
5916        }
5917
5918        return -1;
5919    }
5920
5921    // =========================================================
5922    // THUMBNAILS
5923    // =========================================================
5924
5925    public void reportThumbnail(IBinder token,
5926            Bitmap thumbnail, CharSequence description) {
5927        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5928        final long origId = Binder.clearCallingIdentity();
5929        sendPendingThumbnail(null, token, thumbnail, description, true);
5930        Binder.restoreCallingIdentity(origId);
5931    }
5932
5933    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5934            Bitmap thumbnail, CharSequence description, boolean always) {
5935        TaskRecord task = null;
5936        ArrayList receivers = null;
5937
5938        //System.out.println("Send pending thumbnail: " + r);
5939
5940        synchronized(this) {
5941            if (r == null) {
5942                r = mMainStack.isInStackLocked(token);
5943                if (r == null) {
5944                    return;
5945                }
5946            }
5947            if (thumbnail == null && r.thumbHolder != null) {
5948                thumbnail = r.thumbHolder.lastThumbnail;
5949                description = r.thumbHolder.lastDescription;
5950            }
5951            if (thumbnail == null && !always) {
5952                // If there is no thumbnail, and this entry is not actually
5953                // going away, then abort for now and pick up the next
5954                // thumbnail we get.
5955                return;
5956            }
5957            task = r.task;
5958
5959            int N = mPendingThumbnails.size();
5960            int i=0;
5961            while (i<N) {
5962                PendingThumbnailsRecord pr =
5963                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5964                //System.out.println("Looking in " + pr.pendingRecords);
5965                if (pr.pendingRecords.remove(r)) {
5966                    if (receivers == null) {
5967                        receivers = new ArrayList();
5968                    }
5969                    receivers.add(pr);
5970                    if (pr.pendingRecords.size() == 0) {
5971                        pr.finished = true;
5972                        mPendingThumbnails.remove(i);
5973                        N--;
5974                        continue;
5975                    }
5976                }
5977                i++;
5978            }
5979        }
5980
5981        if (receivers != null) {
5982            final int N = receivers.size();
5983            for (int i=0; i<N; i++) {
5984                try {
5985                    PendingThumbnailsRecord pr =
5986                        (PendingThumbnailsRecord)receivers.get(i);
5987                    pr.receiver.newThumbnail(
5988                        task != null ? task.taskId : -1, thumbnail, description);
5989                    if (pr.finished) {
5990                        pr.receiver.finished();
5991                    }
5992                } catch (Exception e) {
5993                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5994                }
5995            }
5996        }
5997    }
5998
5999    // =========================================================
6000    // CONTENT PROVIDERS
6001    // =========================================================
6002
6003    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6004        List<ProviderInfo> providers = null;
6005        try {
6006            providers = AppGlobals.getPackageManager().
6007                queryContentProviders(app.processName, app.uid,
6008                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6009        } catch (RemoteException ex) {
6010        }
6011        if (DEBUG_MU)
6012            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6013        int userId = app.userId;
6014        if (providers != null) {
6015            int N = providers.size();
6016            for (int i=0; i<N; i++) {
6017                ProviderInfo cpi =
6018                    (ProviderInfo)providers.get(i);
6019                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6020                        cpi.name, cpi.flags);
6021                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6022                    // This is a singleton provider, but a user besides the
6023                    // default user is asking to initialize a process it runs
6024                    // in...  well, no, it doesn't actually run in this process,
6025                    // it runs in the process of the default user.  Get rid of it.
6026                    providers.remove(i);
6027                    N--;
6028                    continue;
6029                }
6030
6031                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6032                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6033                if (cpr == null) {
6034                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6035                    mProviderMap.putProviderByClass(comp, cpr);
6036                }
6037                if (DEBUG_MU)
6038                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6039                app.pubProviders.put(cpi.name, cpr);
6040                app.addPackage(cpi.applicationInfo.packageName);
6041                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6042            }
6043        }
6044        return providers;
6045    }
6046
6047    /**
6048     * Check if {@link ProcessRecord} has a possible chance at accessing the
6049     * given {@link ProviderInfo}. Final permission checking is always done
6050     * in {@link ContentProvider}.
6051     */
6052    private final String checkContentProviderPermissionLocked(
6053            ProviderInfo cpi, ProcessRecord r) {
6054        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6055        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6056        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6057                cpi.applicationInfo.uid, cpi.exported)
6058                == PackageManager.PERMISSION_GRANTED) {
6059            return null;
6060        }
6061        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6062                cpi.applicationInfo.uid, cpi.exported)
6063                == PackageManager.PERMISSION_GRANTED) {
6064            return null;
6065        }
6066
6067        PathPermission[] pps = cpi.pathPermissions;
6068        if (pps != null) {
6069            int i = pps.length;
6070            while (i > 0) {
6071                i--;
6072                PathPermission pp = pps[i];
6073                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6074                        cpi.applicationInfo.uid, cpi.exported)
6075                        == PackageManager.PERMISSION_GRANTED) {
6076                    return null;
6077                }
6078                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6079                        cpi.applicationInfo.uid, cpi.exported)
6080                        == PackageManager.PERMISSION_GRANTED) {
6081                    return null;
6082                }
6083            }
6084        }
6085
6086        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6087        if (perms != null) {
6088            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6089                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6090                    return null;
6091                }
6092            }
6093        }
6094
6095        String msg;
6096        if (!cpi.exported) {
6097            msg = "Permission Denial: opening provider " + cpi.name
6098                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6099                    + ", uid=" + callingUid + ") that is not exported from uid "
6100                    + cpi.applicationInfo.uid;
6101        } else {
6102            msg = "Permission Denial: opening provider " + cpi.name
6103                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6104                    + ", uid=" + callingUid + ") requires "
6105                    + cpi.readPermission + " or " + cpi.writePermission;
6106        }
6107        Slog.w(TAG, msg);
6108        return msg;
6109    }
6110
6111    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6112            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6113        if (r != null) {
6114            for (int i=0; i<r.conProviders.size(); i++) {
6115                ContentProviderConnection conn = r.conProviders.get(i);
6116                if (conn.provider == cpr) {
6117                    if (DEBUG_PROVIDER) Slog.v(TAG,
6118                            "Adding provider requested by "
6119                            + r.processName + " from process "
6120                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6121                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6122                    if (stable) {
6123                        conn.stableCount++;
6124                        conn.numStableIncs++;
6125                    } else {
6126                        conn.unstableCount++;
6127                        conn.numUnstableIncs++;
6128                    }
6129                    return conn;
6130                }
6131            }
6132            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6133            if (stable) {
6134                conn.stableCount = 1;
6135                conn.numStableIncs = 1;
6136            } else {
6137                conn.unstableCount = 1;
6138                conn.numUnstableIncs = 1;
6139            }
6140            cpr.connections.add(conn);
6141            r.conProviders.add(conn);
6142            return conn;
6143        }
6144        cpr.addExternalProcessHandleLocked(externalProcessToken);
6145        return null;
6146    }
6147
6148    boolean decProviderCountLocked(ContentProviderConnection conn,
6149            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6150        if (conn != null) {
6151            cpr = conn.provider;
6152            if (DEBUG_PROVIDER) Slog.v(TAG,
6153                    "Removing provider requested by "
6154                    + conn.client.processName + " from process "
6155                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6156                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6157            if (stable) {
6158                conn.stableCount--;
6159            } else {
6160                conn.unstableCount--;
6161            }
6162            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6163                cpr.connections.remove(conn);
6164                conn.client.conProviders.remove(conn);
6165                return true;
6166            }
6167            return false;
6168        }
6169        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6170        return false;
6171    }
6172
6173    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6174            String name, IBinder token, boolean stable) {
6175        ContentProviderRecord cpr;
6176        ContentProviderConnection conn = null;
6177        ProviderInfo cpi = null;
6178
6179        synchronized(this) {
6180            ProcessRecord r = null;
6181            if (caller != null) {
6182                r = getRecordForAppLocked(caller);
6183                if (r == null) {
6184                    throw new SecurityException(
6185                            "Unable to find app for caller " + caller
6186                          + " (pid=" + Binder.getCallingPid()
6187                          + ") when getting content provider " + name);
6188                }
6189            }
6190
6191            // First check if this content provider has been published...
6192            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6193            cpr = mProviderMap.getProviderByName(name, userId);
6194            boolean providerRunning = cpr != null;
6195            if (providerRunning) {
6196                cpi = cpr.info;
6197                String msg;
6198                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6199                    throw new SecurityException(msg);
6200                }
6201
6202                if (r != null && cpr.canRunHere(r)) {
6203                    // This provider has been published or is in the process
6204                    // of being published...  but it is also allowed to run
6205                    // in the caller's process, so don't make a connection
6206                    // and just let the caller instantiate its own instance.
6207                    ContentProviderHolder holder = cpr.newHolder(null);
6208                    // don't give caller the provider object, it needs
6209                    // to make its own.
6210                    holder.provider = null;
6211                    return holder;
6212                }
6213
6214                final long origId = Binder.clearCallingIdentity();
6215
6216                // In this case the provider instance already exists, so we can
6217                // return it right away.
6218                conn = incProviderCountLocked(r, cpr, token, stable);
6219                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6220                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6221                        // If this is a perceptible app accessing the provider,
6222                        // make sure to count it as being accessed and thus
6223                        // back up on the LRU list.  This is good because
6224                        // content providers are often expensive to start.
6225                        updateLruProcessLocked(cpr.proc, false, true);
6226                    }
6227                }
6228
6229                if (cpr.proc != null) {
6230                    if (false) {
6231                        if (cpr.name.flattenToShortString().equals(
6232                                "com.android.providers.calendar/.CalendarProvider2")) {
6233                            Slog.v(TAG, "****************** KILLING "
6234                                + cpr.name.flattenToShortString());
6235                            Process.killProcess(cpr.proc.pid);
6236                        }
6237                    }
6238                    boolean success = updateOomAdjLocked(cpr.proc);
6239                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6240                    // NOTE: there is still a race here where a signal could be
6241                    // pending on the process even though we managed to update its
6242                    // adj level.  Not sure what to do about this, but at least
6243                    // the race is now smaller.
6244                    if (!success) {
6245                        // Uh oh...  it looks like the provider's process
6246                        // has been killed on us.  We need to wait for a new
6247                        // process to be started, and make sure its death
6248                        // doesn't kill our process.
6249                        Slog.i(TAG,
6250                                "Existing provider " + cpr.name.flattenToShortString()
6251                                + " is crashing; detaching " + r);
6252                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6253                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6254                        if (!lastRef) {
6255                            // This wasn't the last ref our process had on
6256                            // the provider...  we have now been killed, bail.
6257                            return null;
6258                        }
6259                        providerRunning = false;
6260                        conn = null;
6261                    }
6262                }
6263
6264                Binder.restoreCallingIdentity(origId);
6265            }
6266
6267            boolean singleton;
6268            if (!providerRunning) {
6269                try {
6270                    cpi = AppGlobals.getPackageManager().
6271                        resolveContentProvider(name,
6272                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6273                } catch (RemoteException ex) {
6274                }
6275                if (cpi == null) {
6276                    return null;
6277                }
6278                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6279                        cpi.name, cpi.flags);
6280                if (singleton) {
6281                    userId = 0;
6282                }
6283                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6284
6285                String msg;
6286                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6287                    throw new SecurityException(msg);
6288                }
6289
6290                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6291                        && !cpi.processName.equals("system")) {
6292                    // If this content provider does not run in the system
6293                    // process, and the system is not yet ready to run other
6294                    // processes, then fail fast instead of hanging.
6295                    throw new IllegalArgumentException(
6296                            "Attempt to launch content provider before system ready");
6297                }
6298
6299                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6300                cpr = mProviderMap.getProviderByClass(comp, userId);
6301                final boolean firstClass = cpr == null;
6302                if (firstClass) {
6303                    try {
6304                        ApplicationInfo ai =
6305                            AppGlobals.getPackageManager().
6306                                getApplicationInfo(
6307                                        cpi.applicationInfo.packageName,
6308                                        STOCK_PM_FLAGS, userId);
6309                        if (ai == null) {
6310                            Slog.w(TAG, "No package info for content provider "
6311                                    + cpi.name);
6312                            return null;
6313                        }
6314                        ai = getAppInfoForUser(ai, userId);
6315                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6316                    } catch (RemoteException ex) {
6317                        // pm is in same process, this will never happen.
6318                    }
6319                }
6320
6321                if (r != null && cpr.canRunHere(r)) {
6322                    // If this is a multiprocess provider, then just return its
6323                    // info and allow the caller to instantiate it.  Only do
6324                    // this if the provider is the same user as the caller's
6325                    // process, or can run as root (so can be in any process).
6326                    return cpr.newHolder(null);
6327                }
6328
6329                if (DEBUG_PROVIDER) {
6330                    RuntimeException e = new RuntimeException("here");
6331                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6332                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6333                }
6334
6335                // This is single process, and our app is now connecting to it.
6336                // See if we are already in the process of launching this
6337                // provider.
6338                final int N = mLaunchingProviders.size();
6339                int i;
6340                for (i=0; i<N; i++) {
6341                    if (mLaunchingProviders.get(i) == cpr) {
6342                        break;
6343                    }
6344                }
6345
6346                // If the provider is not already being launched, then get it
6347                // started.
6348                if (i >= N) {
6349                    final long origId = Binder.clearCallingIdentity();
6350
6351                    try {
6352                        // Content provider is now in use, its package can't be stopped.
6353                        try {
6354                            AppGlobals.getPackageManager().setPackageStoppedState(
6355                                    cpr.appInfo.packageName, false, userId);
6356                        } catch (RemoteException e) {
6357                        } catch (IllegalArgumentException e) {
6358                            Slog.w(TAG, "Failed trying to unstop package "
6359                                    + cpr.appInfo.packageName + ": " + e);
6360                        }
6361
6362                        ProcessRecord proc = startProcessLocked(cpi.processName,
6363                                cpr.appInfo, false, 0, "content provider",
6364                                new ComponentName(cpi.applicationInfo.packageName,
6365                                        cpi.name), false, false);
6366                        if (proc == null) {
6367                            Slog.w(TAG, "Unable to launch app "
6368                                    + cpi.applicationInfo.packageName + "/"
6369                                    + cpi.applicationInfo.uid + " for provider "
6370                                    + name + ": process is bad");
6371                            return null;
6372                        }
6373                        cpr.launchingApp = proc;
6374                        mLaunchingProviders.add(cpr);
6375                    } finally {
6376                        Binder.restoreCallingIdentity(origId);
6377                    }
6378                }
6379
6380                // Make sure the provider is published (the same provider class
6381                // may be published under multiple names).
6382                if (firstClass) {
6383                    mProviderMap.putProviderByClass(comp, cpr);
6384                }
6385
6386                mProviderMap.putProviderByName(name, cpr);
6387                conn = incProviderCountLocked(r, cpr, token, stable);
6388                if (conn != null) {
6389                    conn.waiting = true;
6390                }
6391            }
6392        }
6393
6394        // Wait for the provider to be published...
6395        synchronized (cpr) {
6396            while (cpr.provider == null) {
6397                if (cpr.launchingApp == null) {
6398                    Slog.w(TAG, "Unable to launch app "
6399                            + cpi.applicationInfo.packageName + "/"
6400                            + cpi.applicationInfo.uid + " for provider "
6401                            + name + ": launching app became null");
6402                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6403                            cpi.applicationInfo.packageName,
6404                            cpi.applicationInfo.uid, name);
6405                    return null;
6406                }
6407                try {
6408                    if (DEBUG_MU) {
6409                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6410                                + cpr.launchingApp);
6411                    }
6412                    if (conn != null) {
6413                        conn.waiting = true;
6414                    }
6415                    cpr.wait();
6416                } catch (InterruptedException ex) {
6417                } finally {
6418                    if (conn != null) {
6419                        conn.waiting = false;
6420                    }
6421                }
6422            }
6423        }
6424        return cpr != null ? cpr.newHolder(conn) : null;
6425    }
6426
6427    public final ContentProviderHolder getContentProvider(
6428            IApplicationThread caller, String name, boolean stable) {
6429        enforceNotIsolatedCaller("getContentProvider");
6430        if (caller == null) {
6431            String msg = "null IApplicationThread when getting content provider "
6432                    + name;
6433            Slog.w(TAG, msg);
6434            throw new SecurityException(msg);
6435        }
6436
6437        return getContentProviderImpl(caller, name, null, stable);
6438    }
6439
6440    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6441        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6442            "Do not have permission in call getContentProviderExternal()");
6443        return getContentProviderExternalUnchecked(name, token);
6444    }
6445
6446    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6447        return getContentProviderImpl(null, name, token, true);
6448    }
6449
6450    /**
6451     * Drop a content provider from a ProcessRecord's bookkeeping
6452     * @param cpr
6453     */
6454    public void removeContentProvider(IBinder connection, boolean stable) {
6455        enforceNotIsolatedCaller("removeContentProvider");
6456        synchronized (this) {
6457            ContentProviderConnection conn;
6458            try {
6459                conn = (ContentProviderConnection)connection;
6460            } catch (ClassCastException e) {
6461                String msg ="removeContentProvider: " + connection
6462                        + " not a ContentProviderConnection";
6463                Slog.w(TAG, msg);
6464                throw new IllegalArgumentException(msg);
6465            }
6466            if (conn == null) {
6467                throw new NullPointerException("connection is null");
6468            }
6469            if (decProviderCountLocked(conn, null, null, stable)) {
6470                updateOomAdjLocked();
6471            }
6472        }
6473    }
6474
6475    public void removeContentProviderExternal(String name, IBinder token) {
6476        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6477            "Do not have permission in call removeContentProviderExternal()");
6478        removeContentProviderExternalUnchecked(name, token);
6479    }
6480
6481    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6482        synchronized (this) {
6483            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6484                    Binder.getOrigCallingUser());
6485            if(cpr == null) {
6486                //remove from mProvidersByClass
6487                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6488                return;
6489            }
6490
6491            //update content provider record entry info
6492            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6493            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6494                    Binder.getOrigCallingUser());
6495            if (localCpr.hasExternalProcessHandles()) {
6496                if (localCpr.removeExternalProcessHandleLocked(token)) {
6497                    updateOomAdjLocked();
6498                } else {
6499                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6500                            + " with no external reference for token: "
6501                            + token + ".");
6502                }
6503            } else {
6504                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6505                        + " with no external references.");
6506            }
6507        }
6508    }
6509
6510    public final void publishContentProviders(IApplicationThread caller,
6511            List<ContentProviderHolder> providers) {
6512        if (providers == null) {
6513            return;
6514        }
6515
6516        enforceNotIsolatedCaller("publishContentProviders");
6517        synchronized (this) {
6518            final ProcessRecord r = getRecordForAppLocked(caller);
6519            if (DEBUG_MU)
6520                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6521            if (r == null) {
6522                throw new SecurityException(
6523                        "Unable to find app for caller " + caller
6524                      + " (pid=" + Binder.getCallingPid()
6525                      + ") when publishing content providers");
6526            }
6527
6528            final long origId = Binder.clearCallingIdentity();
6529
6530            final int N = providers.size();
6531            for (int i=0; i<N; i++) {
6532                ContentProviderHolder src = providers.get(i);
6533                if (src == null || src.info == null || src.provider == null) {
6534                    continue;
6535                }
6536                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6537                if (DEBUG_MU)
6538                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6539                if (dst != null) {
6540                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6541                    mProviderMap.putProviderByClass(comp, dst);
6542                    String names[] = dst.info.authority.split(";");
6543                    for (int j = 0; j < names.length; j++) {
6544                        mProviderMap.putProviderByName(names[j], dst);
6545                    }
6546
6547                    int NL = mLaunchingProviders.size();
6548                    int j;
6549                    for (j=0; j<NL; j++) {
6550                        if (mLaunchingProviders.get(j) == dst) {
6551                            mLaunchingProviders.remove(j);
6552                            j--;
6553                            NL--;
6554                        }
6555                    }
6556                    synchronized (dst) {
6557                        dst.provider = src.provider;
6558                        dst.proc = r;
6559                        dst.notifyAll();
6560                    }
6561                    updateOomAdjLocked(r);
6562                }
6563            }
6564
6565            Binder.restoreCallingIdentity(origId);
6566        }
6567    }
6568
6569    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6570        ContentProviderConnection conn;
6571        try {
6572            conn = (ContentProviderConnection)connection;
6573        } catch (ClassCastException e) {
6574            String msg ="refContentProvider: " + connection
6575                    + " not a ContentProviderConnection";
6576            Slog.w(TAG, msg);
6577            throw new IllegalArgumentException(msg);
6578        }
6579        if (conn == null) {
6580            throw new NullPointerException("connection is null");
6581        }
6582
6583        synchronized (this) {
6584            if (stable > 0) {
6585                conn.numStableIncs += stable;
6586            }
6587            stable = conn.stableCount + stable;
6588            if (stable < 0) {
6589                throw new IllegalStateException("stableCount < 0: " + stable);
6590            }
6591
6592            if (unstable > 0) {
6593                conn.numUnstableIncs += unstable;
6594            }
6595            unstable = conn.unstableCount + unstable;
6596            if (unstable < 0) {
6597                throw new IllegalStateException("unstableCount < 0: " + unstable);
6598            }
6599
6600            if ((stable+unstable) <= 0) {
6601                throw new IllegalStateException("ref counts can't go to zero here: stable="
6602                        + stable + " unstable=" + unstable);
6603            }
6604            conn.stableCount = stable;
6605            conn.unstableCount = unstable;
6606            return !conn.dead;
6607        }
6608    }
6609
6610    public void unstableProviderDied(IBinder connection) {
6611        ContentProviderConnection conn;
6612        try {
6613            conn = (ContentProviderConnection)connection;
6614        } catch (ClassCastException e) {
6615            String msg ="refContentProvider: " + connection
6616                    + " not a ContentProviderConnection";
6617            Slog.w(TAG, msg);
6618            throw new IllegalArgumentException(msg);
6619        }
6620        if (conn == null) {
6621            throw new NullPointerException("connection is null");
6622        }
6623
6624        // Safely retrieve the content provider associated with the connection.
6625        IContentProvider provider;
6626        synchronized (this) {
6627            provider = conn.provider.provider;
6628        }
6629
6630        if (provider == null) {
6631            // Um, yeah, we're way ahead of you.
6632            return;
6633        }
6634
6635        // Make sure the caller is being honest with us.
6636        if (provider.asBinder().pingBinder()) {
6637            // Er, no, still looks good to us.
6638            synchronized (this) {
6639                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6640                        + " says " + conn + " died, but we don't agree");
6641                return;
6642            }
6643        }
6644
6645        // Well look at that!  It's dead!
6646        synchronized (this) {
6647            if (conn.provider.provider != provider) {
6648                // But something changed...  good enough.
6649                return;
6650            }
6651
6652            ProcessRecord proc = conn.provider.proc;
6653            if (proc == null || proc.thread == null) {
6654                // Seems like the process is already cleaned up.
6655                return;
6656            }
6657
6658            // As far as we're concerned, this is just like receiving a
6659            // death notification...  just a bit prematurely.
6660            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6661                    + ") early provider death");
6662            final long ident = Binder.clearCallingIdentity();
6663            try {
6664                appDiedLocked(proc, proc.pid, proc.thread);
6665            } finally {
6666                Binder.restoreCallingIdentity(ident);
6667            }
6668        }
6669    }
6670
6671    public static final void installSystemProviders() {
6672        List<ProviderInfo> providers;
6673        synchronized (mSelf) {
6674            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6675            providers = mSelf.generateApplicationProvidersLocked(app);
6676            if (providers != null) {
6677                for (int i=providers.size()-1; i>=0; i--) {
6678                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6679                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6680                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6681                                + ": not system .apk");
6682                        providers.remove(i);
6683                    }
6684                }
6685            }
6686        }
6687        if (providers != null) {
6688            mSystemThread.installSystemProviders(providers);
6689        }
6690
6691        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6692
6693        mSelf.mUsageStatsService.monitorPackages();
6694    }
6695
6696    /**
6697     * Allows app to retrieve the MIME type of a URI without having permission
6698     * to access its content provider.
6699     *
6700     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6701     *
6702     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6703     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6704     */
6705    public String getProviderMimeType(Uri uri) {
6706        enforceNotIsolatedCaller("getProviderMimeType");
6707        final String name = uri.getAuthority();
6708        final long ident = Binder.clearCallingIdentity();
6709        ContentProviderHolder holder = null;
6710
6711        try {
6712            holder = getContentProviderExternalUnchecked(name, null);
6713            if (holder != null) {
6714                return holder.provider.getType(uri);
6715            }
6716        } catch (RemoteException e) {
6717            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6718            return null;
6719        } finally {
6720            if (holder != null) {
6721                removeContentProviderExternalUnchecked(name, null);
6722            }
6723            Binder.restoreCallingIdentity(ident);
6724        }
6725
6726        return null;
6727    }
6728
6729    // =========================================================
6730    // GLOBAL MANAGEMENT
6731    // =========================================================
6732
6733    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6734            ApplicationInfo info, String customProcess, boolean isolated) {
6735        String proc = customProcess != null ? customProcess : info.processName;
6736        BatteryStatsImpl.Uid.Proc ps = null;
6737        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6738        int uid = info.uid;
6739        if (isolated) {
6740            int userId = UserHandle.getUserId(uid);
6741            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6742            uid = 0;
6743            while (true) {
6744                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6745                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6746                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6747                }
6748                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6749                mNextIsolatedProcessUid++;
6750                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6751                    // No process for this uid, use it.
6752                    break;
6753                }
6754                stepsLeft--;
6755                if (stepsLeft <= 0) {
6756                    return null;
6757                }
6758            }
6759        }
6760        synchronized (stats) {
6761            ps = stats.getProcessStatsLocked(info.uid, proc);
6762        }
6763        return new ProcessRecord(ps, thread, info, proc, uid);
6764    }
6765
6766    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6767        ProcessRecord app;
6768        if (!isolated) {
6769            app = getProcessRecordLocked(info.processName, info.uid);
6770        } else {
6771            app = null;
6772        }
6773
6774        if (app == null) {
6775            app = newProcessRecordLocked(null, info, null, isolated);
6776            mProcessNames.put(info.processName, app.uid, app);
6777            if (isolated) {
6778                mIsolatedProcesses.put(app.uid, app);
6779            }
6780            updateLruProcessLocked(app, true, true);
6781        }
6782
6783        // This package really, really can not be stopped.
6784        try {
6785            AppGlobals.getPackageManager().setPackageStoppedState(
6786                    info.packageName, false, UserHandle.getUserId(app.uid));
6787        } catch (RemoteException e) {
6788        } catch (IllegalArgumentException e) {
6789            Slog.w(TAG, "Failed trying to unstop package "
6790                    + info.packageName + ": " + e);
6791        }
6792
6793        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6794                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6795            app.persistent = true;
6796            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6797        }
6798        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6799            mPersistentStartingProcesses.add(app);
6800            startProcessLocked(app, "added application", app.processName);
6801        }
6802
6803        return app;
6804    }
6805
6806    public void unhandledBack() {
6807        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6808                "unhandledBack()");
6809
6810        synchronized(this) {
6811            int count = mMainStack.mHistory.size();
6812            if (DEBUG_SWITCH) Slog.d(
6813                TAG, "Performing unhandledBack(): stack size = " + count);
6814            if (count > 1) {
6815                final long origId = Binder.clearCallingIdentity();
6816                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6817                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6818                Binder.restoreCallingIdentity(origId);
6819            }
6820        }
6821    }
6822
6823    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6824        enforceNotIsolatedCaller("openContentUri");
6825        String name = uri.getAuthority();
6826        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6827        ParcelFileDescriptor pfd = null;
6828        if (cph != null) {
6829            // We record the binder invoker's uid in thread-local storage before
6830            // going to the content provider to open the file.  Later, in the code
6831            // that handles all permissions checks, we look for this uid and use
6832            // that rather than the Activity Manager's own uid.  The effect is that
6833            // we do the check against the caller's permissions even though it looks
6834            // to the content provider like the Activity Manager itself is making
6835            // the request.
6836            sCallerIdentity.set(new Identity(
6837                    Binder.getCallingPid(), Binder.getCallingUid()));
6838            try {
6839                pfd = cph.provider.openFile(uri, "r");
6840            } catch (FileNotFoundException e) {
6841                // do nothing; pfd will be returned null
6842            } finally {
6843                // Ensure that whatever happens, we clean up the identity state
6844                sCallerIdentity.remove();
6845            }
6846
6847            // We've got the fd now, so we're done with the provider.
6848            removeContentProviderExternalUnchecked(name, null);
6849        } else {
6850            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6851        }
6852        return pfd;
6853    }
6854
6855    // Actually is sleeping or shutting down or whatever else in the future
6856    // is an inactive state.
6857    public boolean isSleeping() {
6858        return mSleeping || mShuttingDown;
6859    }
6860
6861    public void goingToSleep() {
6862        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6863                != PackageManager.PERMISSION_GRANTED) {
6864            throw new SecurityException("Requires permission "
6865                    + android.Manifest.permission.DEVICE_POWER);
6866        }
6867
6868        synchronized(this) {
6869            mWentToSleep = true;
6870            updateEventDispatchingLocked();
6871
6872            if (!mSleeping) {
6873                mSleeping = true;
6874                mMainStack.stopIfSleepingLocked();
6875
6876                // Initialize the wake times of all processes.
6877                checkExcessivePowerUsageLocked(false);
6878                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6879                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6880                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6881            }
6882        }
6883    }
6884
6885    public boolean shutdown(int timeout) {
6886        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6887                != PackageManager.PERMISSION_GRANTED) {
6888            throw new SecurityException("Requires permission "
6889                    + android.Manifest.permission.SHUTDOWN);
6890        }
6891
6892        boolean timedout = false;
6893
6894        synchronized(this) {
6895            mShuttingDown = true;
6896            updateEventDispatchingLocked();
6897
6898            if (mMainStack.mResumedActivity != null) {
6899                mMainStack.stopIfSleepingLocked();
6900                final long endTime = System.currentTimeMillis() + timeout;
6901                while (mMainStack.mResumedActivity != null
6902                        || mMainStack.mPausingActivity != null) {
6903                    long delay = endTime - System.currentTimeMillis();
6904                    if (delay <= 0) {
6905                        Slog.w(TAG, "Activity manager shutdown timed out");
6906                        timedout = true;
6907                        break;
6908                    }
6909                    try {
6910                        this.wait();
6911                    } catch (InterruptedException e) {
6912                    }
6913                }
6914            }
6915        }
6916
6917        mUsageStatsService.shutdown();
6918        mBatteryStatsService.shutdown();
6919
6920        return timedout;
6921    }
6922
6923    public final void activitySlept(IBinder token) {
6924        if (localLOGV) Slog.v(
6925            TAG, "Activity slept: token=" + token);
6926
6927        ActivityRecord r = null;
6928
6929        final long origId = Binder.clearCallingIdentity();
6930
6931        synchronized (this) {
6932            r = mMainStack.isInStackLocked(token);
6933            if (r != null) {
6934                mMainStack.activitySleptLocked(r);
6935            }
6936        }
6937
6938        Binder.restoreCallingIdentity(origId);
6939    }
6940
6941    private void comeOutOfSleepIfNeededLocked() {
6942        if (!mWentToSleep && !mLockScreenShown) {
6943            if (mSleeping) {
6944                mSleeping = false;
6945                mMainStack.awakeFromSleepingLocked();
6946                mMainStack.resumeTopActivityLocked(null);
6947            }
6948        }
6949    }
6950
6951    public void wakingUp() {
6952        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6953                != PackageManager.PERMISSION_GRANTED) {
6954            throw new SecurityException("Requires permission "
6955                    + android.Manifest.permission.DEVICE_POWER);
6956        }
6957
6958        synchronized(this) {
6959            mWentToSleep = false;
6960            updateEventDispatchingLocked();
6961            comeOutOfSleepIfNeededLocked();
6962        }
6963    }
6964
6965    private void updateEventDispatchingLocked() {
6966        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6967    }
6968
6969    public void setLockScreenShown(boolean shown) {
6970        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6971                != PackageManager.PERMISSION_GRANTED) {
6972            throw new SecurityException("Requires permission "
6973                    + android.Manifest.permission.DEVICE_POWER);
6974        }
6975
6976        synchronized(this) {
6977            mLockScreenShown = shown;
6978            comeOutOfSleepIfNeededLocked();
6979        }
6980    }
6981
6982    public void stopAppSwitches() {
6983        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6984                != PackageManager.PERMISSION_GRANTED) {
6985            throw new SecurityException("Requires permission "
6986                    + android.Manifest.permission.STOP_APP_SWITCHES);
6987        }
6988
6989        synchronized(this) {
6990            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6991                    + APP_SWITCH_DELAY_TIME;
6992            mDidAppSwitch = false;
6993            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6994            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6995            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6996        }
6997    }
6998
6999    public void resumeAppSwitches() {
7000        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7001                != PackageManager.PERMISSION_GRANTED) {
7002            throw new SecurityException("Requires permission "
7003                    + android.Manifest.permission.STOP_APP_SWITCHES);
7004        }
7005
7006        synchronized(this) {
7007            // Note that we don't execute any pending app switches... we will
7008            // let those wait until either the timeout, or the next start
7009            // activity request.
7010            mAppSwitchesAllowedTime = 0;
7011        }
7012    }
7013
7014    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7015            String name) {
7016        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7017            return true;
7018        }
7019
7020        final int perm = checkComponentPermission(
7021                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7022                callingUid, -1, true);
7023        if (perm == PackageManager.PERMISSION_GRANTED) {
7024            return true;
7025        }
7026
7027        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7028        return false;
7029    }
7030
7031    public void setDebugApp(String packageName, boolean waitForDebugger,
7032            boolean persistent) {
7033        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7034                "setDebugApp()");
7035
7036        // Note that this is not really thread safe if there are multiple
7037        // callers into it at the same time, but that's not a situation we
7038        // care about.
7039        if (persistent) {
7040            final ContentResolver resolver = mContext.getContentResolver();
7041            Settings.System.putString(
7042                resolver, Settings.System.DEBUG_APP,
7043                packageName);
7044            Settings.System.putInt(
7045                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7046                waitForDebugger ? 1 : 0);
7047        }
7048
7049        synchronized (this) {
7050            if (!persistent) {
7051                mOrigDebugApp = mDebugApp;
7052                mOrigWaitForDebugger = mWaitForDebugger;
7053            }
7054            mDebugApp = packageName;
7055            mWaitForDebugger = waitForDebugger;
7056            mDebugTransient = !persistent;
7057            if (packageName != null) {
7058                final long origId = Binder.clearCallingIdentity();
7059                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7060                Binder.restoreCallingIdentity(origId);
7061            }
7062        }
7063    }
7064
7065    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7066        synchronized (this) {
7067            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7068            if (!isDebuggable) {
7069                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7070                    throw new SecurityException("Process not debuggable: " + app.packageName);
7071                }
7072            }
7073
7074            mOpenGlTraceApp = processName;
7075        }
7076    }
7077
7078    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7079            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7080        synchronized (this) {
7081            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7082            if (!isDebuggable) {
7083                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7084                    throw new SecurityException("Process not debuggable: " + app.packageName);
7085                }
7086            }
7087            mProfileApp = processName;
7088            mProfileFile = profileFile;
7089            if (mProfileFd != null) {
7090                try {
7091                    mProfileFd.close();
7092                } catch (IOException e) {
7093                }
7094                mProfileFd = null;
7095            }
7096            mProfileFd = profileFd;
7097            mProfileType = 0;
7098            mAutoStopProfiler = autoStopProfiler;
7099        }
7100    }
7101
7102    public void setAlwaysFinish(boolean enabled) {
7103        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7104                "setAlwaysFinish()");
7105
7106        Settings.System.putInt(
7107                mContext.getContentResolver(),
7108                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7109
7110        synchronized (this) {
7111            mAlwaysFinishActivities = enabled;
7112        }
7113    }
7114
7115    public void setActivityController(IActivityController controller) {
7116        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7117                "setActivityController()");
7118        synchronized (this) {
7119            mController = controller;
7120        }
7121    }
7122
7123    public boolean isUserAMonkey() {
7124        // For now the fact that there is a controller implies
7125        // we have a monkey.
7126        synchronized (this) {
7127            return mController != null;
7128        }
7129    }
7130
7131    public void registerProcessObserver(IProcessObserver observer) {
7132        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7133                "registerProcessObserver()");
7134        synchronized (this) {
7135            mProcessObservers.register(observer);
7136        }
7137    }
7138
7139    public void unregisterProcessObserver(IProcessObserver observer) {
7140        synchronized (this) {
7141            mProcessObservers.unregister(observer);
7142        }
7143    }
7144
7145    public void setImmersive(IBinder token, boolean immersive) {
7146        synchronized(this) {
7147            ActivityRecord r = mMainStack.isInStackLocked(token);
7148            if (r == null) {
7149                throw new IllegalArgumentException();
7150            }
7151            r.immersive = immersive;
7152        }
7153    }
7154
7155    public boolean isImmersive(IBinder token) {
7156        synchronized (this) {
7157            ActivityRecord r = mMainStack.isInStackLocked(token);
7158            if (r == null) {
7159                throw new IllegalArgumentException();
7160            }
7161            return r.immersive;
7162        }
7163    }
7164
7165    public boolean isTopActivityImmersive() {
7166        enforceNotIsolatedCaller("startActivity");
7167        synchronized (this) {
7168            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7169            return (r != null) ? r.immersive : false;
7170        }
7171    }
7172
7173    public final void enterSafeMode() {
7174        synchronized(this) {
7175            // It only makes sense to do this before the system is ready
7176            // and started launching other packages.
7177            if (!mSystemReady) {
7178                try {
7179                    AppGlobals.getPackageManager().enterSafeMode();
7180                } catch (RemoteException e) {
7181                }
7182            }
7183        }
7184    }
7185
7186    public final void showSafeModeOverlay() {
7187        View v = LayoutInflater.from(mContext).inflate(
7188                com.android.internal.R.layout.safe_mode, null);
7189        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7190        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7191        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7192        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7193        lp.gravity = Gravity.BOTTOM | Gravity.START;
7194        lp.format = v.getBackground().getOpacity();
7195        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7196                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7197        ((WindowManager)mContext.getSystemService(
7198                Context.WINDOW_SERVICE)).addView(v, lp);
7199    }
7200
7201    public void noteWakeupAlarm(IIntentSender sender) {
7202        if (!(sender instanceof PendingIntentRecord)) {
7203            return;
7204        }
7205        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7206        synchronized (stats) {
7207            if (mBatteryStatsService.isOnBattery()) {
7208                mBatteryStatsService.enforceCallingPermission();
7209                PendingIntentRecord rec = (PendingIntentRecord)sender;
7210                int MY_UID = Binder.getCallingUid();
7211                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7212                BatteryStatsImpl.Uid.Pkg pkg =
7213                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7214                pkg.incWakeupsLocked();
7215            }
7216        }
7217    }
7218
7219    public boolean killPids(int[] pids, String pReason, boolean secure) {
7220        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7221            throw new SecurityException("killPids only available to the system");
7222        }
7223        String reason = (pReason == null) ? "Unknown" : pReason;
7224        // XXX Note: don't acquire main activity lock here, because the window
7225        // manager calls in with its locks held.
7226
7227        boolean killed = false;
7228        synchronized (mPidsSelfLocked) {
7229            int[] types = new int[pids.length];
7230            int worstType = 0;
7231            for (int i=0; i<pids.length; i++) {
7232                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7233                if (proc != null) {
7234                    int type = proc.setAdj;
7235                    types[i] = type;
7236                    if (type > worstType) {
7237                        worstType = type;
7238                    }
7239                }
7240            }
7241
7242            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7243            // then constrain it so we will kill all hidden procs.
7244            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7245                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7246                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7247            }
7248
7249            // If this is not a secure call, don't let it kill processes that
7250            // are important.
7251            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7252                worstType = ProcessList.SERVICE_ADJ;
7253            }
7254
7255            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7256            for (int i=0; i<pids.length; i++) {
7257                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7258                if (proc == null) {
7259                    continue;
7260                }
7261                int adj = proc.setAdj;
7262                if (adj >= worstType && !proc.killedBackground) {
7263                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7264                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7265                            proc.processName, adj, reason);
7266                    killed = true;
7267                    proc.killedBackground = true;
7268                    Process.killProcessQuiet(pids[i]);
7269                }
7270            }
7271        }
7272        return killed;
7273    }
7274
7275    @Override
7276    public boolean killProcessesBelowForeground(String reason) {
7277        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7278            throw new SecurityException("killProcessesBelowForeground() only available to system");
7279        }
7280
7281        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7282    }
7283
7284    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7285        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7286            throw new SecurityException("killProcessesBelowAdj() only available to system");
7287        }
7288
7289        boolean killed = false;
7290        synchronized (mPidsSelfLocked) {
7291            final int size = mPidsSelfLocked.size();
7292            for (int i = 0; i < size; i++) {
7293                final int pid = mPidsSelfLocked.keyAt(i);
7294                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7295                if (proc == null) continue;
7296
7297                final int adj = proc.setAdj;
7298                if (adj > belowAdj && !proc.killedBackground) {
7299                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7300                    EventLog.writeEvent(
7301                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7302                    killed = true;
7303                    proc.killedBackground = true;
7304                    Process.killProcessQuiet(pid);
7305                }
7306            }
7307        }
7308        return killed;
7309    }
7310
7311    public final void startRunning(String pkg, String cls, String action,
7312            String data) {
7313        synchronized(this) {
7314            if (mStartRunning) {
7315                return;
7316            }
7317            mStartRunning = true;
7318            mTopComponent = pkg != null && cls != null
7319                    ? new ComponentName(pkg, cls) : null;
7320            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7321            mTopData = data;
7322            if (!mSystemReady) {
7323                return;
7324            }
7325        }
7326
7327        systemReady(null);
7328    }
7329
7330    private void retrieveSettings() {
7331        final ContentResolver resolver = mContext.getContentResolver();
7332        String debugApp = Settings.System.getString(
7333            resolver, Settings.System.DEBUG_APP);
7334        boolean waitForDebugger = Settings.System.getInt(
7335            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7336        boolean alwaysFinishActivities = Settings.System.getInt(
7337            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7338
7339        Configuration configuration = new Configuration();
7340        Settings.System.getConfiguration(resolver, configuration);
7341
7342        synchronized (this) {
7343            mDebugApp = mOrigDebugApp = debugApp;
7344            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7345            mAlwaysFinishActivities = alwaysFinishActivities;
7346            // This happens before any activities are started, so we can
7347            // change mConfiguration in-place.
7348            updateConfigurationLocked(configuration, null, false, true);
7349            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7350        }
7351    }
7352
7353    public boolean testIsSystemReady() {
7354        // no need to synchronize(this) just to read & return the value
7355        return mSystemReady;
7356    }
7357
7358    private static File getCalledPreBootReceiversFile() {
7359        File dataDir = Environment.getDataDirectory();
7360        File systemDir = new File(dataDir, "system");
7361        File fname = new File(systemDir, "called_pre_boots.dat");
7362        return fname;
7363    }
7364
7365    static final int LAST_DONE_VERSION = 10000;
7366
7367    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7368        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7369        File file = getCalledPreBootReceiversFile();
7370        FileInputStream fis = null;
7371        try {
7372            fis = new FileInputStream(file);
7373            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7374            int fvers = dis.readInt();
7375            if (fvers == LAST_DONE_VERSION) {
7376                String vers = dis.readUTF();
7377                String codename = dis.readUTF();
7378                String build = dis.readUTF();
7379                if (android.os.Build.VERSION.RELEASE.equals(vers)
7380                        && android.os.Build.VERSION.CODENAME.equals(codename)
7381                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7382                    int num = dis.readInt();
7383                    while (num > 0) {
7384                        num--;
7385                        String pkg = dis.readUTF();
7386                        String cls = dis.readUTF();
7387                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7388                    }
7389                }
7390            }
7391        } catch (FileNotFoundException e) {
7392        } catch (IOException e) {
7393            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7394        } finally {
7395            if (fis != null) {
7396                try {
7397                    fis.close();
7398                } catch (IOException e) {
7399                }
7400            }
7401        }
7402        return lastDoneReceivers;
7403    }
7404
7405    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7406        File file = getCalledPreBootReceiversFile();
7407        FileOutputStream fos = null;
7408        DataOutputStream dos = null;
7409        try {
7410            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7411            fos = new FileOutputStream(file);
7412            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7413            dos.writeInt(LAST_DONE_VERSION);
7414            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7415            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7416            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7417            dos.writeInt(list.size());
7418            for (int i=0; i<list.size(); i++) {
7419                dos.writeUTF(list.get(i).getPackageName());
7420                dos.writeUTF(list.get(i).getClassName());
7421            }
7422        } catch (IOException e) {
7423            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7424            file.delete();
7425        } finally {
7426            FileUtils.sync(fos);
7427            if (dos != null) {
7428                try {
7429                    dos.close();
7430                } catch (IOException e) {
7431                    // TODO Auto-generated catch block
7432                    e.printStackTrace();
7433                }
7434            }
7435        }
7436    }
7437
7438    public void systemReady(final Runnable goingCallback) {
7439        synchronized(this) {
7440            if (mSystemReady) {
7441                if (goingCallback != null) goingCallback.run();
7442                return;
7443            }
7444
7445            // Check to see if there are any update receivers to run.
7446            if (!mDidUpdate) {
7447                if (mWaitingUpdate) {
7448                    return;
7449                }
7450                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7451                List<ResolveInfo> ris = null;
7452                try {
7453                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7454                            intent, null, 0, 0);
7455                } catch (RemoteException e) {
7456                }
7457                if (ris != null) {
7458                    for (int i=ris.size()-1; i>=0; i--) {
7459                        if ((ris.get(i).activityInfo.applicationInfo.flags
7460                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7461                            ris.remove(i);
7462                        }
7463                    }
7464                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7465
7466                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7467
7468                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7469                    for (int i=0; i<ris.size(); i++) {
7470                        ActivityInfo ai = ris.get(i).activityInfo;
7471                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7472                        if (lastDoneReceivers.contains(comp)) {
7473                            ris.remove(i);
7474                            i--;
7475                        }
7476                    }
7477
7478                    for (int i=0; i<ris.size(); i++) {
7479                        ActivityInfo ai = ris.get(i).activityInfo;
7480                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7481                        doneReceivers.add(comp);
7482                        intent.setComponent(comp);
7483                        IIntentReceiver finisher = null;
7484                        if (i == ris.size()-1) {
7485                            finisher = new IIntentReceiver.Stub() {
7486                                public void performReceive(Intent intent, int resultCode,
7487                                        String data, Bundle extras, boolean ordered,
7488                                        boolean sticky) {
7489                                    // The raw IIntentReceiver interface is called
7490                                    // with the AM lock held, so redispatch to
7491                                    // execute our code without the lock.
7492                                    mHandler.post(new Runnable() {
7493                                        public void run() {
7494                                            synchronized (ActivityManagerService.this) {
7495                                                mDidUpdate = true;
7496                                            }
7497                                            writeLastDonePreBootReceivers(doneReceivers);
7498                                            showBootMessage(mContext.getText(
7499                                                    R.string.android_upgrading_complete),
7500                                                    false);
7501                                            systemReady(goingCallback);
7502                                        }
7503                                    });
7504                                }
7505                            };
7506                        }
7507                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7508                        /* TODO: Send this to all users */
7509                        broadcastIntentLocked(null, null, intent, null, finisher,
7510                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7511                                0 /* UserId zero */);
7512                        if (finisher != null) {
7513                            mWaitingUpdate = true;
7514                        }
7515                    }
7516                }
7517                if (mWaitingUpdate) {
7518                    return;
7519                }
7520                mDidUpdate = true;
7521            }
7522
7523            mSystemReady = true;
7524            if (!mStartRunning) {
7525                return;
7526            }
7527        }
7528
7529        ArrayList<ProcessRecord> procsToKill = null;
7530        synchronized(mPidsSelfLocked) {
7531            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7532                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7533                if (!isAllowedWhileBooting(proc.info)){
7534                    if (procsToKill == null) {
7535                        procsToKill = new ArrayList<ProcessRecord>();
7536                    }
7537                    procsToKill.add(proc);
7538                }
7539            }
7540        }
7541
7542        synchronized(this) {
7543            if (procsToKill != null) {
7544                for (int i=procsToKill.size()-1; i>=0; i--) {
7545                    ProcessRecord proc = procsToKill.get(i);
7546                    Slog.i(TAG, "Removing system update proc: " + proc);
7547                    removeProcessLocked(proc, true, false, "system update done");
7548                }
7549            }
7550
7551            // Now that we have cleaned up any update processes, we
7552            // are ready to start launching real processes and know that
7553            // we won't trample on them any more.
7554            mProcessesReady = true;
7555        }
7556
7557        Slog.i(TAG, "System now ready");
7558        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7559            SystemClock.uptimeMillis());
7560
7561        synchronized(this) {
7562            // Make sure we have no pre-ready processes sitting around.
7563
7564            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7565                ResolveInfo ri = mContext.getPackageManager()
7566                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7567                                STOCK_PM_FLAGS);
7568                CharSequence errorMsg = null;
7569                if (ri != null) {
7570                    ActivityInfo ai = ri.activityInfo;
7571                    ApplicationInfo app = ai.applicationInfo;
7572                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7573                        mTopAction = Intent.ACTION_FACTORY_TEST;
7574                        mTopData = null;
7575                        mTopComponent = new ComponentName(app.packageName,
7576                                ai.name);
7577                    } else {
7578                        errorMsg = mContext.getResources().getText(
7579                                com.android.internal.R.string.factorytest_not_system);
7580                    }
7581                } else {
7582                    errorMsg = mContext.getResources().getText(
7583                            com.android.internal.R.string.factorytest_no_action);
7584                }
7585                if (errorMsg != null) {
7586                    mTopAction = null;
7587                    mTopData = null;
7588                    mTopComponent = null;
7589                    Message msg = Message.obtain();
7590                    msg.what = SHOW_FACTORY_ERROR_MSG;
7591                    msg.getData().putCharSequence("msg", errorMsg);
7592                    mHandler.sendMessage(msg);
7593                }
7594            }
7595        }
7596
7597        retrieveSettings();
7598
7599        if (goingCallback != null) goingCallback.run();
7600
7601        synchronized (this) {
7602            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7603                try {
7604                    List apps = AppGlobals.getPackageManager().
7605                        getPersistentApplications(STOCK_PM_FLAGS);
7606                    if (apps != null) {
7607                        int N = apps.size();
7608                        int i;
7609                        for (i=0; i<N; i++) {
7610                            ApplicationInfo info
7611                                = (ApplicationInfo)apps.get(i);
7612                            if (info != null &&
7613                                    !info.packageName.equals("android")) {
7614                                addAppLocked(info, false);
7615                            }
7616                        }
7617                    }
7618                } catch (RemoteException ex) {
7619                    // pm is in same process, this will never happen.
7620                }
7621            }
7622
7623            // Start up initial activity.
7624            mBooting = true;
7625
7626            try {
7627                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7628                    Message msg = Message.obtain();
7629                    msg.what = SHOW_UID_ERROR_MSG;
7630                    mHandler.sendMessage(msg);
7631                }
7632            } catch (RemoteException e) {
7633            }
7634
7635            mMainStack.resumeTopActivityLocked(null);
7636        }
7637    }
7638
7639    private boolean makeAppCrashingLocked(ProcessRecord app,
7640            String shortMsg, String longMsg, String stackTrace) {
7641        app.crashing = true;
7642        app.crashingReport = generateProcessError(app,
7643                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7644        startAppProblemLocked(app);
7645        app.stopFreezingAllLocked();
7646        return handleAppCrashLocked(app);
7647    }
7648
7649    private void makeAppNotRespondingLocked(ProcessRecord app,
7650            String activity, String shortMsg, String longMsg) {
7651        app.notResponding = true;
7652        app.notRespondingReport = generateProcessError(app,
7653                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7654                activity, shortMsg, longMsg, null);
7655        startAppProblemLocked(app);
7656        app.stopFreezingAllLocked();
7657    }
7658
7659    /**
7660     * Generate a process error record, suitable for attachment to a ProcessRecord.
7661     *
7662     * @param app The ProcessRecord in which the error occurred.
7663     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7664     *                      ActivityManager.AppErrorStateInfo
7665     * @param activity The activity associated with the crash, if known.
7666     * @param shortMsg Short message describing the crash.
7667     * @param longMsg Long message describing the crash.
7668     * @param stackTrace Full crash stack trace, may be null.
7669     *
7670     * @return Returns a fully-formed AppErrorStateInfo record.
7671     */
7672    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7673            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7674        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7675
7676        report.condition = condition;
7677        report.processName = app.processName;
7678        report.pid = app.pid;
7679        report.uid = app.info.uid;
7680        report.tag = activity;
7681        report.shortMsg = shortMsg;
7682        report.longMsg = longMsg;
7683        report.stackTrace = stackTrace;
7684
7685        return report;
7686    }
7687
7688    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7689        synchronized (this) {
7690            app.crashing = false;
7691            app.crashingReport = null;
7692            app.notResponding = false;
7693            app.notRespondingReport = null;
7694            if (app.anrDialog == fromDialog) {
7695                app.anrDialog = null;
7696            }
7697            if (app.waitDialog == fromDialog) {
7698                app.waitDialog = null;
7699            }
7700            if (app.pid > 0 && app.pid != MY_PID) {
7701                handleAppCrashLocked(app);
7702                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7703                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7704                        app.processName, app.setAdj, "user's request after error");
7705                Process.killProcessQuiet(app.pid);
7706            }
7707        }
7708    }
7709
7710    private boolean handleAppCrashLocked(ProcessRecord app) {
7711        if (mHeadless) {
7712            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7713            return false;
7714        }
7715        long now = SystemClock.uptimeMillis();
7716
7717        Long crashTime;
7718        if (!app.isolated) {
7719            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7720        } else {
7721            crashTime = null;
7722        }
7723        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7724            // This process loses!
7725            Slog.w(TAG, "Process " + app.info.processName
7726                    + " has crashed too many times: killing!");
7727            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7728                    app.info.processName, app.uid);
7729            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7730                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7731                if (r.app == app) {
7732                    Slog.w(TAG, "  Force finishing activity "
7733                        + r.intent.getComponent().flattenToShortString());
7734                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7735                }
7736            }
7737            if (!app.persistent) {
7738                // We don't want to start this process again until the user
7739                // explicitly does so...  but for persistent process, we really
7740                // need to keep it running.  If a persistent process is actually
7741                // repeatedly crashing, then badness for everyone.
7742                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7743                        app.info.processName);
7744                if (!app.isolated) {
7745                    // XXX We don't have a way to mark isolated processes
7746                    // as bad, since they don't have a peristent identity.
7747                    mBadProcesses.put(app.info.processName, app.uid, now);
7748                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7749                }
7750                app.bad = true;
7751                app.removed = true;
7752                // Don't let services in this process be restarted and potentially
7753                // annoy the user repeatedly.  Unless it is persistent, since those
7754                // processes run critical code.
7755                removeProcessLocked(app, false, false, "crash");
7756                mMainStack.resumeTopActivityLocked(null);
7757                return false;
7758            }
7759            mMainStack.resumeTopActivityLocked(null);
7760        } else {
7761            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7762            if (r != null && r.app == app) {
7763                // If the top running activity is from this crashing
7764                // process, then terminate it to avoid getting in a loop.
7765                Slog.w(TAG, "  Force finishing activity "
7766                        + r.intent.getComponent().flattenToShortString());
7767                int index = mMainStack.indexOfActivityLocked(r);
7768                r.stack.finishActivityLocked(r, index,
7769                        Activity.RESULT_CANCELED, null, "crashed");
7770                // Also terminate any activities below it that aren't yet
7771                // stopped, to avoid a situation where one will get
7772                // re-start our crashing activity once it gets resumed again.
7773                index--;
7774                if (index >= 0) {
7775                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7776                    if (r.state == ActivityState.RESUMED
7777                            || r.state == ActivityState.PAUSING
7778                            || r.state == ActivityState.PAUSED) {
7779                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7780                            Slog.w(TAG, "  Force finishing activity "
7781                                    + r.intent.getComponent().flattenToShortString());
7782                            r.stack.finishActivityLocked(r, index,
7783                                    Activity.RESULT_CANCELED, null, "crashed");
7784                        }
7785                    }
7786                }
7787            }
7788        }
7789
7790        // Bump up the crash count of any services currently running in the proc.
7791        if (app.services.size() != 0) {
7792            // Any services running in the application need to be placed
7793            // back in the pending list.
7794            Iterator<ServiceRecord> it = app.services.iterator();
7795            while (it.hasNext()) {
7796                ServiceRecord sr = it.next();
7797                sr.crashCount++;
7798            }
7799        }
7800
7801        // If the crashing process is what we consider to be the "home process" and it has been
7802        // replaced by a third-party app, clear the package preferred activities from packages
7803        // with a home activity running in the process to prevent a repeatedly crashing app
7804        // from blocking the user to manually clear the list.
7805        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7806                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7807            Iterator it = mHomeProcess.activities.iterator();
7808            while (it.hasNext()) {
7809                ActivityRecord r = (ActivityRecord)it.next();
7810                if (r.isHomeActivity) {
7811                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7812                    try {
7813                        ActivityThread.getPackageManager()
7814                                .clearPackagePreferredActivities(r.packageName);
7815                    } catch (RemoteException c) {
7816                        // pm is in same process, this will never happen.
7817                    }
7818                }
7819            }
7820        }
7821
7822        if (!app.isolated) {
7823            // XXX Can't keep track of crash times for isolated processes,
7824            // because they don't have a perisistent identity.
7825            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7826        }
7827
7828        return true;
7829    }
7830
7831    void startAppProblemLocked(ProcessRecord app) {
7832        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7833                mContext, app.info.packageName, app.info.flags);
7834        skipCurrentReceiverLocked(app);
7835    }
7836
7837    void skipCurrentReceiverLocked(ProcessRecord app) {
7838        for (BroadcastQueue queue : mBroadcastQueues) {
7839            queue.skipCurrentReceiverLocked(app);
7840        }
7841    }
7842
7843    /**
7844     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7845     * The application process will exit immediately after this call returns.
7846     * @param app object of the crashing app, null for the system server
7847     * @param crashInfo describing the exception
7848     */
7849    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7850        ProcessRecord r = findAppProcess(app, "Crash");
7851        final String processName = app == null ? "system_server"
7852                : (r == null ? "unknown" : r.processName);
7853
7854        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7855                processName,
7856                r == null ? -1 : r.info.flags,
7857                crashInfo.exceptionClassName,
7858                crashInfo.exceptionMessage,
7859                crashInfo.throwFileName,
7860                crashInfo.throwLineNumber);
7861
7862        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7863
7864        crashApplication(r, crashInfo);
7865    }
7866
7867    public void handleApplicationStrictModeViolation(
7868            IBinder app,
7869            int violationMask,
7870            StrictMode.ViolationInfo info) {
7871        ProcessRecord r = findAppProcess(app, "StrictMode");
7872        if (r == null) {
7873            return;
7874        }
7875
7876        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7877            Integer stackFingerprint = info.hashCode();
7878            boolean logIt = true;
7879            synchronized (mAlreadyLoggedViolatedStacks) {
7880                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7881                    logIt = false;
7882                    // TODO: sub-sample into EventLog for these, with
7883                    // the info.durationMillis?  Then we'd get
7884                    // the relative pain numbers, without logging all
7885                    // the stack traces repeatedly.  We'd want to do
7886                    // likewise in the client code, which also does
7887                    // dup suppression, before the Binder call.
7888                } else {
7889                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7890                        mAlreadyLoggedViolatedStacks.clear();
7891                    }
7892                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7893                }
7894            }
7895            if (logIt) {
7896                logStrictModeViolationToDropBox(r, info);
7897            }
7898        }
7899
7900        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7901            AppErrorResult result = new AppErrorResult();
7902            synchronized (this) {
7903                final long origId = Binder.clearCallingIdentity();
7904
7905                Message msg = Message.obtain();
7906                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7907                HashMap<String, Object> data = new HashMap<String, Object>();
7908                data.put("result", result);
7909                data.put("app", r);
7910                data.put("violationMask", violationMask);
7911                data.put("info", info);
7912                msg.obj = data;
7913                mHandler.sendMessage(msg);
7914
7915                Binder.restoreCallingIdentity(origId);
7916            }
7917            int res = result.get();
7918            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7919        }
7920    }
7921
7922    // Depending on the policy in effect, there could be a bunch of
7923    // these in quick succession so we try to batch these together to
7924    // minimize disk writes, number of dropbox entries, and maximize
7925    // compression, by having more fewer, larger records.
7926    private void logStrictModeViolationToDropBox(
7927            ProcessRecord process,
7928            StrictMode.ViolationInfo info) {
7929        if (info == null) {
7930            return;
7931        }
7932        final boolean isSystemApp = process == null ||
7933                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7934                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7935        final String processName = process == null ? "unknown" : process.processName;
7936        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7937        final DropBoxManager dbox = (DropBoxManager)
7938                mContext.getSystemService(Context.DROPBOX_SERVICE);
7939
7940        // Exit early if the dropbox isn't configured to accept this report type.
7941        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7942
7943        boolean bufferWasEmpty;
7944        boolean needsFlush;
7945        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7946        synchronized (sb) {
7947            bufferWasEmpty = sb.length() == 0;
7948            appendDropBoxProcessHeaders(process, processName, sb);
7949            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7950            sb.append("System-App: ").append(isSystemApp).append("\n");
7951            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7952            if (info.violationNumThisLoop != 0) {
7953                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7954            }
7955            if (info.numAnimationsRunning != 0) {
7956                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7957            }
7958            if (info.broadcastIntentAction != null) {
7959                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7960            }
7961            if (info.durationMillis != -1) {
7962                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7963            }
7964            if (info.numInstances != -1) {
7965                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7966            }
7967            if (info.tags != null) {
7968                for (String tag : info.tags) {
7969                    sb.append("Span-Tag: ").append(tag).append("\n");
7970                }
7971            }
7972            sb.append("\n");
7973            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7974                sb.append(info.crashInfo.stackTrace);
7975            }
7976            sb.append("\n");
7977
7978            // Only buffer up to ~64k.  Various logging bits truncate
7979            // things at 128k.
7980            needsFlush = (sb.length() > 64 * 1024);
7981        }
7982
7983        // Flush immediately if the buffer's grown too large, or this
7984        // is a non-system app.  Non-system apps are isolated with a
7985        // different tag & policy and not batched.
7986        //
7987        // Batching is useful during internal testing with
7988        // StrictMode settings turned up high.  Without batching,
7989        // thousands of separate files could be created on boot.
7990        if (!isSystemApp || needsFlush) {
7991            new Thread("Error dump: " + dropboxTag) {
7992                @Override
7993                public void run() {
7994                    String report;
7995                    synchronized (sb) {
7996                        report = sb.toString();
7997                        sb.delete(0, sb.length());
7998                        sb.trimToSize();
7999                    }
8000                    if (report.length() != 0) {
8001                        dbox.addText(dropboxTag, report);
8002                    }
8003                }
8004            }.start();
8005            return;
8006        }
8007
8008        // System app batching:
8009        if (!bufferWasEmpty) {
8010            // An existing dropbox-writing thread is outstanding, so
8011            // we don't need to start it up.  The existing thread will
8012            // catch the buffer appends we just did.
8013            return;
8014        }
8015
8016        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8017        // (After this point, we shouldn't access AMS internal data structures.)
8018        new Thread("Error dump: " + dropboxTag) {
8019            @Override
8020            public void run() {
8021                // 5 second sleep to let stacks arrive and be batched together
8022                try {
8023                    Thread.sleep(5000);  // 5 seconds
8024                } catch (InterruptedException e) {}
8025
8026                String errorReport;
8027                synchronized (mStrictModeBuffer) {
8028                    errorReport = mStrictModeBuffer.toString();
8029                    if (errorReport.length() == 0) {
8030                        return;
8031                    }
8032                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8033                    mStrictModeBuffer.trimToSize();
8034                }
8035                dbox.addText(dropboxTag, errorReport);
8036            }
8037        }.start();
8038    }
8039
8040    /**
8041     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8042     * @param app object of the crashing app, null for the system server
8043     * @param tag reported by the caller
8044     * @param crashInfo describing the context of the error
8045     * @return true if the process should exit immediately (WTF is fatal)
8046     */
8047    public boolean handleApplicationWtf(IBinder app, String tag,
8048            ApplicationErrorReport.CrashInfo crashInfo) {
8049        ProcessRecord r = findAppProcess(app, "WTF");
8050        final String processName = app == null ? "system_server"
8051                : (r == null ? "unknown" : r.processName);
8052
8053        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8054                processName,
8055                r == null ? -1 : r.info.flags,
8056                tag, crashInfo.exceptionMessage);
8057
8058        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8059
8060        if (r != null && r.pid != Process.myPid() &&
8061                Settings.Secure.getInt(mContext.getContentResolver(),
8062                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8063            crashApplication(r, crashInfo);
8064            return true;
8065        } else {
8066            return false;
8067        }
8068    }
8069
8070    /**
8071     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8072     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8073     */
8074    private ProcessRecord findAppProcess(IBinder app, String reason) {
8075        if (app == null) {
8076            return null;
8077        }
8078
8079        synchronized (this) {
8080            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8081                final int NA = apps.size();
8082                for (int ia=0; ia<NA; ia++) {
8083                    ProcessRecord p = apps.valueAt(ia);
8084                    if (p.thread != null && p.thread.asBinder() == app) {
8085                        return p;
8086                    }
8087                }
8088            }
8089
8090            Slog.w(TAG, "Can't find mystery application for " + reason
8091                    + " from pid=" + Binder.getCallingPid()
8092                    + " uid=" + Binder.getCallingUid() + ": " + app);
8093            return null;
8094        }
8095    }
8096
8097    /**
8098     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8099     * to append various headers to the dropbox log text.
8100     */
8101    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8102            StringBuilder sb) {
8103        // Watchdog thread ends up invoking this function (with
8104        // a null ProcessRecord) to add the stack file to dropbox.
8105        // Do not acquire a lock on this (am) in such cases, as it
8106        // could cause a potential deadlock, if and when watchdog
8107        // is invoked due to unavailability of lock on am and it
8108        // would prevent watchdog from killing system_server.
8109        if (process == null) {
8110            sb.append("Process: ").append(processName).append("\n");
8111            return;
8112        }
8113        // Note: ProcessRecord 'process' is guarded by the service
8114        // instance.  (notably process.pkgList, which could otherwise change
8115        // concurrently during execution of this method)
8116        synchronized (this) {
8117            sb.append("Process: ").append(processName).append("\n");
8118            int flags = process.info.flags;
8119            IPackageManager pm = AppGlobals.getPackageManager();
8120            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8121            for (String pkg : process.pkgList) {
8122                sb.append("Package: ").append(pkg);
8123                try {
8124                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8125                    if (pi != null) {
8126                        sb.append(" v").append(pi.versionCode);
8127                        if (pi.versionName != null) {
8128                            sb.append(" (").append(pi.versionName).append(")");
8129                        }
8130                    }
8131                } catch (RemoteException e) {
8132                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8133                }
8134                sb.append("\n");
8135            }
8136        }
8137    }
8138
8139    private static String processClass(ProcessRecord process) {
8140        if (process == null || process.pid == MY_PID) {
8141            return "system_server";
8142        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8143            return "system_app";
8144        } else {
8145            return "data_app";
8146        }
8147    }
8148
8149    /**
8150     * Write a description of an error (crash, WTF, ANR) to the drop box.
8151     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8152     * @param process which caused the error, null means the system server
8153     * @param activity which triggered the error, null if unknown
8154     * @param parent activity related to the error, null if unknown
8155     * @param subject line related to the error, null if absent
8156     * @param report in long form describing the error, null if absent
8157     * @param logFile to include in the report, null if none
8158     * @param crashInfo giving an application stack trace, null if absent
8159     */
8160    public void addErrorToDropBox(String eventType,
8161            ProcessRecord process, String processName, ActivityRecord activity,
8162            ActivityRecord parent, String subject,
8163            final String report, final File logFile,
8164            final ApplicationErrorReport.CrashInfo crashInfo) {
8165        // NOTE -- this must never acquire the ActivityManagerService lock,
8166        // otherwise the watchdog may be prevented from resetting the system.
8167
8168        final String dropboxTag = processClass(process) + "_" + eventType;
8169        final DropBoxManager dbox = (DropBoxManager)
8170                mContext.getSystemService(Context.DROPBOX_SERVICE);
8171
8172        // Exit early if the dropbox isn't configured to accept this report type.
8173        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8174
8175        final StringBuilder sb = new StringBuilder(1024);
8176        appendDropBoxProcessHeaders(process, processName, sb);
8177        if (activity != null) {
8178            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8179        }
8180        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8181            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8182        }
8183        if (parent != null && parent != activity) {
8184            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8185        }
8186        if (subject != null) {
8187            sb.append("Subject: ").append(subject).append("\n");
8188        }
8189        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8190        if (Debug.isDebuggerConnected()) {
8191            sb.append("Debugger: Connected\n");
8192        }
8193        sb.append("\n");
8194
8195        // Do the rest in a worker thread to avoid blocking the caller on I/O
8196        // (After this point, we shouldn't access AMS internal data structures.)
8197        Thread worker = new Thread("Error dump: " + dropboxTag) {
8198            @Override
8199            public void run() {
8200                if (report != null) {
8201                    sb.append(report);
8202                }
8203                if (logFile != null) {
8204                    try {
8205                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8206                    } catch (IOException e) {
8207                        Slog.e(TAG, "Error reading " + logFile, e);
8208                    }
8209                }
8210                if (crashInfo != null && crashInfo.stackTrace != null) {
8211                    sb.append(crashInfo.stackTrace);
8212                }
8213
8214                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8215                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8216                if (lines > 0) {
8217                    sb.append("\n");
8218
8219                    // Merge several logcat streams, and take the last N lines
8220                    InputStreamReader input = null;
8221                    try {
8222                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8223                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8224                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8225
8226                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8227                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8228                        input = new InputStreamReader(logcat.getInputStream());
8229
8230                        int num;
8231                        char[] buf = new char[8192];
8232                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8233                    } catch (IOException e) {
8234                        Slog.e(TAG, "Error running logcat", e);
8235                    } finally {
8236                        if (input != null) try { input.close(); } catch (IOException e) {}
8237                    }
8238                }
8239
8240                dbox.addText(dropboxTag, sb.toString());
8241            }
8242        };
8243
8244        if (process == null) {
8245            // If process is null, we are being called from some internal code
8246            // and may be about to die -- run this synchronously.
8247            worker.run();
8248        } else {
8249            worker.start();
8250        }
8251    }
8252
8253    /**
8254     * Bring up the "unexpected error" dialog box for a crashing app.
8255     * Deal with edge cases (intercepts from instrumented applications,
8256     * ActivityController, error intent receivers, that sort of thing).
8257     * @param r the application crashing
8258     * @param crashInfo describing the failure
8259     */
8260    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8261        long timeMillis = System.currentTimeMillis();
8262        String shortMsg = crashInfo.exceptionClassName;
8263        String longMsg = crashInfo.exceptionMessage;
8264        String stackTrace = crashInfo.stackTrace;
8265        if (shortMsg != null && longMsg != null) {
8266            longMsg = shortMsg + ": " + longMsg;
8267        } else if (shortMsg != null) {
8268            longMsg = shortMsg;
8269        }
8270
8271        AppErrorResult result = new AppErrorResult();
8272        synchronized (this) {
8273            if (mController != null) {
8274                try {
8275                    String name = r != null ? r.processName : null;
8276                    int pid = r != null ? r.pid : Binder.getCallingPid();
8277                    if (!mController.appCrashed(name, pid,
8278                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8279                        Slog.w(TAG, "Force-killing crashed app " + name
8280                                + " at watcher's request");
8281                        Process.killProcess(pid);
8282                        return;
8283                    }
8284                } catch (RemoteException e) {
8285                    mController = null;
8286                }
8287            }
8288
8289            final long origId = Binder.clearCallingIdentity();
8290
8291            // If this process is running instrumentation, finish it.
8292            if (r != null && r.instrumentationClass != null) {
8293                Slog.w(TAG, "Error in app " + r.processName
8294                      + " running instrumentation " + r.instrumentationClass + ":");
8295                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8296                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8297                Bundle info = new Bundle();
8298                info.putString("shortMsg", shortMsg);
8299                info.putString("longMsg", longMsg);
8300                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8301                Binder.restoreCallingIdentity(origId);
8302                return;
8303            }
8304
8305            // If we can't identify the process or it's already exceeded its crash quota,
8306            // quit right away without showing a crash dialog.
8307            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8308                Binder.restoreCallingIdentity(origId);
8309                return;
8310            }
8311
8312            Message msg = Message.obtain();
8313            msg.what = SHOW_ERROR_MSG;
8314            HashMap data = new HashMap();
8315            data.put("result", result);
8316            data.put("app", r);
8317            msg.obj = data;
8318            mHandler.sendMessage(msg);
8319
8320            Binder.restoreCallingIdentity(origId);
8321        }
8322
8323        int res = result.get();
8324
8325        Intent appErrorIntent = null;
8326        synchronized (this) {
8327            if (r != null && !r.isolated) {
8328                // XXX Can't keep track of crash time for isolated processes,
8329                // since they don't have a persistent identity.
8330                mProcessCrashTimes.put(r.info.processName, r.uid,
8331                        SystemClock.uptimeMillis());
8332            }
8333            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8334                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8335            }
8336        }
8337
8338        if (appErrorIntent != null) {
8339            try {
8340                mContext.startActivity(appErrorIntent);
8341            } catch (ActivityNotFoundException e) {
8342                Slog.w(TAG, "bug report receiver dissappeared", e);
8343            }
8344        }
8345    }
8346
8347    Intent createAppErrorIntentLocked(ProcessRecord r,
8348            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8349        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8350        if (report == null) {
8351            return null;
8352        }
8353        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8354        result.setComponent(r.errorReportReceiver);
8355        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8356        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8357        return result;
8358    }
8359
8360    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8361            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8362        if (r.errorReportReceiver == null) {
8363            return null;
8364        }
8365
8366        if (!r.crashing && !r.notResponding) {
8367            return null;
8368        }
8369
8370        ApplicationErrorReport report = new ApplicationErrorReport();
8371        report.packageName = r.info.packageName;
8372        report.installerPackageName = r.errorReportReceiver.getPackageName();
8373        report.processName = r.processName;
8374        report.time = timeMillis;
8375        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8376
8377        if (r.crashing) {
8378            report.type = ApplicationErrorReport.TYPE_CRASH;
8379            report.crashInfo = crashInfo;
8380        } else if (r.notResponding) {
8381            report.type = ApplicationErrorReport.TYPE_ANR;
8382            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8383
8384            report.anrInfo.activity = r.notRespondingReport.tag;
8385            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8386            report.anrInfo.info = r.notRespondingReport.longMsg;
8387        }
8388
8389        return report;
8390    }
8391
8392    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8393        enforceNotIsolatedCaller("getProcessesInErrorState");
8394        // assume our apps are happy - lazy create the list
8395        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8396
8397        final boolean allUsers = ActivityManager.checkUidPermission(
8398                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8399                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8400        int userId = UserHandle.getUserId(Binder.getCallingUid());
8401
8402        synchronized (this) {
8403
8404            // iterate across all processes
8405            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8406                ProcessRecord app = mLruProcesses.get(i);
8407                if (!allUsers && app.userId != userId) {
8408                    continue;
8409                }
8410                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8411                    // This one's in trouble, so we'll generate a report for it
8412                    // crashes are higher priority (in case there's a crash *and* an anr)
8413                    ActivityManager.ProcessErrorStateInfo report = null;
8414                    if (app.crashing) {
8415                        report = app.crashingReport;
8416                    } else if (app.notResponding) {
8417                        report = app.notRespondingReport;
8418                    }
8419
8420                    if (report != null) {
8421                        if (errList == null) {
8422                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8423                        }
8424                        errList.add(report);
8425                    } else {
8426                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8427                                " crashing = " + app.crashing +
8428                                " notResponding = " + app.notResponding);
8429                    }
8430                }
8431            }
8432        }
8433
8434        return errList;
8435    }
8436
8437    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8438        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8439            if (currApp != null) {
8440                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8441            }
8442            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8443        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8444            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8445        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8446            if (currApp != null) {
8447                currApp.lru = 0;
8448            }
8449            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8450        } else if (adj >= ProcessList.SERVICE_ADJ) {
8451            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8452        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8453            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8454        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8455            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8456        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8457            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8458        } else {
8459            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8460        }
8461    }
8462
8463    private void fillInProcMemInfo(ProcessRecord app,
8464            ActivityManager.RunningAppProcessInfo outInfo) {
8465        outInfo.pid = app.pid;
8466        outInfo.uid = app.info.uid;
8467        if (mHeavyWeightProcess == app) {
8468            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8469        }
8470        if (app.persistent) {
8471            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8472        }
8473        if (app.hasActivities) {
8474            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8475        }
8476        outInfo.lastTrimLevel = app.trimMemoryLevel;
8477        int adj = app.curAdj;
8478        outInfo.importance = oomAdjToImportance(adj, outInfo);
8479        outInfo.importanceReasonCode = app.adjTypeCode;
8480    }
8481
8482    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8483        enforceNotIsolatedCaller("getRunningAppProcesses");
8484        // Lazy instantiation of list
8485        List<ActivityManager.RunningAppProcessInfo> runList = null;
8486        final boolean allUsers = ActivityManager.checkUidPermission(
8487                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8488                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8489        int userId = UserHandle.getUserId(Binder.getCallingUid());
8490        synchronized (this) {
8491            // Iterate across all processes
8492            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8493                ProcessRecord app = mLruProcesses.get(i);
8494                if (!allUsers && app.userId != userId) {
8495                    continue;
8496                }
8497                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8498                    // Generate process state info for running application
8499                    ActivityManager.RunningAppProcessInfo currApp =
8500                        new ActivityManager.RunningAppProcessInfo(app.processName,
8501                                app.pid, app.getPackageList());
8502                    fillInProcMemInfo(app, currApp);
8503                    if (app.adjSource instanceof ProcessRecord) {
8504                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8505                        currApp.importanceReasonImportance = oomAdjToImportance(
8506                                app.adjSourceOom, null);
8507                    } else if (app.adjSource instanceof ActivityRecord) {
8508                        ActivityRecord r = (ActivityRecord)app.adjSource;
8509                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8510                    }
8511                    if (app.adjTarget instanceof ComponentName) {
8512                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8513                    }
8514                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8515                    //        + " lru=" + currApp.lru);
8516                    if (runList == null) {
8517                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8518                    }
8519                    runList.add(currApp);
8520                }
8521            }
8522        }
8523        return runList;
8524    }
8525
8526    public List<ApplicationInfo> getRunningExternalApplications() {
8527        enforceNotIsolatedCaller("getRunningExternalApplications");
8528        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8529        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8530        if (runningApps != null && runningApps.size() > 0) {
8531            Set<String> extList = new HashSet<String>();
8532            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8533                if (app.pkgList != null) {
8534                    for (String pkg : app.pkgList) {
8535                        extList.add(pkg);
8536                    }
8537                }
8538            }
8539            IPackageManager pm = AppGlobals.getPackageManager();
8540            for (String pkg : extList) {
8541                try {
8542                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8543                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8544                        retList.add(info);
8545                    }
8546                } catch (RemoteException e) {
8547                }
8548            }
8549        }
8550        return retList;
8551    }
8552
8553    @Override
8554    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8555        enforceNotIsolatedCaller("getMyMemoryState");
8556        synchronized (this) {
8557            ProcessRecord proc;
8558            synchronized (mPidsSelfLocked) {
8559                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8560            }
8561            fillInProcMemInfo(proc, outInfo);
8562        }
8563    }
8564
8565    @Override
8566    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8567        if (checkCallingPermission(android.Manifest.permission.DUMP)
8568                != PackageManager.PERMISSION_GRANTED) {
8569            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8570                    + Binder.getCallingPid()
8571                    + ", uid=" + Binder.getCallingUid()
8572                    + " without permission "
8573                    + android.Manifest.permission.DUMP);
8574            return;
8575        }
8576
8577        boolean dumpAll = false;
8578        boolean dumpClient = false;
8579        String dumpPackage = null;
8580
8581        int opti = 0;
8582        while (opti < args.length) {
8583            String opt = args[opti];
8584            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8585                break;
8586            }
8587            opti++;
8588            if ("-a".equals(opt)) {
8589                dumpAll = true;
8590            } else if ("-c".equals(opt)) {
8591                dumpClient = true;
8592            } else if ("-h".equals(opt)) {
8593                pw.println("Activity manager dump options:");
8594                pw.println("  [-a] [-c] [-h] [cmd] ...");
8595                pw.println("  cmd may be one of:");
8596                pw.println("    a[ctivities]: activity stack state");
8597                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8598                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8599                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8600                pw.println("    o[om]: out of memory management");
8601                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8602                pw.println("    provider [COMP_SPEC]: provider client-side state");
8603                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8604                pw.println("    service [COMP_SPEC]: service client-side state");
8605                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8606                pw.println("    all: dump all activities");
8607                pw.println("    top: dump the top activity");
8608                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8609                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8610                pw.println("    a partial substring in a component name, a");
8611                pw.println("    hex object identifier.");
8612                pw.println("  -a: include all available server state.");
8613                pw.println("  -c: include client state.");
8614                return;
8615            } else {
8616                pw.println("Unknown argument: " + opt + "; use -h for help");
8617            }
8618        }
8619
8620        long origId = Binder.clearCallingIdentity();
8621        boolean more = false;
8622        // Is the caller requesting to dump a particular piece of data?
8623        if (opti < args.length) {
8624            String cmd = args[opti];
8625            opti++;
8626            if ("activities".equals(cmd) || "a".equals(cmd)) {
8627                synchronized (this) {
8628                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8629                }
8630            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8631                String[] newArgs;
8632                String name;
8633                if (opti >= args.length) {
8634                    name = null;
8635                    newArgs = EMPTY_STRING_ARRAY;
8636                } else {
8637                    name = args[opti];
8638                    opti++;
8639                    newArgs = new String[args.length - opti];
8640                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8641                            args.length - opti);
8642                }
8643                synchronized (this) {
8644                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8645                }
8646            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8647                String[] newArgs;
8648                String name;
8649                if (opti >= args.length) {
8650                    name = null;
8651                    newArgs = EMPTY_STRING_ARRAY;
8652                } else {
8653                    name = args[opti];
8654                    opti++;
8655                    newArgs = new String[args.length - opti];
8656                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8657                            args.length - opti);
8658                }
8659                synchronized (this) {
8660                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8661                }
8662            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8663                String[] newArgs;
8664                String name;
8665                if (opti >= args.length) {
8666                    name = null;
8667                    newArgs = EMPTY_STRING_ARRAY;
8668                } else {
8669                    name = args[opti];
8670                    opti++;
8671                    newArgs = new String[args.length - opti];
8672                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8673                            args.length - opti);
8674                }
8675                synchronized (this) {
8676                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8677                }
8678            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8679                synchronized (this) {
8680                    dumpOomLocked(fd, pw, args, opti, true);
8681                }
8682            } else if ("provider".equals(cmd)) {
8683                String[] newArgs;
8684                String name;
8685                if (opti >= args.length) {
8686                    name = null;
8687                    newArgs = EMPTY_STRING_ARRAY;
8688                } else {
8689                    name = args[opti];
8690                    opti++;
8691                    newArgs = new String[args.length - opti];
8692                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8693                }
8694                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8695                    pw.println("No providers match: " + name);
8696                    pw.println("Use -h for help.");
8697                }
8698            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8699                synchronized (this) {
8700                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8701                }
8702            } else if ("service".equals(cmd)) {
8703                String[] newArgs;
8704                String name;
8705                if (opti >= args.length) {
8706                    name = null;
8707                    newArgs = EMPTY_STRING_ARRAY;
8708                } else {
8709                    name = args[opti];
8710                    opti++;
8711                    newArgs = new String[args.length - opti];
8712                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8713                            args.length - opti);
8714                }
8715                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8716                    pw.println("No services match: " + name);
8717                    pw.println("Use -h for help.");
8718                }
8719            } else if ("package".equals(cmd)) {
8720                String[] newArgs;
8721                if (opti >= args.length) {
8722                    pw.println("package: no package name specified");
8723                    pw.println("Use -h for help.");
8724                } else {
8725                    dumpPackage = args[opti];
8726                    opti++;
8727                    newArgs = new String[args.length - opti];
8728                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8729                            args.length - opti);
8730                    args = newArgs;
8731                    opti = 0;
8732                    more = true;
8733                }
8734            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8735                synchronized (this) {
8736                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8737                }
8738            } else {
8739                // Dumping a single activity?
8740                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8741                    pw.println("Bad activity command, or no activities match: " + cmd);
8742                    pw.println("Use -h for help.");
8743                }
8744            }
8745            if (!more) {
8746                Binder.restoreCallingIdentity(origId);
8747                return;
8748            }
8749        }
8750
8751        // No piece of data specified, dump everything.
8752        synchronized (this) {
8753            boolean needSep;
8754            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8755            if (needSep) {
8756                pw.println(" ");
8757            }
8758            if (dumpAll) {
8759                pw.println("-------------------------------------------------------------------------------");
8760            }
8761            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8762            if (needSep) {
8763                pw.println(" ");
8764            }
8765            if (dumpAll) {
8766                pw.println("-------------------------------------------------------------------------------");
8767            }
8768            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8769            if (needSep) {
8770                pw.println(" ");
8771            }
8772            if (dumpAll) {
8773                pw.println("-------------------------------------------------------------------------------");
8774            }
8775            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8776            if (needSep) {
8777                pw.println(" ");
8778            }
8779            if (dumpAll) {
8780                pw.println("-------------------------------------------------------------------------------");
8781            }
8782            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8783            if (needSep) {
8784                pw.println(" ");
8785            }
8786            if (dumpAll) {
8787                pw.println("-------------------------------------------------------------------------------");
8788            }
8789            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8790        }
8791        Binder.restoreCallingIdentity(origId);
8792    }
8793
8794    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8795            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8796        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8797        pw.println("  Main stack:");
8798        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8799                dumpPackage);
8800        pw.println(" ");
8801        pw.println("  Running activities (most recent first):");
8802        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8803                dumpPackage);
8804        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8805            pw.println(" ");
8806            pw.println("  Activities waiting for another to become visible:");
8807            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8808                    !dumpAll, false, dumpPackage);
8809        }
8810        if (mMainStack.mStoppingActivities.size() > 0) {
8811            pw.println(" ");
8812            pw.println("  Activities waiting to stop:");
8813            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8814                    !dumpAll, false, dumpPackage);
8815        }
8816        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8817            pw.println(" ");
8818            pw.println("  Activities waiting to sleep:");
8819            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8820                    !dumpAll, false, dumpPackage);
8821        }
8822        if (mMainStack.mFinishingActivities.size() > 0) {
8823            pw.println(" ");
8824            pw.println("  Activities waiting to finish:");
8825            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8826                    !dumpAll, false, dumpPackage);
8827        }
8828
8829        pw.println(" ");
8830        if (mMainStack.mPausingActivity != null) {
8831            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8832        }
8833        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8834        pw.println("  mFocusedActivity: " + mFocusedActivity);
8835        if (dumpAll) {
8836            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8837            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8838            pw.println("  mDismissKeyguardOnNextActivity: "
8839                    + mMainStack.mDismissKeyguardOnNextActivity);
8840        }
8841
8842        if (mRecentTasks.size() > 0) {
8843            pw.println();
8844            pw.println("  Recent tasks:");
8845
8846            final int N = mRecentTasks.size();
8847            for (int i=0; i<N; i++) {
8848                TaskRecord tr = mRecentTasks.get(i);
8849                if (dumpPackage != null) {
8850                    if (tr.realActivity == null ||
8851                            !dumpPackage.equals(tr.realActivity)) {
8852                        continue;
8853                    }
8854                }
8855                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8856                        pw.println(tr);
8857                if (dumpAll) {
8858                    mRecentTasks.get(i).dump(pw, "    ");
8859                }
8860            }
8861        }
8862
8863        if (dumpAll) {
8864            pw.println(" ");
8865            pw.println("  mCurTask: " + mCurTask);
8866        }
8867
8868        return true;
8869    }
8870
8871    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8872            int opti, boolean dumpAll, String dumpPackage) {
8873        boolean needSep = false;
8874        int numPers = 0;
8875
8876        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8877
8878        if (dumpAll) {
8879            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8880                final int NA = procs.size();
8881                for (int ia=0; ia<NA; ia++) {
8882                    ProcessRecord r = procs.valueAt(ia);
8883                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8884                        continue;
8885                    }
8886                    if (!needSep) {
8887                        pw.println("  All known processes:");
8888                        needSep = true;
8889                    }
8890                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8891                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8892                        pw.print(" "); pw.println(r);
8893                    r.dump(pw, "    ");
8894                    if (r.persistent) {
8895                        numPers++;
8896                    }
8897                }
8898            }
8899        }
8900
8901        if (mIsolatedProcesses.size() > 0) {
8902            if (needSep) pw.println(" ");
8903            needSep = true;
8904            pw.println("  Isolated process list (sorted by uid):");
8905            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8906                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8907                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8908                    continue;
8909                }
8910                pw.println(String.format("%sIsolated #%2d: %s",
8911                        "    ", i, r.toString()));
8912            }
8913        }
8914
8915        if (mLruProcesses.size() > 0) {
8916            if (needSep) pw.println(" ");
8917            needSep = true;
8918            pw.println("  Process LRU list (sorted by oom_adj):");
8919            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8920                    "Proc", "PERS", false, dumpPackage);
8921            needSep = true;
8922        }
8923
8924        if (dumpAll) {
8925            synchronized (mPidsSelfLocked) {
8926                boolean printed = false;
8927                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8928                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8929                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8930                        continue;
8931                    }
8932                    if (!printed) {
8933                        if (needSep) pw.println(" ");
8934                        needSep = true;
8935                        pw.println("  PID mappings:");
8936                        printed = true;
8937                    }
8938                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8939                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8940                }
8941            }
8942        }
8943
8944        if (mForegroundProcesses.size() > 0) {
8945            synchronized (mPidsSelfLocked) {
8946                boolean printed = false;
8947                for (int i=0; i<mForegroundProcesses.size(); i++) {
8948                    ProcessRecord r = mPidsSelfLocked.get(
8949                            mForegroundProcesses.valueAt(i).pid);
8950                    if (dumpPackage != null && (r == null
8951                            || !dumpPackage.equals(r.info.packageName))) {
8952                        continue;
8953                    }
8954                    if (!printed) {
8955                        if (needSep) pw.println(" ");
8956                        needSep = true;
8957                        pw.println("  Foreground Processes:");
8958                        printed = true;
8959                    }
8960                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8961                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8962                }
8963            }
8964        }
8965
8966        if (mPersistentStartingProcesses.size() > 0) {
8967            if (needSep) pw.println(" ");
8968            needSep = true;
8969            pw.println("  Persisent processes that are starting:");
8970            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8971                    "Starting Norm", "Restarting PERS", dumpPackage);
8972        }
8973
8974        if (mRemovedProcesses.size() > 0) {
8975            if (needSep) pw.println(" ");
8976            needSep = true;
8977            pw.println("  Processes that are being removed:");
8978            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8979                    "Removed Norm", "Removed PERS", dumpPackage);
8980        }
8981
8982        if (mProcessesOnHold.size() > 0) {
8983            if (needSep) pw.println(" ");
8984            needSep = true;
8985            pw.println("  Processes that are on old until the system is ready:");
8986            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8987                    "OnHold Norm", "OnHold PERS", dumpPackage);
8988        }
8989
8990        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8991
8992        if (mProcessCrashTimes.getMap().size() > 0) {
8993            boolean printed = false;
8994            long now = SystemClock.uptimeMillis();
8995            for (Map.Entry<String, SparseArray<Long>> procs
8996                    : mProcessCrashTimes.getMap().entrySet()) {
8997                String pname = procs.getKey();
8998                SparseArray<Long> uids = procs.getValue();
8999                final int N = uids.size();
9000                for (int i=0; i<N; i++) {
9001                    int puid = uids.keyAt(i);
9002                    ProcessRecord r = mProcessNames.get(pname, puid);
9003                    if (dumpPackage != null && (r == null
9004                            || !dumpPackage.equals(r.info.packageName))) {
9005                        continue;
9006                    }
9007                    if (!printed) {
9008                        if (needSep) pw.println(" ");
9009                        needSep = true;
9010                        pw.println("  Time since processes crashed:");
9011                        printed = true;
9012                    }
9013                    pw.print("    Process "); pw.print(pname);
9014                            pw.print(" uid "); pw.print(puid);
9015                            pw.print(": last crashed ");
9016                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9017                            pw.println(" ago");
9018                }
9019            }
9020        }
9021
9022        if (mBadProcesses.getMap().size() > 0) {
9023            boolean printed = false;
9024            for (Map.Entry<String, SparseArray<Long>> procs
9025                    : mBadProcesses.getMap().entrySet()) {
9026                String pname = procs.getKey();
9027                SparseArray<Long> uids = procs.getValue();
9028                final int N = uids.size();
9029                for (int i=0; i<N; i++) {
9030                    int puid = uids.keyAt(i);
9031                    ProcessRecord r = mProcessNames.get(pname, puid);
9032                    if (dumpPackage != null && (r == null
9033                            || !dumpPackage.equals(r.info.packageName))) {
9034                        continue;
9035                    }
9036                    if (!printed) {
9037                        if (needSep) pw.println(" ");
9038                        needSep = true;
9039                        pw.println("  Bad processes:");
9040                    }
9041                    pw.print("    Bad process "); pw.print(pname);
9042                            pw.print(" uid "); pw.print(puid);
9043                            pw.print(": crashed at time ");
9044                            pw.println(uids.valueAt(i));
9045                }
9046            }
9047        }
9048
9049        pw.println();
9050        pw.println("  mHomeProcess: " + mHomeProcess);
9051        pw.println("  mPreviousProcess: " + mPreviousProcess);
9052        if (dumpAll) {
9053            StringBuilder sb = new StringBuilder(128);
9054            sb.append("  mPreviousProcessVisibleTime: ");
9055            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9056            pw.println(sb);
9057        }
9058        if (mHeavyWeightProcess != null) {
9059            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9060        }
9061        pw.println("  mConfiguration: " + mConfiguration);
9062        if (dumpAll) {
9063            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9064            if (mCompatModePackages.getPackages().size() > 0) {
9065                boolean printed = false;
9066                for (Map.Entry<String, Integer> entry
9067                        : mCompatModePackages.getPackages().entrySet()) {
9068                    String pkg = entry.getKey();
9069                    int mode = entry.getValue();
9070                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9071                        continue;
9072                    }
9073                    if (!printed) {
9074                        pw.println("  mScreenCompatPackages:");
9075                        printed = true;
9076                    }
9077                    pw.print("    "); pw.print(pkg); pw.print(": ");
9078                            pw.print(mode); pw.println();
9079                }
9080            }
9081        }
9082        if (mSleeping || mWentToSleep || mLockScreenShown) {
9083            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9084                    + " mLockScreenShown " + mLockScreenShown);
9085        }
9086        if (mShuttingDown) {
9087            pw.println("  mShuttingDown=" + mShuttingDown);
9088        }
9089        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9090                || mOrigWaitForDebugger) {
9091            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9092                    + " mDebugTransient=" + mDebugTransient
9093                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9094        }
9095        if (mOpenGlTraceApp != null) {
9096            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9097        }
9098        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9099                || mProfileFd != null) {
9100            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9101            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9102            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9103                    + mAutoStopProfiler);
9104        }
9105        if (mAlwaysFinishActivities || mController != null) {
9106            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9107                    + " mController=" + mController);
9108        }
9109        if (dumpAll) {
9110            pw.println("  Total persistent processes: " + numPers);
9111            pw.println("  mStartRunning=" + mStartRunning
9112                    + " mProcessesReady=" + mProcessesReady
9113                    + " mSystemReady=" + mSystemReady);
9114            pw.println("  mBooting=" + mBooting
9115                    + " mBooted=" + mBooted
9116                    + " mFactoryTest=" + mFactoryTest);
9117            pw.print("  mLastPowerCheckRealtime=");
9118                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9119                    pw.println("");
9120            pw.print("  mLastPowerCheckUptime=");
9121                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9122                    pw.println("");
9123            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9124            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9125            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9126            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9127                    + " mNumHiddenProcs=" + mNumHiddenProcs
9128                    + " mNumServiceProcs=" + mNumServiceProcs
9129                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9130        }
9131
9132        return true;
9133    }
9134
9135    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9136            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9137        if (mProcessesToGc.size() > 0) {
9138            boolean printed = false;
9139            long now = SystemClock.uptimeMillis();
9140            for (int i=0; i<mProcessesToGc.size(); i++) {
9141                ProcessRecord proc = mProcessesToGc.get(i);
9142                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9143                    continue;
9144                }
9145                if (!printed) {
9146                    if (needSep) pw.println(" ");
9147                    needSep = true;
9148                    pw.println("  Processes that are waiting to GC:");
9149                    printed = true;
9150                }
9151                pw.print("    Process "); pw.println(proc);
9152                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9153                        pw.print(", last gced=");
9154                        pw.print(now-proc.lastRequestedGc);
9155                        pw.print(" ms ago, last lowMem=");
9156                        pw.print(now-proc.lastLowMemory);
9157                        pw.println(" ms ago");
9158
9159            }
9160        }
9161        return needSep;
9162    }
9163
9164    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9165            int opti, boolean dumpAll) {
9166        boolean needSep = false;
9167
9168        if (mLruProcesses.size() > 0) {
9169            if (needSep) pw.println(" ");
9170            needSep = true;
9171            pw.println("  OOM levels:");
9172            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9173            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9174            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9175            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9176            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9177            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9178            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9179            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9180            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9181            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9182            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9183            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9184            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9185
9186            if (needSep) pw.println(" ");
9187            needSep = true;
9188            pw.println("  Process OOM control:");
9189            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9190                    "Proc", "PERS", true, null);
9191            needSep = true;
9192        }
9193
9194        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9195
9196        pw.println();
9197        pw.println("  mHomeProcess: " + mHomeProcess);
9198        pw.println("  mPreviousProcess: " + mPreviousProcess);
9199        if (mHeavyWeightProcess != null) {
9200            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9201        }
9202
9203        return true;
9204    }
9205
9206    /**
9207     * There are three ways to call this:
9208     *  - no provider specified: dump all the providers
9209     *  - a flattened component name that matched an existing provider was specified as the
9210     *    first arg: dump that one provider
9211     *  - the first arg isn't the flattened component name of an existing provider:
9212     *    dump all providers whose component contains the first arg as a substring
9213     */
9214    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9215            int opti, boolean dumpAll) {
9216        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9217    }
9218
9219    static class ItemMatcher {
9220        ArrayList<ComponentName> components;
9221        ArrayList<String> strings;
9222        ArrayList<Integer> objects;
9223        boolean all;
9224
9225        ItemMatcher() {
9226            all = true;
9227        }
9228
9229        void build(String name) {
9230            ComponentName componentName = ComponentName.unflattenFromString(name);
9231            if (componentName != null) {
9232                if (components == null) {
9233                    components = new ArrayList<ComponentName>();
9234                }
9235                components.add(componentName);
9236                all = false;
9237            } else {
9238                int objectId = 0;
9239                // Not a '/' separated full component name; maybe an object ID?
9240                try {
9241                    objectId = Integer.parseInt(name, 16);
9242                    if (objects == null) {
9243                        objects = new ArrayList<Integer>();
9244                    }
9245                    objects.add(objectId);
9246                    all = false;
9247                } catch (RuntimeException e) {
9248                    // Not an integer; just do string match.
9249                    if (strings == null) {
9250                        strings = new ArrayList<String>();
9251                    }
9252                    strings.add(name);
9253                    all = false;
9254                }
9255            }
9256        }
9257
9258        int build(String[] args, int opti) {
9259            for (; opti<args.length; opti++) {
9260                String name = args[opti];
9261                if ("--".equals(name)) {
9262                    return opti+1;
9263                }
9264                build(name);
9265            }
9266            return opti;
9267        }
9268
9269        boolean match(Object object, ComponentName comp) {
9270            if (all) {
9271                return true;
9272            }
9273            if (components != null) {
9274                for (int i=0; i<components.size(); i++) {
9275                    if (components.get(i).equals(comp)) {
9276                        return true;
9277                    }
9278                }
9279            }
9280            if (objects != null) {
9281                for (int i=0; i<objects.size(); i++) {
9282                    if (System.identityHashCode(object) == objects.get(i)) {
9283                        return true;
9284                    }
9285                }
9286            }
9287            if (strings != null) {
9288                String flat = comp.flattenToString();
9289                for (int i=0; i<strings.size(); i++) {
9290                    if (flat.contains(strings.get(i))) {
9291                        return true;
9292                    }
9293                }
9294            }
9295            return false;
9296        }
9297    }
9298
9299    /**
9300     * There are three things that cmd can be:
9301     *  - a flattened component name that matches an existing activity
9302     *  - the cmd arg isn't the flattened component name of an existing activity:
9303     *    dump all activity whose component contains the cmd as a substring
9304     *  - A hex number of the ActivityRecord object instance.
9305     */
9306    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9307            int opti, boolean dumpAll) {
9308        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9309
9310        if ("all".equals(name)) {
9311            synchronized (this) {
9312                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9313                    activities.add(r1);
9314                }
9315            }
9316        } else if ("top".equals(name)) {
9317            synchronized (this) {
9318                final int N = mMainStack.mHistory.size();
9319                if (N > 0) {
9320                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9321                }
9322            }
9323        } else {
9324            ItemMatcher matcher = new ItemMatcher();
9325            matcher.build(name);
9326
9327            synchronized (this) {
9328                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9329                    if (matcher.match(r1, r1.intent.getComponent())) {
9330                        activities.add(r1);
9331                    }
9332                }
9333            }
9334        }
9335
9336        if (activities.size() <= 0) {
9337            return false;
9338        }
9339
9340        String[] newArgs = new String[args.length - opti];
9341        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9342
9343        TaskRecord lastTask = null;
9344        boolean needSep = false;
9345        for (int i=activities.size()-1; i>=0; i--) {
9346            ActivityRecord r = (ActivityRecord)activities.get(i);
9347            if (needSep) {
9348                pw.println();
9349            }
9350            needSep = true;
9351            synchronized (this) {
9352                if (lastTask != r.task) {
9353                    lastTask = r.task;
9354                    pw.print("TASK "); pw.print(lastTask.affinity);
9355                            pw.print(" id="); pw.println(lastTask.taskId);
9356                    if (dumpAll) {
9357                        lastTask.dump(pw, "  ");
9358                    }
9359                }
9360            }
9361            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9362        }
9363        return true;
9364    }
9365
9366    /**
9367     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9368     * there is a thread associated with the activity.
9369     */
9370    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9371            final ActivityRecord r, String[] args, boolean dumpAll) {
9372        String innerPrefix = prefix + "  ";
9373        synchronized (this) {
9374            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9375                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9376                    pw.print(" pid=");
9377                    if (r.app != null) pw.println(r.app.pid);
9378                    else pw.println("(not running)");
9379            if (dumpAll) {
9380                r.dump(pw, innerPrefix);
9381            }
9382        }
9383        if (r.app != null && r.app.thread != null) {
9384            // flush anything that is already in the PrintWriter since the thread is going
9385            // to write to the file descriptor directly
9386            pw.flush();
9387            try {
9388                TransferPipe tp = new TransferPipe();
9389                try {
9390                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9391                            r.appToken, innerPrefix, args);
9392                    tp.go(fd);
9393                } finally {
9394                    tp.kill();
9395                }
9396            } catch (IOException e) {
9397                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9398            } catch (RemoteException e) {
9399                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9400            }
9401        }
9402    }
9403
9404    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9405            int opti, boolean dumpAll, String dumpPackage) {
9406        boolean needSep = false;
9407        boolean onlyHistory = false;
9408
9409        if ("history".equals(dumpPackage)) {
9410            onlyHistory = true;
9411            dumpPackage = null;
9412        }
9413
9414        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9415        if (!onlyHistory && dumpAll) {
9416            if (mRegisteredReceivers.size() > 0) {
9417                boolean printed = false;
9418                Iterator it = mRegisteredReceivers.values().iterator();
9419                while (it.hasNext()) {
9420                    ReceiverList r = (ReceiverList)it.next();
9421                    if (dumpPackage != null && (r.app == null ||
9422                            !dumpPackage.equals(r.app.info.packageName))) {
9423                        continue;
9424                    }
9425                    if (!printed) {
9426                        pw.println("  Registered Receivers:");
9427                        needSep = true;
9428                        printed = true;
9429                    }
9430                    pw.print("  * "); pw.println(r);
9431                    r.dump(pw, "    ");
9432                }
9433            }
9434
9435            if (mReceiverResolver.dump(pw, needSep ?
9436                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9437                    "    ", dumpPackage, false)) {
9438                needSep = true;
9439            }
9440        }
9441
9442        for (BroadcastQueue q : mBroadcastQueues) {
9443            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9444        }
9445
9446        needSep = true;
9447
9448        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9449            if (needSep) {
9450                pw.println();
9451            }
9452            needSep = true;
9453            pw.println("  Sticky broadcasts:");
9454            StringBuilder sb = new StringBuilder(128);
9455            for (Map.Entry<String, ArrayList<Intent>> ent
9456                    : mStickyBroadcasts.entrySet()) {
9457                pw.print("  * Sticky action "); pw.print(ent.getKey());
9458                if (dumpAll) {
9459                    pw.println(":");
9460                    ArrayList<Intent> intents = ent.getValue();
9461                    final int N = intents.size();
9462                    for (int i=0; i<N; i++) {
9463                        sb.setLength(0);
9464                        sb.append("    Intent: ");
9465                        intents.get(i).toShortString(sb, false, true, false, false);
9466                        pw.println(sb.toString());
9467                        Bundle bundle = intents.get(i).getExtras();
9468                        if (bundle != null) {
9469                            pw.print("      ");
9470                            pw.println(bundle.toString());
9471                        }
9472                    }
9473                } else {
9474                    pw.println("");
9475                }
9476            }
9477            needSep = true;
9478        }
9479
9480        if (!onlyHistory && dumpAll) {
9481            pw.println();
9482            for (BroadcastQueue queue : mBroadcastQueues) {
9483                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9484                        + queue.mBroadcastsScheduled);
9485            }
9486            pw.println("  mHandler:");
9487            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9488            needSep = true;
9489        }
9490
9491        return needSep;
9492    }
9493
9494    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9495            int opti, boolean dumpAll, String dumpPackage) {
9496        boolean needSep = true;
9497
9498        ItemMatcher matcher = new ItemMatcher();
9499        matcher.build(args, opti);
9500
9501        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9502
9503        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9504
9505        if (mLaunchingProviders.size() > 0) {
9506            boolean printed = false;
9507            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9508                ContentProviderRecord r = mLaunchingProviders.get(i);
9509                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9510                    continue;
9511                }
9512                if (!printed) {
9513                    if (needSep) pw.println(" ");
9514                    needSep = true;
9515                    pw.println("  Launching content providers:");
9516                    printed = true;
9517                }
9518                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9519                        pw.println(r);
9520            }
9521        }
9522
9523        if (mGrantedUriPermissions.size() > 0) {
9524            if (needSep) pw.println();
9525            needSep = true;
9526            pw.println("Granted Uri Permissions:");
9527            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9528                int uid = mGrantedUriPermissions.keyAt(i);
9529                HashMap<Uri, UriPermission> perms
9530                        = mGrantedUriPermissions.valueAt(i);
9531                pw.print("  * UID "); pw.print(uid);
9532                        pw.println(" holds:");
9533                for (UriPermission perm : perms.values()) {
9534                    pw.print("    "); pw.println(perm);
9535                    if (dumpAll) {
9536                        perm.dump(pw, "      ");
9537                    }
9538                }
9539            }
9540            needSep = true;
9541        }
9542
9543        return needSep;
9544    }
9545
9546    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9547            int opti, boolean dumpAll, String dumpPackage) {
9548        boolean needSep = false;
9549
9550        if (mIntentSenderRecords.size() > 0) {
9551            boolean printed = false;
9552            Iterator<WeakReference<PendingIntentRecord>> it
9553                    = mIntentSenderRecords.values().iterator();
9554            while (it.hasNext()) {
9555                WeakReference<PendingIntentRecord> ref = it.next();
9556                PendingIntentRecord rec = ref != null ? ref.get(): null;
9557                if (dumpPackage != null && (rec == null
9558                        || !dumpPackage.equals(rec.key.packageName))) {
9559                    continue;
9560                }
9561                if (!printed) {
9562                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9563                    printed = true;
9564                }
9565                needSep = true;
9566                if (rec != null) {
9567                    pw.print("  * "); pw.println(rec);
9568                    if (dumpAll) {
9569                        rec.dump(pw, "    ");
9570                    }
9571                } else {
9572                    pw.print("  * "); pw.println(ref);
9573                }
9574            }
9575        }
9576
9577        return needSep;
9578    }
9579
9580    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9581            String prefix, String label, boolean complete, boolean brief, boolean client,
9582            String dumpPackage) {
9583        TaskRecord lastTask = null;
9584        boolean needNL = false;
9585        final String innerPrefix = prefix + "      ";
9586        final String[] args = new String[0];
9587        for (int i=list.size()-1; i>=0; i--) {
9588            final ActivityRecord r = (ActivityRecord)list.get(i);
9589            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9590                continue;
9591            }
9592            final boolean full = !brief && (complete || !r.isInHistory());
9593            if (needNL) {
9594                pw.println(" ");
9595                needNL = false;
9596            }
9597            if (lastTask != r.task) {
9598                lastTask = r.task;
9599                pw.print(prefix);
9600                pw.print(full ? "* " : "  ");
9601                pw.println(lastTask);
9602                if (full) {
9603                    lastTask.dump(pw, prefix + "  ");
9604                } else if (complete) {
9605                    // Complete + brief == give a summary.  Isn't that obvious?!?
9606                    if (lastTask.intent != null) {
9607                        pw.print(prefix); pw.print("  ");
9608                                pw.println(lastTask.intent.toInsecureStringWithClip());
9609                    }
9610                }
9611            }
9612            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9613            pw.print(" #"); pw.print(i); pw.print(": ");
9614            pw.println(r);
9615            if (full) {
9616                r.dump(pw, innerPrefix);
9617            } else if (complete) {
9618                // Complete + brief == give a summary.  Isn't that obvious?!?
9619                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9620                if (r.app != null) {
9621                    pw.print(innerPrefix); pw.println(r.app);
9622                }
9623            }
9624            if (client && r.app != null && r.app.thread != null) {
9625                // flush anything that is already in the PrintWriter since the thread is going
9626                // to write to the file descriptor directly
9627                pw.flush();
9628                try {
9629                    TransferPipe tp = new TransferPipe();
9630                    try {
9631                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9632                                r.appToken, innerPrefix, args);
9633                        // Short timeout, since blocking here can
9634                        // deadlock with the application.
9635                        tp.go(fd, 2000);
9636                    } finally {
9637                        tp.kill();
9638                    }
9639                } catch (IOException e) {
9640                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9641                } catch (RemoteException e) {
9642                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9643                }
9644                needNL = true;
9645            }
9646        }
9647    }
9648
9649    private static String buildOomTag(String prefix, String space, int val, int base) {
9650        if (val == base) {
9651            if (space == null) return prefix;
9652            return prefix + "  ";
9653        }
9654        return prefix + "+" + Integer.toString(val-base);
9655    }
9656
9657    private static final int dumpProcessList(PrintWriter pw,
9658            ActivityManagerService service, List list,
9659            String prefix, String normalLabel, String persistentLabel,
9660            String dumpPackage) {
9661        int numPers = 0;
9662        final int N = list.size()-1;
9663        for (int i=N; i>=0; i--) {
9664            ProcessRecord r = (ProcessRecord)list.get(i);
9665            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9666                continue;
9667            }
9668            pw.println(String.format("%s%s #%2d: %s",
9669                    prefix, (r.persistent ? persistentLabel : normalLabel),
9670                    i, r.toString()));
9671            if (r.persistent) {
9672                numPers++;
9673            }
9674        }
9675        return numPers;
9676    }
9677
9678    private static final boolean dumpProcessOomList(PrintWriter pw,
9679            ActivityManagerService service, List<ProcessRecord> origList,
9680            String prefix, String normalLabel, String persistentLabel,
9681            boolean inclDetails, String dumpPackage) {
9682
9683        ArrayList<Pair<ProcessRecord, Integer>> list
9684                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9685        for (int i=0; i<origList.size(); i++) {
9686            ProcessRecord r = origList.get(i);
9687            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9688                continue;
9689            }
9690            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9691        }
9692
9693        if (list.size() <= 0) {
9694            return false;
9695        }
9696
9697        Comparator<Pair<ProcessRecord, Integer>> comparator
9698                = new Comparator<Pair<ProcessRecord, Integer>>() {
9699            @Override
9700            public int compare(Pair<ProcessRecord, Integer> object1,
9701                    Pair<ProcessRecord, Integer> object2) {
9702                if (object1.first.setAdj != object2.first.setAdj) {
9703                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9704                }
9705                if (object1.second.intValue() != object2.second.intValue()) {
9706                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9707                }
9708                return 0;
9709            }
9710        };
9711
9712        Collections.sort(list, comparator);
9713
9714        final long curRealtime = SystemClock.elapsedRealtime();
9715        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9716        final long curUptime = SystemClock.uptimeMillis();
9717        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9718
9719        for (int i=list.size()-1; i>=0; i--) {
9720            ProcessRecord r = list.get(i).first;
9721            String oomAdj;
9722            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9723                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9724            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9725                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9726            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9727                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9728            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9729                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9730            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9731                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9732            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9733                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9734            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9735                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9736            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9737                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9738            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9739                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9740            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9741                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9742            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9743                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9744            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9745                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9746            } else {
9747                oomAdj = Integer.toString(r.setAdj);
9748            }
9749            String schedGroup;
9750            switch (r.setSchedGroup) {
9751                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9752                    schedGroup = "B";
9753                    break;
9754                case Process.THREAD_GROUP_DEFAULT:
9755                    schedGroup = "F";
9756                    break;
9757                default:
9758                    schedGroup = Integer.toString(r.setSchedGroup);
9759                    break;
9760            }
9761            String foreground;
9762            if (r.foregroundActivities) {
9763                foreground = "A";
9764            } else if (r.foregroundServices) {
9765                foreground = "S";
9766            } else {
9767                foreground = " ";
9768            }
9769            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9770                    prefix, (r.persistent ? persistentLabel : normalLabel),
9771                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9772                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9773            if (r.adjSource != null || r.adjTarget != null) {
9774                pw.print(prefix);
9775                pw.print("    ");
9776                if (r.adjTarget instanceof ComponentName) {
9777                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9778                } else if (r.adjTarget != null) {
9779                    pw.print(r.adjTarget.toString());
9780                } else {
9781                    pw.print("{null}");
9782                }
9783                pw.print("<=");
9784                if (r.adjSource instanceof ProcessRecord) {
9785                    pw.print("Proc{");
9786                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9787                    pw.println("}");
9788                } else if (r.adjSource != null) {
9789                    pw.println(r.adjSource.toString());
9790                } else {
9791                    pw.println("{null}");
9792                }
9793            }
9794            if (inclDetails) {
9795                pw.print(prefix);
9796                pw.print("    ");
9797                pw.print("oom: max="); pw.print(r.maxAdj);
9798                pw.print(" hidden="); pw.print(r.hiddenAdj);
9799                pw.print(" empty="); pw.print(r.emptyAdj);
9800                pw.print(" curRaw="); pw.print(r.curRawAdj);
9801                pw.print(" setRaw="); pw.print(r.setRawAdj);
9802                pw.print(" cur="); pw.print(r.curAdj);
9803                pw.print(" set="); pw.println(r.setAdj);
9804                pw.print(prefix);
9805                pw.print("    ");
9806                pw.print("keeping="); pw.print(r.keeping);
9807                pw.print(" hidden="); pw.print(r.hidden);
9808                pw.print(" empty="); pw.print(r.empty);
9809                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9810
9811                if (!r.keeping) {
9812                    if (r.lastWakeTime != 0) {
9813                        long wtime;
9814                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9815                        synchronized (stats) {
9816                            wtime = stats.getProcessWakeTime(r.info.uid,
9817                                    r.pid, curRealtime);
9818                        }
9819                        long timeUsed = wtime - r.lastWakeTime;
9820                        pw.print(prefix);
9821                        pw.print("    ");
9822                        pw.print("keep awake over ");
9823                        TimeUtils.formatDuration(realtimeSince, pw);
9824                        pw.print(" used ");
9825                        TimeUtils.formatDuration(timeUsed, pw);
9826                        pw.print(" (");
9827                        pw.print((timeUsed*100)/realtimeSince);
9828                        pw.println("%)");
9829                    }
9830                    if (r.lastCpuTime != 0) {
9831                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9832                        pw.print(prefix);
9833                        pw.print("    ");
9834                        pw.print("run cpu over ");
9835                        TimeUtils.formatDuration(uptimeSince, pw);
9836                        pw.print(" used ");
9837                        TimeUtils.formatDuration(timeUsed, pw);
9838                        pw.print(" (");
9839                        pw.print((timeUsed*100)/uptimeSince);
9840                        pw.println("%)");
9841                    }
9842                }
9843            }
9844        }
9845        return true;
9846    }
9847
9848    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9849        ArrayList<ProcessRecord> procs;
9850        synchronized (this) {
9851            if (args != null && args.length > start
9852                    && args[start].charAt(0) != '-') {
9853                procs = new ArrayList<ProcessRecord>();
9854                int pid = -1;
9855                try {
9856                    pid = Integer.parseInt(args[start]);
9857                } catch (NumberFormatException e) {
9858
9859                }
9860                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9861                    ProcessRecord proc = mLruProcesses.get(i);
9862                    if (proc.pid == pid) {
9863                        procs.add(proc);
9864                    } else if (proc.processName.equals(args[start])) {
9865                        procs.add(proc);
9866                    }
9867                }
9868                if (procs.size() <= 0) {
9869                    pw.println("No process found for: " + args[start]);
9870                    return null;
9871                }
9872            } else {
9873                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9874            }
9875        }
9876        return procs;
9877    }
9878
9879    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9880            PrintWriter pw, String[] args) {
9881        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9882        if (procs == null) {
9883            return;
9884        }
9885
9886        long uptime = SystemClock.uptimeMillis();
9887        long realtime = SystemClock.elapsedRealtime();
9888        pw.println("Applications Graphics Acceleration Info:");
9889        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9890
9891        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9892            ProcessRecord r = procs.get(i);
9893            if (r.thread != null) {
9894                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9895                pw.flush();
9896                try {
9897                    TransferPipe tp = new TransferPipe();
9898                    try {
9899                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9900                        tp.go(fd);
9901                    } finally {
9902                        tp.kill();
9903                    }
9904                } catch (IOException e) {
9905                    pw.println("Failure while dumping the app: " + r);
9906                    pw.flush();
9907                } catch (RemoteException e) {
9908                    pw.println("Got a RemoteException while dumping the app " + r);
9909                    pw.flush();
9910                }
9911            }
9912        }
9913    }
9914
9915    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9916        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9917        if (procs == null) {
9918            return;
9919        }
9920
9921        pw.println("Applications Database Info:");
9922
9923        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9924            ProcessRecord r = procs.get(i);
9925            if (r.thread != null) {
9926                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9927                pw.flush();
9928                try {
9929                    TransferPipe tp = new TransferPipe();
9930                    try {
9931                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9932                        tp.go(fd);
9933                    } finally {
9934                        tp.kill();
9935                    }
9936                } catch (IOException e) {
9937                    pw.println("Failure while dumping the app: " + r);
9938                    pw.flush();
9939                } catch (RemoteException e) {
9940                    pw.println("Got a RemoteException while dumping the app " + r);
9941                    pw.flush();
9942                }
9943            }
9944        }
9945    }
9946
9947    final static class MemItem {
9948        final String label;
9949        final String shortLabel;
9950        final long pss;
9951        final int id;
9952        ArrayList<MemItem> subitems;
9953
9954        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9955            label = _label;
9956            shortLabel = _shortLabel;
9957            pss = _pss;
9958            id = _id;
9959        }
9960    }
9961
9962    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9963            boolean sort) {
9964        if (sort) {
9965            Collections.sort(items, new Comparator<MemItem>() {
9966                @Override
9967                public int compare(MemItem lhs, MemItem rhs) {
9968                    if (lhs.pss < rhs.pss) {
9969                        return 1;
9970                    } else if (lhs.pss > rhs.pss) {
9971                        return -1;
9972                    }
9973                    return 0;
9974                }
9975            });
9976        }
9977
9978        for (int i=0; i<items.size(); i++) {
9979            MemItem mi = items.get(i);
9980            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9981            if (mi.subitems != null) {
9982                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9983            }
9984        }
9985    }
9986
9987    // These are in KB.
9988    static final long[] DUMP_MEM_BUCKETS = new long[] {
9989        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9990        120*1024, 160*1024, 200*1024,
9991        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9992        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9993    };
9994
9995    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9996            boolean stackLike) {
9997        int start = label.lastIndexOf('.');
9998        if (start >= 0) start++;
9999        else start = 0;
10000        int end = label.length();
10001        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10002            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10003                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10004                out.append(bucket);
10005                out.append(stackLike ? "MB." : "MB ");
10006                out.append(label, start, end);
10007                return;
10008            }
10009        }
10010        out.append(memKB/1024);
10011        out.append(stackLike ? "MB." : "MB ");
10012        out.append(label, start, end);
10013    }
10014
10015    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10016            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10017            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10018            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10019            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10020    };
10021    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10022            "System", "Persistent", "Foreground",
10023            "Visible", "Perceptible", "Heavy Weight",
10024            "Backup", "A Services", "Home", "Previous",
10025            "B Services", "Background"
10026    };
10027
10028    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10029            PrintWriter pw, String prefix, String[] args, boolean brief,
10030            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10031        boolean dumpAll = false;
10032        boolean oomOnly = false;
10033
10034        int opti = 0;
10035        while (opti < args.length) {
10036            String opt = args[opti];
10037            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10038                break;
10039            }
10040            opti++;
10041            if ("-a".equals(opt)) {
10042                dumpAll = true;
10043            } else if ("--oom".equals(opt)) {
10044                oomOnly = true;
10045            } else if ("-h".equals(opt)) {
10046                pw.println("meminfo dump options: [-a] [--oom] [process]");
10047                pw.println("  -a: include all available information for each process.");
10048                pw.println("  --oom: only show processes organized by oom adj.");
10049                pw.println("If [process] is specified it can be the name or ");
10050                pw.println("pid of a specific process to dump.");
10051                return;
10052            } else {
10053                pw.println("Unknown argument: " + opt + "; use -h for help");
10054            }
10055        }
10056
10057        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10058        if (procs == null) {
10059            return;
10060        }
10061
10062        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10063        long uptime = SystemClock.uptimeMillis();
10064        long realtime = SystemClock.elapsedRealtime();
10065
10066        if (procs.size() == 1 || isCheckinRequest) {
10067            dumpAll = true;
10068        }
10069
10070        if (isCheckinRequest) {
10071            // short checkin version
10072            pw.println(uptime + "," + realtime);
10073            pw.flush();
10074        } else {
10075            pw.println("Applications Memory Usage (kB):");
10076            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10077        }
10078
10079        String[] innerArgs = new String[args.length-opti];
10080        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10081
10082        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10083        long nativePss=0, dalvikPss=0, otherPss=0;
10084        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10085
10086        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10087        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10088                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10089
10090        long totalPss = 0;
10091
10092        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10093            ProcessRecord r = procs.get(i);
10094            if (r.thread != null) {
10095                if (!isCheckinRequest && dumpAll) {
10096                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10097                    pw.flush();
10098                }
10099                Debug.MemoryInfo mi = null;
10100                if (dumpAll) {
10101                    try {
10102                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10103                    } catch (RemoteException e) {
10104                        if (!isCheckinRequest) {
10105                            pw.println("Got RemoteException!");
10106                            pw.flush();
10107                        }
10108                    }
10109                } else {
10110                    mi = new Debug.MemoryInfo();
10111                    Debug.getMemoryInfo(r.pid, mi);
10112                }
10113
10114                if (!isCheckinRequest && mi != null) {
10115                    long myTotalPss = mi.getTotalPss();
10116                    totalPss += myTotalPss;
10117                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10118                            r.processName, myTotalPss, 0);
10119                    procMems.add(pssItem);
10120
10121                    nativePss += mi.nativePss;
10122                    dalvikPss += mi.dalvikPss;
10123                    otherPss += mi.otherPss;
10124                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10125                        long mem = mi.getOtherPss(j);
10126                        miscPss[j] += mem;
10127                        otherPss -= mem;
10128                    }
10129
10130                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10131                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10132                                || oomIndex == (oomPss.length-1)) {
10133                            oomPss[oomIndex] += myTotalPss;
10134                            if (oomProcs[oomIndex] == null) {
10135                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10136                            }
10137                            oomProcs[oomIndex].add(pssItem);
10138                            break;
10139                        }
10140                    }
10141                }
10142            }
10143        }
10144
10145        if (!isCheckinRequest && procs.size() > 1) {
10146            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10147
10148            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10149            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10150            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10151            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10152                String label = Debug.MemoryInfo.getOtherLabel(j);
10153                catMems.add(new MemItem(label, label, miscPss[j], j));
10154            }
10155
10156            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10157            for (int j=0; j<oomPss.length; j++) {
10158                if (oomPss[j] != 0) {
10159                    String label = DUMP_MEM_OOM_LABEL[j];
10160                    MemItem item = new MemItem(label, label, oomPss[j],
10161                            DUMP_MEM_OOM_ADJ[j]);
10162                    item.subitems = oomProcs[j];
10163                    oomMems.add(item);
10164                }
10165            }
10166
10167            if (outTag != null || outStack != null) {
10168                if (outTag != null) {
10169                    appendMemBucket(outTag, totalPss, "total", false);
10170                }
10171                if (outStack != null) {
10172                    appendMemBucket(outStack, totalPss, "total", true);
10173                }
10174                boolean firstLine = true;
10175                for (int i=0; i<oomMems.size(); i++) {
10176                    MemItem miCat = oomMems.get(i);
10177                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10178                        continue;
10179                    }
10180                    if (miCat.id < ProcessList.SERVICE_ADJ
10181                            || miCat.id == ProcessList.HOME_APP_ADJ
10182                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10183                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10184                            outTag.append(" / ");
10185                        }
10186                        if (outStack != null) {
10187                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10188                                if (firstLine) {
10189                                    outStack.append(":");
10190                                    firstLine = false;
10191                                }
10192                                outStack.append("\n\t at ");
10193                            } else {
10194                                outStack.append("$");
10195                            }
10196                        }
10197                        for (int j=0; j<miCat.subitems.size(); j++) {
10198                            MemItem mi = miCat.subitems.get(j);
10199                            if (j > 0) {
10200                                if (outTag != null) {
10201                                    outTag.append(" ");
10202                                }
10203                                if (outStack != null) {
10204                                    outStack.append("$");
10205                                }
10206                            }
10207                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10208                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10209                            }
10210                            if (outStack != null) {
10211                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10212                            }
10213                        }
10214                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10215                            outStack.append("(");
10216                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10217                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10218                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10219                                    outStack.append(":");
10220                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10221                                }
10222                            }
10223                            outStack.append(")");
10224                        }
10225                    }
10226                }
10227            }
10228
10229            if (!brief && !oomOnly) {
10230                pw.println();
10231                pw.println("Total PSS by process:");
10232                dumpMemItems(pw, "  ", procMems, true);
10233                pw.println();
10234            }
10235            pw.println("Total PSS by OOM adjustment:");
10236            dumpMemItems(pw, "  ", oomMems, false);
10237            if (!oomOnly) {
10238                PrintWriter out = categoryPw != null ? categoryPw : pw;
10239                out.println();
10240                out.println("Total PSS by category:");
10241                dumpMemItems(out, "  ", catMems, true);
10242            }
10243            pw.println();
10244            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10245            final int[] SINGLE_LONG_FORMAT = new int[] {
10246                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10247            };
10248            long[] longOut = new long[1];
10249            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10250                    SINGLE_LONG_FORMAT, null, longOut, null);
10251            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10252            longOut[0] = 0;
10253            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10254                    SINGLE_LONG_FORMAT, null, longOut, null);
10255            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10256            longOut[0] = 0;
10257            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10258                    SINGLE_LONG_FORMAT, null, longOut, null);
10259            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10260            longOut[0] = 0;
10261            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10262                    SINGLE_LONG_FORMAT, null, longOut, null);
10263            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10264            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10265                    pw.print(shared); pw.println(" kB");
10266            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10267                    pw.print(voltile); pw.println(" kB volatile");
10268        }
10269    }
10270
10271    /**
10272     * Searches array of arguments for the specified string
10273     * @param args array of argument strings
10274     * @param value value to search for
10275     * @return true if the value is contained in the array
10276     */
10277    private static boolean scanArgs(String[] args, String value) {
10278        if (args != null) {
10279            for (String arg : args) {
10280                if (value.equals(arg)) {
10281                    return true;
10282                }
10283            }
10284        }
10285        return false;
10286    }
10287
10288    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10289            ContentProviderRecord cpr, boolean always) {
10290        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10291
10292        if (!inLaunching || always) {
10293            synchronized (cpr) {
10294                cpr.launchingApp = null;
10295                cpr.notifyAll();
10296            }
10297            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10298            String names[] = cpr.info.authority.split(";");
10299            for (int j = 0; j < names.length; j++) {
10300                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10301            }
10302        }
10303
10304        for (int i=0; i<cpr.connections.size(); i++) {
10305            ContentProviderConnection conn = cpr.connections.get(i);
10306            if (conn.waiting) {
10307                // If this connection is waiting for the provider, then we don't
10308                // need to mess with its process unless we are always removing
10309                // or for some reason the provider is not currently launching.
10310                if (inLaunching && !always) {
10311                    continue;
10312                }
10313            }
10314            ProcessRecord capp = conn.client;
10315            conn.dead = true;
10316            if (conn.stableCount > 0) {
10317                if (!capp.persistent && capp.thread != null
10318                        && capp.pid != 0
10319                        && capp.pid != MY_PID) {
10320                    Slog.i(TAG, "Kill " + capp.processName
10321                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10322                            + " in dying process " + (proc != null ? proc.processName : "??"));
10323                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10324                            capp.processName, capp.setAdj, "dying provider "
10325                                    + cpr.name.toShortString());
10326                    Process.killProcessQuiet(capp.pid);
10327                }
10328            } else if (capp.thread != null && conn.provider.provider != null) {
10329                try {
10330                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10331                } catch (RemoteException e) {
10332                }
10333                // In the protocol here, we don't expect the client to correctly
10334                // clean up this connection, we'll just remove it.
10335                cpr.connections.remove(i);
10336                conn.client.conProviders.remove(conn);
10337            }
10338        }
10339
10340        if (inLaunching && always) {
10341            mLaunchingProviders.remove(cpr);
10342        }
10343        return inLaunching;
10344    }
10345
10346    /**
10347     * Main code for cleaning up a process when it has gone away.  This is
10348     * called both as a result of the process dying, or directly when stopping
10349     * a process when running in single process mode.
10350     */
10351    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10352            boolean restarting, boolean allowRestart, int index) {
10353        if (index >= 0) {
10354            mLruProcesses.remove(index);
10355        }
10356
10357        mProcessesToGc.remove(app);
10358
10359        // Dismiss any open dialogs.
10360        if (app.crashDialog != null) {
10361            app.crashDialog.dismiss();
10362            app.crashDialog = null;
10363        }
10364        if (app.anrDialog != null) {
10365            app.anrDialog.dismiss();
10366            app.anrDialog = null;
10367        }
10368        if (app.waitDialog != null) {
10369            app.waitDialog.dismiss();
10370            app.waitDialog = null;
10371        }
10372
10373        app.crashing = false;
10374        app.notResponding = false;
10375
10376        app.resetPackageList();
10377        app.unlinkDeathRecipient();
10378        app.thread = null;
10379        app.forcingToForeground = null;
10380        app.foregroundServices = false;
10381        app.foregroundActivities = false;
10382        app.hasShownUi = false;
10383        app.hasAboveClient = false;
10384
10385        mServices.killServicesLocked(app, allowRestart);
10386
10387        boolean restart = false;
10388
10389        // Remove published content providers.
10390        if (!app.pubProviders.isEmpty()) {
10391            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10392            while (it.hasNext()) {
10393                ContentProviderRecord cpr = it.next();
10394
10395                final boolean always = app.bad || !allowRestart;
10396                if (removeDyingProviderLocked(app, cpr, always) || always) {
10397                    // We left the provider in the launching list, need to
10398                    // restart it.
10399                    restart = true;
10400                }
10401
10402                cpr.provider = null;
10403                cpr.proc = null;
10404            }
10405            app.pubProviders.clear();
10406        }
10407
10408        // Take care of any launching providers waiting for this process.
10409        if (checkAppInLaunchingProvidersLocked(app, false)) {
10410            restart = true;
10411        }
10412
10413        // Unregister from connected content providers.
10414        if (!app.conProviders.isEmpty()) {
10415            for (int i=0; i<app.conProviders.size(); i++) {
10416                ContentProviderConnection conn = app.conProviders.get(i);
10417                conn.provider.connections.remove(conn);
10418            }
10419            app.conProviders.clear();
10420        }
10421
10422        // At this point there may be remaining entries in mLaunchingProviders
10423        // where we were the only one waiting, so they are no longer of use.
10424        // Look for these and clean up if found.
10425        // XXX Commented out for now.  Trying to figure out a way to reproduce
10426        // the actual situation to identify what is actually going on.
10427        if (false) {
10428            for (int i=0; i<mLaunchingProviders.size(); i++) {
10429                ContentProviderRecord cpr = (ContentProviderRecord)
10430                        mLaunchingProviders.get(i);
10431                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10432                    synchronized (cpr) {
10433                        cpr.launchingApp = null;
10434                        cpr.notifyAll();
10435                    }
10436                }
10437            }
10438        }
10439
10440        skipCurrentReceiverLocked(app);
10441
10442        // Unregister any receivers.
10443        if (app.receivers.size() > 0) {
10444            Iterator<ReceiverList> it = app.receivers.iterator();
10445            while (it.hasNext()) {
10446                removeReceiverLocked(it.next());
10447            }
10448            app.receivers.clear();
10449        }
10450
10451        // If the app is undergoing backup, tell the backup manager about it
10452        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10453            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10454            try {
10455                IBackupManager bm = IBackupManager.Stub.asInterface(
10456                        ServiceManager.getService(Context.BACKUP_SERVICE));
10457                bm.agentDisconnected(app.info.packageName);
10458            } catch (RemoteException e) {
10459                // can't happen; backup manager is local
10460            }
10461        }
10462
10463        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10464            ProcessChangeItem item = mPendingProcessChanges.get(i);
10465            if (item.pid == app.pid) {
10466                mPendingProcessChanges.remove(i);
10467                mAvailProcessChanges.add(item);
10468            }
10469        }
10470        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10471
10472        // If the caller is restarting this app, then leave it in its
10473        // current lists and let the caller take care of it.
10474        if (restarting) {
10475            return;
10476        }
10477
10478        if (!app.persistent || app.isolated) {
10479            if (DEBUG_PROCESSES) Slog.v(TAG,
10480                    "Removing non-persistent process during cleanup: " + app);
10481            mProcessNames.remove(app.processName, app.uid);
10482            mIsolatedProcesses.remove(app.uid);
10483            if (mHeavyWeightProcess == app) {
10484                mHeavyWeightProcess = null;
10485                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10486            }
10487        } else if (!app.removed) {
10488            // This app is persistent, so we need to keep its record around.
10489            // If it is not already on the pending app list, add it there
10490            // and start a new process for it.
10491            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10492                mPersistentStartingProcesses.add(app);
10493                restart = true;
10494            }
10495        }
10496        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10497                "Clean-up removing on hold: " + app);
10498        mProcessesOnHold.remove(app);
10499
10500        if (app == mHomeProcess) {
10501            mHomeProcess = null;
10502        }
10503        if (app == mPreviousProcess) {
10504            mPreviousProcess = null;
10505        }
10506
10507        if (restart && !app.isolated) {
10508            // We have components that still need to be running in the
10509            // process, so re-launch it.
10510            mProcessNames.put(app.processName, app.uid, app);
10511            startProcessLocked(app, "restart", app.processName);
10512        } else if (app.pid > 0 && app.pid != MY_PID) {
10513            // Goodbye!
10514            synchronized (mPidsSelfLocked) {
10515                mPidsSelfLocked.remove(app.pid);
10516                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10517            }
10518            app.setPid(0);
10519        }
10520    }
10521
10522    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10523        // Look through the content providers we are waiting to have launched,
10524        // and if any run in this process then either schedule a restart of
10525        // the process or kill the client waiting for it if this process has
10526        // gone bad.
10527        int NL = mLaunchingProviders.size();
10528        boolean restart = false;
10529        for (int i=0; i<NL; i++) {
10530            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10531            if (cpr.launchingApp == app) {
10532                if (!alwaysBad && !app.bad) {
10533                    restart = true;
10534                } else {
10535                    removeDyingProviderLocked(app, cpr, true);
10536                    NL = mLaunchingProviders.size();
10537                }
10538            }
10539        }
10540        return restart;
10541    }
10542
10543    // =========================================================
10544    // SERVICES
10545    // =========================================================
10546
10547    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10548            int flags) {
10549        enforceNotIsolatedCaller("getServices");
10550        synchronized (this) {
10551            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10552        }
10553    }
10554
10555    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10556        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10557        synchronized (this) {
10558            return mServices.getRunningServiceControlPanelLocked(name);
10559        }
10560    }
10561
10562    public ComponentName startService(IApplicationThread caller, Intent service,
10563            String resolvedType, int userId) {
10564        enforceNotIsolatedCaller("startService");
10565        // Refuse possible leaked file descriptors
10566        if (service != null && service.hasFileDescriptors() == true) {
10567            throw new IllegalArgumentException("File descriptors passed in Intent");
10568        }
10569
10570        if (DEBUG_SERVICE)
10571            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10572        synchronized(this) {
10573            final int callingPid = Binder.getCallingPid();
10574            final int callingUid = Binder.getCallingUid();
10575            checkValidCaller(callingUid, userId);
10576            final long origId = Binder.clearCallingIdentity();
10577            ComponentName res = mServices.startServiceLocked(caller, service,
10578                    resolvedType, callingPid, callingUid, userId);
10579            Binder.restoreCallingIdentity(origId);
10580            return res;
10581        }
10582    }
10583
10584    ComponentName startServiceInPackage(int uid,
10585            Intent service, String resolvedType) {
10586        synchronized(this) {
10587            if (DEBUG_SERVICE)
10588                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10589            final long origId = Binder.clearCallingIdentity();
10590            ComponentName res = mServices.startServiceLocked(null, service,
10591                    resolvedType, -1, uid, UserHandle.getUserId(uid));
10592            Binder.restoreCallingIdentity(origId);
10593            return res;
10594        }
10595    }
10596
10597    public int stopService(IApplicationThread caller, Intent service,
10598            String resolvedType, int userId) {
10599        enforceNotIsolatedCaller("stopService");
10600        // Refuse possible leaked file descriptors
10601        if (service != null && service.hasFileDescriptors() == true) {
10602            throw new IllegalArgumentException("File descriptors passed in Intent");
10603        }
10604
10605        checkValidCaller(Binder.getCallingUid(), userId);
10606
10607        synchronized(this) {
10608            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10609        }
10610    }
10611
10612    public IBinder peekService(Intent service, String resolvedType) {
10613        enforceNotIsolatedCaller("peekService");
10614        // Refuse possible leaked file descriptors
10615        if (service != null && service.hasFileDescriptors() == true) {
10616            throw new IllegalArgumentException("File descriptors passed in Intent");
10617        }
10618        synchronized(this) {
10619            return mServices.peekServiceLocked(service, resolvedType);
10620        }
10621    }
10622
10623    public boolean stopServiceToken(ComponentName className, IBinder token,
10624            int startId) {
10625        synchronized(this) {
10626            return mServices.stopServiceTokenLocked(className, token, startId);
10627        }
10628    }
10629
10630    public void setServiceForeground(ComponentName className, IBinder token,
10631            int id, Notification notification, boolean removeNotification) {
10632        synchronized(this) {
10633            mServices.setServiceForegroundLocked(className, token, id, notification,
10634                    removeNotification);
10635        }
10636    }
10637
10638    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10639            String className, int flags) {
10640        boolean result = false;
10641        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10642            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10643                if (ActivityManager.checkUidPermission(
10644                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10645                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10646                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10647                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10648                            + " requests FLAG_SINGLE_USER, but app does not hold "
10649                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10650                    Slog.w(TAG, msg);
10651                    throw new SecurityException(msg);
10652                }
10653                result = true;
10654            }
10655        } else if (componentProcessName == aInfo.packageName) {
10656            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10657        } else if ("system".equals(componentProcessName)) {
10658            result = true;
10659        }
10660        if (DEBUG_MU) {
10661            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10662                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10663        }
10664        return result;
10665    }
10666
10667    public int bindService(IApplicationThread caller, IBinder token,
10668            Intent service, String resolvedType,
10669            IServiceConnection connection, int flags, int userId) {
10670        enforceNotIsolatedCaller("bindService");
10671        // Refuse possible leaked file descriptors
10672        if (service != null && service.hasFileDescriptors() == true) {
10673            throw new IllegalArgumentException("File descriptors passed in Intent");
10674        }
10675
10676        checkValidCaller(Binder.getCallingUid(), userId);
10677
10678        synchronized(this) {
10679            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10680                    connection, flags, userId);
10681        }
10682    }
10683
10684    public boolean unbindService(IServiceConnection connection) {
10685        synchronized (this) {
10686            return mServices.unbindServiceLocked(connection);
10687        }
10688    }
10689
10690    public void publishService(IBinder token, Intent intent, IBinder service) {
10691        // Refuse possible leaked file descriptors
10692        if (intent != null && intent.hasFileDescriptors() == true) {
10693            throw new IllegalArgumentException("File descriptors passed in Intent");
10694        }
10695
10696        synchronized(this) {
10697            if (!(token instanceof ServiceRecord)) {
10698                throw new IllegalArgumentException("Invalid service token");
10699            }
10700            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10701        }
10702    }
10703
10704    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10705        // Refuse possible leaked file descriptors
10706        if (intent != null && intent.hasFileDescriptors() == true) {
10707            throw new IllegalArgumentException("File descriptors passed in Intent");
10708        }
10709
10710        synchronized(this) {
10711            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10712        }
10713    }
10714
10715    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10716        synchronized(this) {
10717            if (!(token instanceof ServiceRecord)) {
10718                throw new IllegalArgumentException("Invalid service token");
10719            }
10720            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10721        }
10722    }
10723
10724    // =========================================================
10725    // BACKUP AND RESTORE
10726    // =========================================================
10727
10728    // Cause the target app to be launched if necessary and its backup agent
10729    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10730    // activity manager to announce its creation.
10731    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10732        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10733        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10734
10735        synchronized(this) {
10736            // !!! TODO: currently no check here that we're already bound
10737            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10738            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10739            synchronized (stats) {
10740                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10741            }
10742
10743            // Backup agent is now in use, its package can't be stopped.
10744            try {
10745                AppGlobals.getPackageManager().setPackageStoppedState(
10746                        app.packageName, false, UserHandle.getUserId(app.uid));
10747            } catch (RemoteException e) {
10748            } catch (IllegalArgumentException e) {
10749                Slog.w(TAG, "Failed trying to unstop package "
10750                        + app.packageName + ": " + e);
10751            }
10752
10753            BackupRecord r = new BackupRecord(ss, app, backupMode);
10754            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10755                    ? new ComponentName(app.packageName, app.backupAgentName)
10756                    : new ComponentName("android", "FullBackupAgent");
10757            // startProcessLocked() returns existing proc's record if it's already running
10758            ProcessRecord proc = startProcessLocked(app.processName, app,
10759                    false, 0, "backup", hostingName, false, false);
10760            if (proc == null) {
10761                Slog.e(TAG, "Unable to start backup agent process " + r);
10762                return false;
10763            }
10764
10765            r.app = proc;
10766            mBackupTarget = r;
10767            mBackupAppName = app.packageName;
10768
10769            // Try not to kill the process during backup
10770            updateOomAdjLocked(proc);
10771
10772            // If the process is already attached, schedule the creation of the backup agent now.
10773            // If it is not yet live, this will be done when it attaches to the framework.
10774            if (proc.thread != null) {
10775                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10776                try {
10777                    proc.thread.scheduleCreateBackupAgent(app,
10778                            compatibilityInfoForPackageLocked(app), backupMode);
10779                } catch (RemoteException e) {
10780                    // Will time out on the backup manager side
10781                }
10782            } else {
10783                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10784            }
10785            // Invariants: at this point, the target app process exists and the application
10786            // is either already running or in the process of coming up.  mBackupTarget and
10787            // mBackupAppName describe the app, so that when it binds back to the AM we
10788            // know that it's scheduled for a backup-agent operation.
10789        }
10790
10791        return true;
10792    }
10793
10794    // A backup agent has just come up
10795    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10796        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10797                + " = " + agent);
10798
10799        synchronized(this) {
10800            if (!agentPackageName.equals(mBackupAppName)) {
10801                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10802                return;
10803            }
10804        }
10805
10806        long oldIdent = Binder.clearCallingIdentity();
10807        try {
10808            IBackupManager bm = IBackupManager.Stub.asInterface(
10809                    ServiceManager.getService(Context.BACKUP_SERVICE));
10810            bm.agentConnected(agentPackageName, agent);
10811        } catch (RemoteException e) {
10812            // can't happen; the backup manager service is local
10813        } catch (Exception e) {
10814            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10815            e.printStackTrace();
10816        } finally {
10817            Binder.restoreCallingIdentity(oldIdent);
10818        }
10819    }
10820
10821    // done with this agent
10822    public void unbindBackupAgent(ApplicationInfo appInfo) {
10823        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10824        if (appInfo == null) {
10825            Slog.w(TAG, "unbind backup agent for null app");
10826            return;
10827        }
10828
10829        synchronized(this) {
10830            if (mBackupAppName == null) {
10831                Slog.w(TAG, "Unbinding backup agent with no active backup");
10832                return;
10833            }
10834
10835            if (!mBackupAppName.equals(appInfo.packageName)) {
10836                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10837                return;
10838            }
10839
10840            ProcessRecord proc = mBackupTarget.app;
10841            mBackupTarget = null;
10842            mBackupAppName = null;
10843
10844            // Not backing this app up any more; reset its OOM adjustment
10845            updateOomAdjLocked(proc);
10846
10847            // If the app crashed during backup, 'thread' will be null here
10848            if (proc.thread != null) {
10849                try {
10850                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10851                            compatibilityInfoForPackageLocked(appInfo));
10852                } catch (Exception e) {
10853                    Slog.e(TAG, "Exception when unbinding backup agent:");
10854                    e.printStackTrace();
10855                }
10856            }
10857        }
10858    }
10859    // =========================================================
10860    // BROADCASTS
10861    // =========================================================
10862
10863    private final List getStickiesLocked(String action, IntentFilter filter,
10864            List cur) {
10865        final ContentResolver resolver = mContext.getContentResolver();
10866        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10867        if (list == null) {
10868            return cur;
10869        }
10870        int N = list.size();
10871        for (int i=0; i<N; i++) {
10872            Intent intent = list.get(i);
10873            if (filter.match(resolver, intent, true, TAG) >= 0) {
10874                if (cur == null) {
10875                    cur = new ArrayList<Intent>();
10876                }
10877                cur.add(intent);
10878            }
10879        }
10880        return cur;
10881    }
10882
10883    boolean isPendingBroadcastProcessLocked(int pid) {
10884        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10885                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10886    }
10887
10888    void skipPendingBroadcastLocked(int pid) {
10889            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10890            for (BroadcastQueue queue : mBroadcastQueues) {
10891                queue.skipPendingBroadcastLocked(pid);
10892            }
10893    }
10894
10895    // The app just attached; send any pending broadcasts that it should receive
10896    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10897        boolean didSomething = false;
10898        for (BroadcastQueue queue : mBroadcastQueues) {
10899            didSomething |= queue.sendPendingBroadcastsLocked(app);
10900        }
10901        return didSomething;
10902    }
10903
10904    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10905            IIntentReceiver receiver, IntentFilter filter, String permission) {
10906        enforceNotIsolatedCaller("registerReceiver");
10907        int callingUid;
10908        synchronized(this) {
10909            ProcessRecord callerApp = null;
10910            if (caller != null) {
10911                callerApp = getRecordForAppLocked(caller);
10912                if (callerApp == null) {
10913                    throw new SecurityException(
10914                            "Unable to find app for caller " + caller
10915                            + " (pid=" + Binder.getCallingPid()
10916                            + ") when registering receiver " + receiver);
10917                }
10918                if (callerApp.info.uid != Process.SYSTEM_UID &&
10919                        !callerApp.pkgList.contains(callerPackage)) {
10920                    throw new SecurityException("Given caller package " + callerPackage
10921                            + " is not running in process " + callerApp);
10922                }
10923                callingUid = callerApp.info.uid;
10924            } else {
10925                callerPackage = null;
10926                callingUid = Binder.getCallingUid();
10927            }
10928
10929            List allSticky = null;
10930
10931            // Look for any matching sticky broadcasts...
10932            Iterator actions = filter.actionsIterator();
10933            if (actions != null) {
10934                while (actions.hasNext()) {
10935                    String action = (String)actions.next();
10936                    allSticky = getStickiesLocked(action, filter, allSticky);
10937                }
10938            } else {
10939                allSticky = getStickiesLocked(null, filter, allSticky);
10940            }
10941
10942            // The first sticky in the list is returned directly back to
10943            // the client.
10944            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10945
10946            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10947                    + ": " + sticky);
10948
10949            if (receiver == null) {
10950                return sticky;
10951            }
10952
10953            ReceiverList rl
10954                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10955            if (rl == null) {
10956                rl = new ReceiverList(this, callerApp,
10957                        Binder.getCallingPid(),
10958                        Binder.getCallingUid(), receiver);
10959                if (rl.app != null) {
10960                    rl.app.receivers.add(rl);
10961                } else {
10962                    try {
10963                        receiver.asBinder().linkToDeath(rl, 0);
10964                    } catch (RemoteException e) {
10965                        return sticky;
10966                    }
10967                    rl.linkedToDeath = true;
10968                }
10969                mRegisteredReceivers.put(receiver.asBinder(), rl);
10970            }
10971            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10972                    permission, callingUid);
10973            rl.add(bf);
10974            if (!bf.debugCheck()) {
10975                Slog.w(TAG, "==> For Dynamic broadast");
10976            }
10977            mReceiverResolver.addFilter(bf);
10978
10979            // Enqueue broadcasts for all existing stickies that match
10980            // this filter.
10981            if (allSticky != null) {
10982                ArrayList receivers = new ArrayList();
10983                receivers.add(bf);
10984
10985                int N = allSticky.size();
10986                for (int i=0; i<N; i++) {
10987                    Intent intent = (Intent)allSticky.get(i);
10988                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10989                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10990                            null, -1, -1, null, receivers, null, 0, null, null,
10991                            false, true, true, false, -1);
10992                    queue.enqueueParallelBroadcastLocked(r);
10993                    queue.scheduleBroadcastsLocked();
10994                }
10995            }
10996
10997            return sticky;
10998        }
10999    }
11000
11001    public void unregisterReceiver(IIntentReceiver receiver) {
11002        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11003
11004        final long origId = Binder.clearCallingIdentity();
11005        try {
11006            boolean doTrim = false;
11007
11008            synchronized(this) {
11009                ReceiverList rl
11010                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11011                if (rl != null) {
11012                    if (rl.curBroadcast != null) {
11013                        BroadcastRecord r = rl.curBroadcast;
11014                        final boolean doNext = finishReceiverLocked(
11015                                receiver.asBinder(), r.resultCode, r.resultData,
11016                                r.resultExtras, r.resultAbort, true);
11017                        if (doNext) {
11018                            doTrim = true;
11019                            r.queue.processNextBroadcast(false);
11020                        }
11021                    }
11022
11023                    if (rl.app != null) {
11024                        rl.app.receivers.remove(rl);
11025                    }
11026                    removeReceiverLocked(rl);
11027                    if (rl.linkedToDeath) {
11028                        rl.linkedToDeath = false;
11029                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11030                    }
11031                }
11032            }
11033
11034            // If we actually concluded any broadcasts, we might now be able
11035            // to trim the recipients' apps from our working set
11036            if (doTrim) {
11037                trimApplications();
11038                return;
11039            }
11040
11041        } finally {
11042            Binder.restoreCallingIdentity(origId);
11043        }
11044    }
11045
11046    void removeReceiverLocked(ReceiverList rl) {
11047        mRegisteredReceivers.remove(rl.receiver.asBinder());
11048        int N = rl.size();
11049        for (int i=0; i<N; i++) {
11050            mReceiverResolver.removeFilter(rl.get(i));
11051        }
11052    }
11053
11054    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11055        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11056            ProcessRecord r = mLruProcesses.get(i);
11057            if (r.thread != null) {
11058                try {
11059                    r.thread.dispatchPackageBroadcast(cmd, packages);
11060                } catch (RemoteException ex) {
11061                }
11062            }
11063        }
11064    }
11065
11066    private final int broadcastIntentLocked(ProcessRecord callerApp,
11067            String callerPackage, Intent intent, String resolvedType,
11068            IIntentReceiver resultTo, int resultCode, String resultData,
11069            Bundle map, String requiredPermission,
11070            boolean ordered, boolean sticky, int callingPid, int callingUid,
11071            int userId) {
11072        intent = new Intent(intent);
11073
11074        // By default broadcasts do not go to stopped apps.
11075        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11076
11077        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11078            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11079            + " ordered=" + ordered + " userid=" + userId);
11080        if ((resultTo != null) && !ordered) {
11081            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11082        }
11083
11084        boolean onlySendToCaller = false;
11085
11086        // If the caller is trying to send this broadcast to a different
11087        // user, verify that is allowed.
11088        if (UserHandle.getUserId(callingUid) != userId) {
11089            if (checkComponentPermission(
11090                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11091                    callingPid, callingUid, -1, true)
11092                    != PackageManager.PERMISSION_GRANTED) {
11093                if (checkComponentPermission(
11094                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11095                        callingPid, callingUid, -1, true)
11096                        == PackageManager.PERMISSION_GRANTED) {
11097                    onlySendToCaller = true;
11098                } else {
11099                    String msg = "Permission Denial: " + intent.getAction()
11100                            + " broadcast from " + callerPackage
11101                            + " asks to send as user " + userId
11102                            + " but is calling from user " + UserHandle.getUserId(callingUid)
11103                            + "; this requires "
11104                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11105                    Slog.w(TAG, msg);
11106                    throw new SecurityException(msg);
11107                }
11108            }
11109        }
11110
11111        // Handle special intents: if this broadcast is from the package
11112        // manager about a package being removed, we need to remove all of
11113        // its activities from the history stack.
11114        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11115                intent.getAction());
11116        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11117                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11118                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11119                || uidRemoved) {
11120            if (checkComponentPermission(
11121                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11122                    callingPid, callingUid, -1, true)
11123                    == PackageManager.PERMISSION_GRANTED) {
11124                if (uidRemoved) {
11125                    final Bundle intentExtras = intent.getExtras();
11126                    final int uid = intentExtras != null
11127                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11128                    if (uid >= 0) {
11129                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11130                        synchronized (bs) {
11131                            bs.removeUidStatsLocked(uid);
11132                        }
11133                    }
11134                } else {
11135                    // If resources are unvailble just force stop all
11136                    // those packages and flush the attribute cache as well.
11137                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11138                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11139                        if (list != null && (list.length > 0)) {
11140                            for (String pkg : list) {
11141                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11142                            }
11143                            sendPackageBroadcastLocked(
11144                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11145                        }
11146                    } else {
11147                        Uri data = intent.getData();
11148                        String ssp;
11149                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11150                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11151                                forceStopPackageLocked(ssp,
11152                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11153                                        false, userId);
11154                            }
11155                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11156                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11157                                        new String[] {ssp});
11158                            }
11159                        }
11160                    }
11161                }
11162            } else {
11163                String msg = "Permission Denial: " + intent.getAction()
11164                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11165                        + ", uid=" + callingUid + ")"
11166                        + " requires "
11167                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11168                Slog.w(TAG, msg);
11169                throw new SecurityException(msg);
11170            }
11171
11172        // Special case for adding a package: by default turn on compatibility
11173        // mode.
11174        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11175            Uri data = intent.getData();
11176            String ssp;
11177            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11178                mCompatModePackages.handlePackageAddedLocked(ssp,
11179                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11180            }
11181        }
11182
11183        /*
11184         * If this is the time zone changed action, queue up a message that will reset the timezone
11185         * of all currently running processes. This message will get queued up before the broadcast
11186         * happens.
11187         */
11188        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11189            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11190        }
11191
11192        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11193            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11194        }
11195
11196        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11197            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11198            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11199        }
11200
11201        /*
11202         * Prevent non-system code (defined here to be non-persistent
11203         * processes) from sending protected broadcasts.
11204         */
11205        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11206            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11207            callingUid == 0) {
11208            // Always okay.
11209        } else if (callerApp == null || !callerApp.persistent) {
11210            try {
11211                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11212                        intent.getAction())) {
11213                    String msg = "Permission Denial: not allowed to send broadcast "
11214                            + intent.getAction() + " from pid="
11215                            + callingPid + ", uid=" + callingUid;
11216                    Slog.w(TAG, msg);
11217                    throw new SecurityException(msg);
11218                }
11219            } catch (RemoteException e) {
11220                Slog.w(TAG, "Remote exception", e);
11221                return ActivityManager.BROADCAST_SUCCESS;
11222            }
11223        }
11224
11225        // Add to the sticky list if requested.
11226        if (sticky) {
11227            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11228                    callingPid, callingUid)
11229                    != PackageManager.PERMISSION_GRANTED) {
11230                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11231                        + callingPid + ", uid=" + callingUid
11232                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11233                Slog.w(TAG, msg);
11234                throw new SecurityException(msg);
11235            }
11236            if (requiredPermission != null) {
11237                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11238                        + " and enforce permission " + requiredPermission);
11239                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11240            }
11241            if (intent.getComponent() != null) {
11242                throw new SecurityException(
11243                        "Sticky broadcasts can't target a specific component");
11244            }
11245            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11246            if (list == null) {
11247                list = new ArrayList<Intent>();
11248                mStickyBroadcasts.put(intent.getAction(), list);
11249            }
11250            int N = list.size();
11251            int i;
11252            for (i=0; i<N; i++) {
11253                if (intent.filterEquals(list.get(i))) {
11254                    // This sticky already exists, replace it.
11255                    list.set(i, new Intent(intent));
11256                    break;
11257                }
11258            }
11259            if (i >= N) {
11260                list.add(new Intent(intent));
11261            }
11262        }
11263
11264        // Figure out who all will receive this broadcast.
11265        List receivers = null;
11266        List<BroadcastFilter> registeredReceivers = null;
11267        try {
11268            // Need to resolve the intent to interested receivers...
11269            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11270                     == 0) {
11271                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11272                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11273            }
11274            if (intent.getComponent() == null) {
11275                registeredReceivers = mReceiverResolver.queryIntent(intent,
11276                        resolvedType, false, userId);
11277            }
11278        } catch (RemoteException ex) {
11279            // pm is in same process, this will never happen.
11280        }
11281
11282        final boolean replacePending =
11283                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11284
11285        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11286                + " replacePending=" + replacePending);
11287
11288        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11289        if (!ordered && NR > 0) {
11290            // If we are not serializing this broadcast, then send the
11291            // registered receivers separately so they don't wait for the
11292            // components to be launched.
11293            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11294            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11295                    callerPackage, callingPid, callingUid, requiredPermission,
11296                    registeredReceivers, resultTo, resultCode, resultData, map,
11297                    ordered, sticky, false, onlySendToCaller, userId);
11298            if (DEBUG_BROADCAST) Slog.v(
11299                    TAG, "Enqueueing parallel broadcast " + r);
11300            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11301            if (!replaced) {
11302                queue.enqueueParallelBroadcastLocked(r);
11303                queue.scheduleBroadcastsLocked();
11304            }
11305            registeredReceivers = null;
11306            NR = 0;
11307        }
11308
11309        // Merge into one list.
11310        int ir = 0;
11311        if (receivers != null) {
11312            // A special case for PACKAGE_ADDED: do not allow the package
11313            // being added to see this broadcast.  This prevents them from
11314            // using this as a back door to get run as soon as they are
11315            // installed.  Maybe in the future we want to have a special install
11316            // broadcast or such for apps, but we'd like to deliberately make
11317            // this decision.
11318            String skipPackages[] = null;
11319            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11320                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11321                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11322                Uri data = intent.getData();
11323                if (data != null) {
11324                    String pkgName = data.getSchemeSpecificPart();
11325                    if (pkgName != null) {
11326                        skipPackages = new String[] { pkgName };
11327                    }
11328                }
11329            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11330                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11331            }
11332            if (skipPackages != null && (skipPackages.length > 0)) {
11333                for (String skipPackage : skipPackages) {
11334                    if (skipPackage != null) {
11335                        int NT = receivers.size();
11336                        for (int it=0; it<NT; it++) {
11337                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11338                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11339                                receivers.remove(it);
11340                                it--;
11341                                NT--;
11342                            }
11343                        }
11344                    }
11345                }
11346            }
11347
11348            int NT = receivers != null ? receivers.size() : 0;
11349            int it = 0;
11350            ResolveInfo curt = null;
11351            BroadcastFilter curr = null;
11352            while (it < NT && ir < NR) {
11353                if (curt == null) {
11354                    curt = (ResolveInfo)receivers.get(it);
11355                }
11356                if (curr == null) {
11357                    curr = registeredReceivers.get(ir);
11358                }
11359                if (curr.getPriority() >= curt.priority) {
11360                    // Insert this broadcast record into the final list.
11361                    receivers.add(it, curr);
11362                    ir++;
11363                    curr = null;
11364                    it++;
11365                    NT++;
11366                } else {
11367                    // Skip to the next ResolveInfo in the final list.
11368                    it++;
11369                    curt = null;
11370                }
11371            }
11372        }
11373        while (ir < NR) {
11374            if (receivers == null) {
11375                receivers = new ArrayList();
11376            }
11377            receivers.add(registeredReceivers.get(ir));
11378            ir++;
11379        }
11380
11381        if ((receivers != null && receivers.size() > 0)
11382                || resultTo != null) {
11383            BroadcastQueue queue = broadcastQueueForIntent(intent);
11384            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11385                    callerPackage, callingPid, callingUid, requiredPermission,
11386                    receivers, resultTo, resultCode, resultData, map, ordered,
11387                    sticky, false, onlySendToCaller, userId);
11388            if (DEBUG_BROADCAST) Slog.v(
11389                    TAG, "Enqueueing ordered broadcast " + r
11390                    + ": prev had " + queue.mOrderedBroadcasts.size());
11391            if (DEBUG_BROADCAST) {
11392                int seq = r.intent.getIntExtra("seq", -1);
11393                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11394            }
11395            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11396            if (!replaced) {
11397                queue.enqueueOrderedBroadcastLocked(r);
11398                queue.scheduleBroadcastsLocked();
11399            }
11400        }
11401
11402        return ActivityManager.BROADCAST_SUCCESS;
11403    }
11404
11405    final Intent verifyBroadcastLocked(Intent intent) {
11406        // Refuse possible leaked file descriptors
11407        if (intent != null && intent.hasFileDescriptors() == true) {
11408            throw new IllegalArgumentException("File descriptors passed in Intent");
11409        }
11410
11411        int flags = intent.getFlags();
11412
11413        if (!mProcessesReady) {
11414            // if the caller really truly claims to know what they're doing, go
11415            // ahead and allow the broadcast without launching any receivers
11416            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11417                intent = new Intent(intent);
11418                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11419            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11420                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11421                        + " before boot completion");
11422                throw new IllegalStateException("Cannot broadcast before boot completed");
11423            }
11424        }
11425
11426        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11427            throw new IllegalArgumentException(
11428                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11429        }
11430
11431        return intent;
11432    }
11433
11434    public final int broadcastIntent(IApplicationThread caller,
11435            Intent intent, String resolvedType, IIntentReceiver resultTo,
11436            int resultCode, String resultData, Bundle map,
11437            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11438        enforceNotIsolatedCaller("broadcastIntent");
11439        synchronized(this) {
11440            intent = verifyBroadcastLocked(intent);
11441
11442            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11443            final int callingPid = Binder.getCallingPid();
11444            final int callingUid = Binder.getCallingUid();
11445            final long origId = Binder.clearCallingIdentity();
11446            int res = broadcastIntentLocked(callerApp,
11447                    callerApp != null ? callerApp.info.packageName : null,
11448                    intent, resolvedType, resultTo,
11449                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11450                    callingPid, callingUid, userId);
11451            Binder.restoreCallingIdentity(origId);
11452            return res;
11453        }
11454    }
11455
11456    int broadcastIntentInPackage(String packageName, int uid,
11457            Intent intent, String resolvedType, IIntentReceiver resultTo,
11458            int resultCode, String resultData, Bundle map,
11459            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11460        synchronized(this) {
11461            intent = verifyBroadcastLocked(intent);
11462
11463            final long origId = Binder.clearCallingIdentity();
11464            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11465                    resultTo, resultCode, resultData, map, requiredPermission,
11466                    serialized, sticky, -1, uid, userId);
11467            Binder.restoreCallingIdentity(origId);
11468            return res;
11469        }
11470    }
11471
11472    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11473    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11474        // Refuse possible leaked file descriptors
11475        if (intent != null && intent.hasFileDescriptors() == true) {
11476            throw new IllegalArgumentException("File descriptors passed in Intent");
11477        }
11478
11479        synchronized(this) {
11480            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11481                    != PackageManager.PERMISSION_GRANTED) {
11482                String msg = "Permission Denial: unbroadcastIntent() from pid="
11483                        + Binder.getCallingPid()
11484                        + ", uid=" + Binder.getCallingUid()
11485                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11486                Slog.w(TAG, msg);
11487                throw new SecurityException(msg);
11488            }
11489            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11490            if (list != null) {
11491                int N = list.size();
11492                int i;
11493                for (i=0; i<N; i++) {
11494                    if (intent.filterEquals(list.get(i))) {
11495                        list.remove(i);
11496                        break;
11497                    }
11498                }
11499            }
11500        }
11501    }
11502
11503    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11504            String resultData, Bundle resultExtras, boolean resultAbort,
11505            boolean explicit) {
11506        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11507        if (r == null) {
11508            Slog.w(TAG, "finishReceiver called but not found on queue");
11509            return false;
11510        }
11511
11512        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11513                explicit);
11514    }
11515
11516    public void finishReceiver(IBinder who, int resultCode, String resultData,
11517            Bundle resultExtras, boolean resultAbort) {
11518        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11519
11520        // Refuse possible leaked file descriptors
11521        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11522            throw new IllegalArgumentException("File descriptors passed in Bundle");
11523        }
11524
11525        final long origId = Binder.clearCallingIdentity();
11526        try {
11527            boolean doNext = false;
11528            BroadcastRecord r = null;
11529
11530            synchronized(this) {
11531                r = broadcastRecordForReceiverLocked(who);
11532                if (r != null) {
11533                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11534                        resultData, resultExtras, resultAbort, true);
11535                }
11536            }
11537
11538            if (doNext) {
11539                r.queue.processNextBroadcast(false);
11540            }
11541            trimApplications();
11542        } finally {
11543            Binder.restoreCallingIdentity(origId);
11544        }
11545    }
11546
11547    // =========================================================
11548    // INSTRUMENTATION
11549    // =========================================================
11550
11551    public boolean startInstrumentation(ComponentName className,
11552            String profileFile, int flags, Bundle arguments,
11553            IInstrumentationWatcher watcher) {
11554        enforceNotIsolatedCaller("startInstrumentation");
11555        // Refuse possible leaked file descriptors
11556        if (arguments != null && arguments.hasFileDescriptors()) {
11557            throw new IllegalArgumentException("File descriptors passed in Bundle");
11558        }
11559
11560        synchronized(this) {
11561            InstrumentationInfo ii = null;
11562            ApplicationInfo ai = null;
11563            try {
11564                ii = mContext.getPackageManager().getInstrumentationInfo(
11565                    className, STOCK_PM_FLAGS);
11566                ai = mContext.getPackageManager().getApplicationInfo(
11567                        ii.targetPackage, STOCK_PM_FLAGS);
11568            } catch (PackageManager.NameNotFoundException e) {
11569            }
11570            if (ii == null) {
11571                reportStartInstrumentationFailure(watcher, className,
11572                        "Unable to find instrumentation info for: " + className);
11573                return false;
11574            }
11575            if (ai == null) {
11576                reportStartInstrumentationFailure(watcher, className,
11577                        "Unable to find instrumentation target package: " + ii.targetPackage);
11578                return false;
11579            }
11580
11581            int match = mContext.getPackageManager().checkSignatures(
11582                    ii.targetPackage, ii.packageName);
11583            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11584                String msg = "Permission Denial: starting instrumentation "
11585                        + className + " from pid="
11586                        + Binder.getCallingPid()
11587                        + ", uid=" + Binder.getCallingPid()
11588                        + " not allowed because package " + ii.packageName
11589                        + " does not have a signature matching the target "
11590                        + ii.targetPackage;
11591                reportStartInstrumentationFailure(watcher, className, msg);
11592                throw new SecurityException(msg);
11593            }
11594
11595            int userId = UserHandle.getCallingUserId();
11596            final long origId = Binder.clearCallingIdentity();
11597            // Instrumentation can kill and relaunch even persistent processes
11598            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11599            ProcessRecord app = addAppLocked(ai, false);
11600            app.instrumentationClass = className;
11601            app.instrumentationInfo = ai;
11602            app.instrumentationProfileFile = profileFile;
11603            app.instrumentationArguments = arguments;
11604            app.instrumentationWatcher = watcher;
11605            app.instrumentationResultClass = className;
11606            Binder.restoreCallingIdentity(origId);
11607        }
11608
11609        return true;
11610    }
11611
11612    /**
11613     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11614     * error to the logs, but if somebody is watching, send the report there too.  This enables
11615     * the "am" command to report errors with more information.
11616     *
11617     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11618     * @param cn The component name of the instrumentation.
11619     * @param report The error report.
11620     */
11621    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11622            ComponentName cn, String report) {
11623        Slog.w(TAG, report);
11624        try {
11625            if (watcher != null) {
11626                Bundle results = new Bundle();
11627                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11628                results.putString("Error", report);
11629                watcher.instrumentationStatus(cn, -1, results);
11630            }
11631        } catch (RemoteException e) {
11632            Slog.w(TAG, e);
11633        }
11634    }
11635
11636    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11637        if (app.instrumentationWatcher != null) {
11638            try {
11639                // NOTE:  IInstrumentationWatcher *must* be oneway here
11640                app.instrumentationWatcher.instrumentationFinished(
11641                    app.instrumentationClass,
11642                    resultCode,
11643                    results);
11644            } catch (RemoteException e) {
11645            }
11646        }
11647        app.instrumentationWatcher = null;
11648        app.instrumentationClass = null;
11649        app.instrumentationInfo = null;
11650        app.instrumentationProfileFile = null;
11651        app.instrumentationArguments = null;
11652
11653        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11654    }
11655
11656    public void finishInstrumentation(IApplicationThread target,
11657            int resultCode, Bundle results) {
11658        int userId = UserHandle.getCallingUserId();
11659        // Refuse possible leaked file descriptors
11660        if (results != null && results.hasFileDescriptors()) {
11661            throw new IllegalArgumentException("File descriptors passed in Intent");
11662        }
11663
11664        synchronized(this) {
11665            ProcessRecord app = getRecordForAppLocked(target);
11666            if (app == null) {
11667                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11668                return;
11669            }
11670            final long origId = Binder.clearCallingIdentity();
11671            finishInstrumentationLocked(app, resultCode, results);
11672            Binder.restoreCallingIdentity(origId);
11673        }
11674    }
11675
11676    // =========================================================
11677    // CONFIGURATION
11678    // =========================================================
11679
11680    public ConfigurationInfo getDeviceConfigurationInfo() {
11681        ConfigurationInfo config = new ConfigurationInfo();
11682        synchronized (this) {
11683            config.reqTouchScreen = mConfiguration.touchscreen;
11684            config.reqKeyboardType = mConfiguration.keyboard;
11685            config.reqNavigation = mConfiguration.navigation;
11686            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11687                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11688                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11689            }
11690            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11691                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11692                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11693            }
11694            config.reqGlEsVersion = GL_ES_VERSION;
11695        }
11696        return config;
11697    }
11698
11699    public Configuration getConfiguration() {
11700        Configuration ci;
11701        synchronized(this) {
11702            ci = new Configuration(mConfiguration);
11703        }
11704        return ci;
11705    }
11706
11707    public void updatePersistentConfiguration(Configuration values) {
11708        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11709                "updateConfiguration()");
11710        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11711                "updateConfiguration()");
11712        if (values == null) {
11713            throw new NullPointerException("Configuration must not be null");
11714        }
11715
11716        synchronized(this) {
11717            final long origId = Binder.clearCallingIdentity();
11718            updateConfigurationLocked(values, null, true, false);
11719            Binder.restoreCallingIdentity(origId);
11720        }
11721    }
11722
11723    public void updateConfiguration(Configuration values) {
11724        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11725                "updateConfiguration()");
11726
11727        synchronized(this) {
11728            if (values == null && mWindowManager != null) {
11729                // sentinel: fetch the current configuration from the window manager
11730                values = mWindowManager.computeNewConfiguration();
11731            }
11732
11733            if (mWindowManager != null) {
11734                mProcessList.applyDisplaySize(mWindowManager);
11735            }
11736
11737            final long origId = Binder.clearCallingIdentity();
11738            if (values != null) {
11739                Settings.System.clearConfiguration(values);
11740            }
11741            updateConfigurationLocked(values, null, false, false);
11742            Binder.restoreCallingIdentity(origId);
11743        }
11744    }
11745
11746    /**
11747     * Do either or both things: (1) change the current configuration, and (2)
11748     * make sure the given activity is running with the (now) current
11749     * configuration.  Returns true if the activity has been left running, or
11750     * false if <var>starting</var> is being destroyed to match the new
11751     * configuration.
11752     * @param persistent TODO
11753     */
11754    boolean updateConfigurationLocked(Configuration values,
11755            ActivityRecord starting, boolean persistent, boolean initLocale) {
11756        // do nothing if we are headless
11757        if (mHeadless) return true;
11758
11759        int changes = 0;
11760
11761        boolean kept = true;
11762
11763        if (values != null) {
11764            Configuration newConfig = new Configuration(mConfiguration);
11765            changes = newConfig.updateFrom(values);
11766            if (changes != 0) {
11767                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11768                    Slog.i(TAG, "Updating configuration to: " + values);
11769                }
11770
11771                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11772
11773                if (values.locale != null && !initLocale) {
11774                    saveLocaleLocked(values.locale,
11775                                     !values.locale.equals(mConfiguration.locale),
11776                                     values.userSetLocale);
11777                }
11778
11779                mConfigurationSeq++;
11780                if (mConfigurationSeq <= 0) {
11781                    mConfigurationSeq = 1;
11782                }
11783                newConfig.seq = mConfigurationSeq;
11784                mConfiguration = newConfig;
11785                Slog.i(TAG, "Config changed: " + newConfig);
11786
11787                final Configuration configCopy = new Configuration(mConfiguration);
11788
11789                // TODO: If our config changes, should we auto dismiss any currently
11790                // showing dialogs?
11791                mShowDialogs = shouldShowDialogs(newConfig);
11792
11793                AttributeCache ac = AttributeCache.instance();
11794                if (ac != null) {
11795                    ac.updateConfiguration(configCopy);
11796                }
11797
11798                // Make sure all resources in our process are updated
11799                // right now, so that anyone who is going to retrieve
11800                // resource values after we return will be sure to get
11801                // the new ones.  This is especially important during
11802                // boot, where the first config change needs to guarantee
11803                // all resources have that config before following boot
11804                // code is executed.
11805                mSystemThread.applyConfigurationToResources(configCopy);
11806
11807                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11808                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11809                    msg.obj = new Configuration(configCopy);
11810                    mHandler.sendMessage(msg);
11811                }
11812
11813                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11814                    ProcessRecord app = mLruProcesses.get(i);
11815                    try {
11816                        if (app.thread != null) {
11817                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11818                                    + app.processName + " new config " + mConfiguration);
11819                            app.thread.scheduleConfigurationChanged(configCopy);
11820                        }
11821                    } catch (Exception e) {
11822                    }
11823                }
11824                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11825                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11826                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11827                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11828                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11829                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11830                    broadcastIntentLocked(null, null,
11831                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11832                            null, null, 0, null, null,
11833                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11834                }
11835            }
11836        }
11837
11838        if (changes != 0 && starting == null) {
11839            // If the configuration changed, and the caller is not already
11840            // in the process of starting an activity, then find the top
11841            // activity to check if its configuration needs to change.
11842            starting = mMainStack.topRunningActivityLocked(null);
11843        }
11844
11845        if (starting != null) {
11846            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11847            // And we need to make sure at this point that all other activities
11848            // are made visible with the correct configuration.
11849            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11850        }
11851
11852        if (values != null && mWindowManager != null) {
11853            mWindowManager.setNewConfiguration(mConfiguration);
11854        }
11855
11856        return kept;
11857    }
11858
11859    /**
11860     * Decide based on the configuration whether we should shouw the ANR,
11861     * crash, etc dialogs.  The idea is that if there is no affordnace to
11862     * press the on-screen buttons, we shouldn't show the dialog.
11863     *
11864     * A thought: SystemUI might also want to get told about this, the Power
11865     * dialog / global actions also might want different behaviors.
11866     */
11867    private static final boolean shouldShowDialogs(Configuration config) {
11868        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11869                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11870    }
11871
11872    /**
11873     * Save the locale.  You must be inside a synchronized (this) block.
11874     */
11875    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11876        if(isDiff) {
11877            SystemProperties.set("user.language", l.getLanguage());
11878            SystemProperties.set("user.region", l.getCountry());
11879        }
11880
11881        if(isPersist) {
11882            SystemProperties.set("persist.sys.language", l.getLanguage());
11883            SystemProperties.set("persist.sys.country", l.getCountry());
11884            SystemProperties.set("persist.sys.localevar", l.getVariant());
11885        }
11886    }
11887
11888    @Override
11889    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11890        ActivityRecord srec = ActivityRecord.forToken(token);
11891        return srec != null && srec.task.affinity != null &&
11892                srec.task.affinity.equals(destAffinity);
11893    }
11894
11895    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11896            Intent resultData) {
11897        ComponentName dest = destIntent.getComponent();
11898
11899        synchronized (this) {
11900            ActivityRecord srec = ActivityRecord.forToken(token);
11901            if (srec == null) {
11902                return false;
11903            }
11904            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11905            final int start = history.indexOf(srec);
11906            if (start < 0) {
11907                // Current activity is not in history stack; do nothing.
11908                return false;
11909            }
11910            int finishTo = start - 1;
11911            ActivityRecord parent = null;
11912            boolean foundParentInTask = false;
11913            if (dest != null) {
11914                TaskRecord tr = srec.task;
11915                for (int i = start - 1; i >= 0; i--) {
11916                    ActivityRecord r = history.get(i);
11917                    if (tr != r.task) {
11918                        // Couldn't find parent in the same task; stop at the one above this.
11919                        // (Root of current task; in-app "home" behavior)
11920                        // Always at least finish the current activity.
11921                        finishTo = Math.min(start - 1, i + 1);
11922                        parent = history.get(finishTo);
11923                        break;
11924                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11925                            r.info.name.equals(dest.getClassName())) {
11926                        finishTo = i;
11927                        parent = r;
11928                        foundParentInTask = true;
11929                        break;
11930                    }
11931                }
11932            }
11933
11934            if (mController != null) {
11935                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11936                if (next != null) {
11937                    // ask watcher if this is allowed
11938                    boolean resumeOK = true;
11939                    try {
11940                        resumeOK = mController.activityResuming(next.packageName);
11941                    } catch (RemoteException e) {
11942                        mController = null;
11943                    }
11944
11945                    if (!resumeOK) {
11946                        return false;
11947                    }
11948                }
11949            }
11950            final long origId = Binder.clearCallingIdentity();
11951            for (int i = start; i > finishTo; i--) {
11952                ActivityRecord r = history.get(i);
11953                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11954                        "navigate-up");
11955                // Only return the supplied result for the first activity finished
11956                resultCode = Activity.RESULT_CANCELED;
11957                resultData = null;
11958            }
11959
11960            if (parent != null && foundParentInTask) {
11961                final int parentLaunchMode = parent.info.launchMode;
11962                final int destIntentFlags = destIntent.getFlags();
11963                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11964                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11965                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11966                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11967                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11968                } else {
11969                    try {
11970                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11971                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
11972                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11973                                null, aInfo, parent.appToken, null,
11974                                0, -1, parent.launchedFromUid, 0, null, true, null);
11975                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11976                    } catch (RemoteException e) {
11977                        foundParentInTask = false;
11978                    }
11979                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11980                            resultData, "navigate-up");
11981                }
11982            }
11983            Binder.restoreCallingIdentity(origId);
11984            return foundParentInTask;
11985        }
11986    }
11987
11988    public int getLaunchedFromUid(IBinder activityToken) {
11989        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11990        if (srec == null) {
11991            return -1;
11992        }
11993        return srec.launchedFromUid;
11994    }
11995
11996    // =========================================================
11997    // LIFETIME MANAGEMENT
11998    // =========================================================
11999
12000    // Returns which broadcast queue the app is the current [or imminent] receiver
12001    // on, or 'null' if the app is not an active broadcast recipient.
12002    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12003        BroadcastRecord r = app.curReceiver;
12004        if (r != null) {
12005            return r.queue;
12006        }
12007
12008        // It's not the current receiver, but it might be starting up to become one
12009        synchronized (this) {
12010            for (BroadcastQueue queue : mBroadcastQueues) {
12011                r = queue.mPendingBroadcast;
12012                if (r != null && r.curApp == app) {
12013                    // found it; report which queue it's in
12014                    return queue;
12015                }
12016            }
12017        }
12018
12019        return null;
12020    }
12021
12022    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12023            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12024        if (mAdjSeq == app.adjSeq) {
12025            // This adjustment has already been computed.  If we are calling
12026            // from the top, we may have already computed our adjustment with
12027            // an earlier hidden adjustment that isn't really for us... if
12028            // so, use the new hidden adjustment.
12029            if (!recursed && app.hidden) {
12030                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12031                        app.hasActivities ? hiddenAdj : emptyAdj;
12032            }
12033            return app.curRawAdj;
12034        }
12035
12036        if (app.thread == null) {
12037            app.adjSeq = mAdjSeq;
12038            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12039            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12040        }
12041
12042        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12043        app.adjSource = null;
12044        app.adjTarget = null;
12045        app.empty = false;
12046        app.hidden = false;
12047
12048        final int activitiesSize = app.activities.size();
12049
12050        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12051            // The max adjustment doesn't allow this app to be anything
12052            // below foreground, so it is not worth doing work for it.
12053            app.adjType = "fixed";
12054            app.adjSeq = mAdjSeq;
12055            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12056            app.hasActivities = false;
12057            app.foregroundActivities = false;
12058            app.keeping = true;
12059            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12060            // System process can do UI, and when they do we want to have
12061            // them trim their memory after the user leaves the UI.  To
12062            // facilitate this, here we need to determine whether or not it
12063            // is currently showing UI.
12064            app.systemNoUi = true;
12065            if (app == TOP_APP) {
12066                app.systemNoUi = false;
12067                app.hasActivities = true;
12068            } else if (activitiesSize > 0) {
12069                for (int j = 0; j < activitiesSize; j++) {
12070                    final ActivityRecord r = app.activities.get(j);
12071                    if (r.visible) {
12072                        app.systemNoUi = false;
12073                    }
12074                    if (r.app == app) {
12075                        app.hasActivities = true;
12076                    }
12077                }
12078            }
12079            return (app.curAdj=app.maxAdj);
12080        }
12081
12082        app.keeping = false;
12083        app.systemNoUi = false;
12084        app.hasActivities = false;
12085
12086        // Determine the importance of the process, starting with most
12087        // important to least, and assign an appropriate OOM adjustment.
12088        int adj;
12089        int schedGroup;
12090        boolean foregroundActivities = false;
12091        boolean interesting = false;
12092        BroadcastQueue queue;
12093        if (app == TOP_APP) {
12094            // The last app on the list is the foreground app.
12095            adj = ProcessList.FOREGROUND_APP_ADJ;
12096            schedGroup = Process.THREAD_GROUP_DEFAULT;
12097            app.adjType = "top-activity";
12098            foregroundActivities = true;
12099            interesting = true;
12100            app.hasActivities = true;
12101        } else if (app.instrumentationClass != null) {
12102            // Don't want to kill running instrumentation.
12103            adj = ProcessList.FOREGROUND_APP_ADJ;
12104            schedGroup = Process.THREAD_GROUP_DEFAULT;
12105            app.adjType = "instrumentation";
12106            interesting = true;
12107        } else if ((queue = isReceivingBroadcast(app)) != null) {
12108            // An app that is currently receiving a broadcast also
12109            // counts as being in the foreground for OOM killer purposes.
12110            // It's placed in a sched group based on the nature of the
12111            // broadcast as reflected by which queue it's active in.
12112            adj = ProcessList.FOREGROUND_APP_ADJ;
12113            schedGroup = (queue == mFgBroadcastQueue)
12114                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12115            app.adjType = "broadcast";
12116        } else if (app.executingServices.size() > 0) {
12117            // An app that is currently executing a service callback also
12118            // counts as being in the foreground.
12119            adj = ProcessList.FOREGROUND_APP_ADJ;
12120            schedGroup = Process.THREAD_GROUP_DEFAULT;
12121            app.adjType = "exec-service";
12122        } else {
12123            // Assume process is hidden (has activities); we will correct
12124            // later if this is not the case.
12125            adj = hiddenAdj;
12126            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12127            app.hidden = true;
12128            app.adjType = "bg-activities";
12129        }
12130
12131        boolean hasStoppingActivities = false;
12132
12133        // Examine all activities if not already foreground.
12134        if (!foregroundActivities && activitiesSize > 0) {
12135            for (int j = 0; j < activitiesSize; j++) {
12136                final ActivityRecord r = app.activities.get(j);
12137                if (r.visible) {
12138                    // App has a visible activity; only upgrade adjustment.
12139                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12140                        adj = ProcessList.VISIBLE_APP_ADJ;
12141                        app.adjType = "visible";
12142                    }
12143                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12144                    app.hidden = false;
12145                    app.hasActivities = true;
12146                    foregroundActivities = true;
12147                    break;
12148                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12149                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12150                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12151                        app.adjType = "pausing";
12152                    }
12153                    app.hidden = false;
12154                    foregroundActivities = true;
12155                } else if (r.state == ActivityState.STOPPING) {
12156                    // We will apply the actual adjustment later, because
12157                    // we want to allow this process to immediately go through
12158                    // any memory trimming that is in effect.
12159                    app.hidden = false;
12160                    foregroundActivities = true;
12161                    hasStoppingActivities = true;
12162                }
12163                if (r.app == app) {
12164                    app.hasActivities = true;
12165                }
12166            }
12167        }
12168
12169        if (adj == hiddenAdj && !app.hasActivities) {
12170            // Whoops, this process is completely empty as far as we know
12171            // at this point.
12172            adj = emptyAdj;
12173            app.empty = true;
12174            app.adjType = "bg-empty";
12175        }
12176
12177        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12178            if (app.foregroundServices) {
12179                // The user is aware of this app, so make it visible.
12180                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12181                app.hidden = false;
12182                app.adjType = "foreground-service";
12183                schedGroup = Process.THREAD_GROUP_DEFAULT;
12184            } else if (app.forcingToForeground != null) {
12185                // The user is aware of this app, so make it visible.
12186                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12187                app.hidden = false;
12188                app.adjType = "force-foreground";
12189                app.adjSource = app.forcingToForeground;
12190                schedGroup = Process.THREAD_GROUP_DEFAULT;
12191            }
12192        }
12193
12194        if (app.foregroundServices) {
12195            interesting = true;
12196        }
12197
12198        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12199            // We don't want to kill the current heavy-weight process.
12200            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12201            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12202            app.hidden = false;
12203            app.adjType = "heavy";
12204        }
12205
12206        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12207            // This process is hosting what we currently consider to be the
12208            // home app, so we don't want to let it go into the background.
12209            adj = ProcessList.HOME_APP_ADJ;
12210            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12211            app.hidden = false;
12212            app.adjType = "home";
12213        }
12214
12215        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12216                && app.activities.size() > 0) {
12217            // This was the previous process that showed UI to the user.
12218            // We want to try to keep it around more aggressively, to give
12219            // a good experience around switching between two apps.
12220            adj = ProcessList.PREVIOUS_APP_ADJ;
12221            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12222            app.hidden = false;
12223            app.adjType = "previous";
12224        }
12225
12226        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12227                + " reason=" + app.adjType);
12228
12229        // By default, we use the computed adjustment.  It may be changed if
12230        // there are applications dependent on our services or providers, but
12231        // this gives us a baseline and makes sure we don't get into an
12232        // infinite recursion.
12233        app.adjSeq = mAdjSeq;
12234        app.curRawAdj = app.nonStoppingAdj = adj;
12235
12236        if (mBackupTarget != null && app == mBackupTarget.app) {
12237            // If possible we want to avoid killing apps while they're being backed up
12238            if (adj > ProcessList.BACKUP_APP_ADJ) {
12239                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12240                adj = ProcessList.BACKUP_APP_ADJ;
12241                app.adjType = "backup";
12242                app.hidden = false;
12243            }
12244        }
12245
12246        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12247                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12248            final long now = SystemClock.uptimeMillis();
12249            // This process is more important if the top activity is
12250            // bound to the service.
12251            Iterator<ServiceRecord> jt = app.services.iterator();
12252            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12253                ServiceRecord s = jt.next();
12254                if (s.startRequested) {
12255                    if (app.hasShownUi && app != mHomeProcess) {
12256                        // If this process has shown some UI, let it immediately
12257                        // go to the LRU list because it may be pretty heavy with
12258                        // UI stuff.  We'll tag it with a label just to help
12259                        // debug and understand what is going on.
12260                        if (adj > ProcessList.SERVICE_ADJ) {
12261                            app.adjType = "started-bg-ui-services";
12262                        }
12263                    } else {
12264                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12265                            // This service has seen some activity within
12266                            // recent memory, so we will keep its process ahead
12267                            // of the background processes.
12268                            if (adj > ProcessList.SERVICE_ADJ) {
12269                                adj = ProcessList.SERVICE_ADJ;
12270                                app.adjType = "started-services";
12271                                app.hidden = false;
12272                            }
12273                        }
12274                        // If we have let the service slide into the background
12275                        // state, still have some text describing what it is doing
12276                        // even though the service no longer has an impact.
12277                        if (adj > ProcessList.SERVICE_ADJ) {
12278                            app.adjType = "started-bg-services";
12279                        }
12280                    }
12281                    // Don't kill this process because it is doing work; it
12282                    // has said it is doing work.
12283                    app.keeping = true;
12284                }
12285                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12286                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12287                    Iterator<ArrayList<ConnectionRecord>> kt
12288                            = s.connections.values().iterator();
12289                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12290                        ArrayList<ConnectionRecord> clist = kt.next();
12291                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12292                            // XXX should compute this based on the max of
12293                            // all connected clients.
12294                            ConnectionRecord cr = clist.get(i);
12295                            if (cr.binding.client == app) {
12296                                // Binding to ourself is not interesting.
12297                                continue;
12298                            }
12299                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12300                                ProcessRecord client = cr.binding.client;
12301                                int clientAdj = adj;
12302                                int myHiddenAdj = hiddenAdj;
12303                                if (myHiddenAdj > client.hiddenAdj) {
12304                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12305                                        myHiddenAdj = client.hiddenAdj;
12306                                    } else {
12307                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12308                                    }
12309                                }
12310                                int myEmptyAdj = emptyAdj;
12311                                if (myEmptyAdj > client.emptyAdj) {
12312                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12313                                        myEmptyAdj = client.emptyAdj;
12314                                    } else {
12315                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12316                                    }
12317                                }
12318                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12319                                        myEmptyAdj, TOP_APP, true, doingAll);
12320                                String adjType = null;
12321                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12322                                    // Not doing bind OOM management, so treat
12323                                    // this guy more like a started service.
12324                                    if (app.hasShownUi && app != mHomeProcess) {
12325                                        // If this process has shown some UI, let it immediately
12326                                        // go to the LRU list because it may be pretty heavy with
12327                                        // UI stuff.  We'll tag it with a label just to help
12328                                        // debug and understand what is going on.
12329                                        if (adj > clientAdj) {
12330                                            adjType = "bound-bg-ui-services";
12331                                        }
12332                                        app.hidden = false;
12333                                        clientAdj = adj;
12334                                    } else {
12335                                        if (now >= (s.lastActivity
12336                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12337                                            // This service has not seen activity within
12338                                            // recent memory, so allow it to drop to the
12339                                            // LRU list if there is no other reason to keep
12340                                            // it around.  We'll also tag it with a label just
12341                                            // to help debug and undertand what is going on.
12342                                            if (adj > clientAdj) {
12343                                                adjType = "bound-bg-services";
12344                                            }
12345                                            clientAdj = adj;
12346                                        }
12347                                    }
12348                                }
12349                                if (adj > clientAdj) {
12350                                    // If this process has recently shown UI, and
12351                                    // the process that is binding to it is less
12352                                    // important than being visible, then we don't
12353                                    // care about the binding as much as we care
12354                                    // about letting this process get into the LRU
12355                                    // list to be killed and restarted if needed for
12356                                    // memory.
12357                                    if (app.hasShownUi && app != mHomeProcess
12358                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12359                                        adjType = "bound-bg-ui-services";
12360                                    } else {
12361                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12362                                                |Context.BIND_IMPORTANT)) != 0) {
12363                                            adj = clientAdj;
12364                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12365                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12366                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12367                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12368                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12369                                            adj = clientAdj;
12370                                        } else {
12371                                            app.pendingUiClean = true;
12372                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12373                                                adj = ProcessList.VISIBLE_APP_ADJ;
12374                                            }
12375                                        }
12376                                        if (!client.hidden) {
12377                                            app.hidden = false;
12378                                        }
12379                                        if (client.keeping) {
12380                                            app.keeping = true;
12381                                        }
12382                                        adjType = "service";
12383                                    }
12384                                }
12385                                if (adjType != null) {
12386                                    app.adjType = adjType;
12387                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12388                                            .REASON_SERVICE_IN_USE;
12389                                    app.adjSource = cr.binding.client;
12390                                    app.adjSourceOom = clientAdj;
12391                                    app.adjTarget = s.name;
12392                                }
12393                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12394                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12395                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12396                                    }
12397                                }
12398                            }
12399                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12400                                ActivityRecord a = cr.activity;
12401                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12402                                        (a.visible || a.state == ActivityState.RESUMED
12403                                         || a.state == ActivityState.PAUSING)) {
12404                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12405                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12406                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12407                                    }
12408                                    app.hidden = false;
12409                                    app.adjType = "service";
12410                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12411                                            .REASON_SERVICE_IN_USE;
12412                                    app.adjSource = a;
12413                                    app.adjSourceOom = adj;
12414                                    app.adjTarget = s.name;
12415                                }
12416                            }
12417                        }
12418                    }
12419                }
12420            }
12421
12422            // Finally, if this process has active services running in it, we
12423            // would like to avoid killing it unless it would prevent the current
12424            // application from running.  By default we put the process in
12425            // with the rest of the background processes; as we scan through
12426            // its services we may bump it up from there.
12427            if (adj > hiddenAdj) {
12428                adj = hiddenAdj;
12429                app.hidden = false;
12430                app.adjType = "bg-services";
12431            }
12432        }
12433
12434        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12435                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12436            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12437            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12438                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12439                ContentProviderRecord cpr = jt.next();
12440                for (int i = cpr.connections.size()-1;
12441                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12442                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12443                        i--) {
12444                    ContentProviderConnection conn = cpr.connections.get(i);
12445                    ProcessRecord client = conn.client;
12446                    if (client == app) {
12447                        // Being our own client is not interesting.
12448                        continue;
12449                    }
12450                    int myHiddenAdj = hiddenAdj;
12451                    if (myHiddenAdj > client.hiddenAdj) {
12452                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12453                            myHiddenAdj = client.hiddenAdj;
12454                        } else {
12455                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12456                        }
12457                    }
12458                    int myEmptyAdj = emptyAdj;
12459                    if (myEmptyAdj > client.emptyAdj) {
12460                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12461                            myEmptyAdj = client.emptyAdj;
12462                        } else {
12463                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12464                        }
12465                    }
12466                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12467                            myEmptyAdj, TOP_APP, true, doingAll);
12468                    if (adj > clientAdj) {
12469                        if (app.hasShownUi && app != mHomeProcess
12470                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12471                            app.adjType = "bg-ui-provider";
12472                        } else {
12473                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12474                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12475                            app.adjType = "provider";
12476                        }
12477                        if (!client.hidden) {
12478                            app.hidden = false;
12479                        }
12480                        if (client.keeping) {
12481                            app.keeping = true;
12482                        }
12483                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12484                                .REASON_PROVIDER_IN_USE;
12485                        app.adjSource = client;
12486                        app.adjSourceOom = clientAdj;
12487                        app.adjTarget = cpr.name;
12488                    }
12489                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12490                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12491                    }
12492                }
12493                // If the provider has external (non-framework) process
12494                // dependencies, ensure that its adjustment is at least
12495                // FOREGROUND_APP_ADJ.
12496                if (cpr.hasExternalProcessHandles()) {
12497                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12498                        adj = ProcessList.FOREGROUND_APP_ADJ;
12499                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12500                        app.hidden = false;
12501                        app.keeping = true;
12502                        app.adjType = "provider";
12503                        app.adjTarget = cpr.name;
12504                    }
12505                }
12506            }
12507        }
12508
12509        if (adj == ProcessList.SERVICE_ADJ) {
12510            if (doingAll) {
12511                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12512                mNewNumServiceProcs++;
12513            }
12514            if (app.serviceb) {
12515                adj = ProcessList.SERVICE_B_ADJ;
12516            }
12517        } else {
12518            app.serviceb = false;
12519        }
12520
12521        app.nonStoppingAdj = adj;
12522
12523        if (hasStoppingActivities) {
12524            // Only upgrade adjustment.
12525            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12526                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12527                app.adjType = "stopping";
12528            }
12529        }
12530
12531        app.curRawAdj = adj;
12532
12533        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12534        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12535        if (adj > app.maxAdj) {
12536            adj = app.maxAdj;
12537            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12538                schedGroup = Process.THREAD_GROUP_DEFAULT;
12539            }
12540        }
12541        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12542            app.keeping = true;
12543        }
12544
12545        if (app.hasAboveClient) {
12546            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12547            // then we need to drop its adjustment to be lower than the service's
12548            // in order to honor the request.  We want to drop it by one adjustment
12549            // level...  but there is special meaning applied to various levels so
12550            // we will skip some of them.
12551            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12552                // System process will not get dropped, ever
12553            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12554                adj = ProcessList.VISIBLE_APP_ADJ;
12555            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12556                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12557            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12558                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12559            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12560                adj++;
12561            }
12562        }
12563
12564        int importance = app.memImportance;
12565        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12566            app.curAdj = adj;
12567            app.curSchedGroup = schedGroup;
12568            if (!interesting) {
12569                // For this reporting, if there is not something explicitly
12570                // interesting in this process then we will push it to the
12571                // background importance.
12572                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12573            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12574                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12575            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12576                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12577            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12578                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12579            } else if (adj >= ProcessList.SERVICE_ADJ) {
12580                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12581            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12582                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12583            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12584                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12585            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12586                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12587            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12588                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12589            } else {
12590                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12591            }
12592        }
12593
12594        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12595        if (foregroundActivities != app.foregroundActivities) {
12596            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12597        }
12598        if (changes != 0) {
12599            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12600            app.memImportance = importance;
12601            app.foregroundActivities = foregroundActivities;
12602            int i = mPendingProcessChanges.size()-1;
12603            ProcessChangeItem item = null;
12604            while (i >= 0) {
12605                item = mPendingProcessChanges.get(i);
12606                if (item.pid == app.pid) {
12607                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12608                    break;
12609                }
12610                i--;
12611            }
12612            if (i < 0) {
12613                // No existing item in pending changes; need a new one.
12614                final int NA = mAvailProcessChanges.size();
12615                if (NA > 0) {
12616                    item = mAvailProcessChanges.remove(NA-1);
12617                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12618                } else {
12619                    item = new ProcessChangeItem();
12620                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12621                }
12622                item.changes = 0;
12623                item.pid = app.pid;
12624                item.uid = app.info.uid;
12625                if (mPendingProcessChanges.size() == 0) {
12626                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12627                            "*** Enqueueing dispatch processes changed!");
12628                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12629                }
12630                mPendingProcessChanges.add(item);
12631            }
12632            item.changes |= changes;
12633            item.importance = importance;
12634            item.foregroundActivities = foregroundActivities;
12635            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12636                    + Integer.toHexString(System.identityHashCode(item))
12637                    + " " + app.toShortString() + ": changes=" + item.changes
12638                    + " importance=" + item.importance
12639                    + " foreground=" + item.foregroundActivities
12640                    + " type=" + app.adjType + " source=" + app.adjSource
12641                    + " target=" + app.adjTarget);
12642        }
12643
12644        return app.curRawAdj;
12645    }
12646
12647    /**
12648     * Ask a given process to GC right now.
12649     */
12650    final void performAppGcLocked(ProcessRecord app) {
12651        try {
12652            app.lastRequestedGc = SystemClock.uptimeMillis();
12653            if (app.thread != null) {
12654                if (app.reportLowMemory) {
12655                    app.reportLowMemory = false;
12656                    app.thread.scheduleLowMemory();
12657                } else {
12658                    app.thread.processInBackground();
12659                }
12660            }
12661        } catch (Exception e) {
12662            // whatever.
12663        }
12664    }
12665
12666    /**
12667     * Returns true if things are idle enough to perform GCs.
12668     */
12669    private final boolean canGcNowLocked() {
12670        boolean processingBroadcasts = false;
12671        for (BroadcastQueue q : mBroadcastQueues) {
12672            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12673                processingBroadcasts = true;
12674            }
12675        }
12676        return !processingBroadcasts
12677                && (mSleeping || (mMainStack.mResumedActivity != null &&
12678                        mMainStack.mResumedActivity.idle));
12679    }
12680
12681    /**
12682     * Perform GCs on all processes that are waiting for it, but only
12683     * if things are idle.
12684     */
12685    final void performAppGcsLocked() {
12686        final int N = mProcessesToGc.size();
12687        if (N <= 0) {
12688            return;
12689        }
12690        if (canGcNowLocked()) {
12691            while (mProcessesToGc.size() > 0) {
12692                ProcessRecord proc = mProcessesToGc.remove(0);
12693                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12694                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12695                            <= SystemClock.uptimeMillis()) {
12696                        // To avoid spamming the system, we will GC processes one
12697                        // at a time, waiting a few seconds between each.
12698                        performAppGcLocked(proc);
12699                        scheduleAppGcsLocked();
12700                        return;
12701                    } else {
12702                        // It hasn't been long enough since we last GCed this
12703                        // process...  put it in the list to wait for its time.
12704                        addProcessToGcListLocked(proc);
12705                        break;
12706                    }
12707                }
12708            }
12709
12710            scheduleAppGcsLocked();
12711        }
12712    }
12713
12714    /**
12715     * If all looks good, perform GCs on all processes waiting for them.
12716     */
12717    final void performAppGcsIfAppropriateLocked() {
12718        if (canGcNowLocked()) {
12719            performAppGcsLocked();
12720            return;
12721        }
12722        // Still not idle, wait some more.
12723        scheduleAppGcsLocked();
12724    }
12725
12726    /**
12727     * Schedule the execution of all pending app GCs.
12728     */
12729    final void scheduleAppGcsLocked() {
12730        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12731
12732        if (mProcessesToGc.size() > 0) {
12733            // Schedule a GC for the time to the next process.
12734            ProcessRecord proc = mProcessesToGc.get(0);
12735            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12736
12737            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12738            long now = SystemClock.uptimeMillis();
12739            if (when < (now+GC_TIMEOUT)) {
12740                when = now + GC_TIMEOUT;
12741            }
12742            mHandler.sendMessageAtTime(msg, when);
12743        }
12744    }
12745
12746    /**
12747     * Add a process to the array of processes waiting to be GCed.  Keeps the
12748     * list in sorted order by the last GC time.  The process can't already be
12749     * on the list.
12750     */
12751    final void addProcessToGcListLocked(ProcessRecord proc) {
12752        boolean added = false;
12753        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12754            if (mProcessesToGc.get(i).lastRequestedGc <
12755                    proc.lastRequestedGc) {
12756                added = true;
12757                mProcessesToGc.add(i+1, proc);
12758                break;
12759            }
12760        }
12761        if (!added) {
12762            mProcessesToGc.add(0, proc);
12763        }
12764    }
12765
12766    /**
12767     * Set up to ask a process to GC itself.  This will either do it
12768     * immediately, or put it on the list of processes to gc the next
12769     * time things are idle.
12770     */
12771    final void scheduleAppGcLocked(ProcessRecord app) {
12772        long now = SystemClock.uptimeMillis();
12773        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12774            return;
12775        }
12776        if (!mProcessesToGc.contains(app)) {
12777            addProcessToGcListLocked(app);
12778            scheduleAppGcsLocked();
12779        }
12780    }
12781
12782    final void checkExcessivePowerUsageLocked(boolean doKills) {
12783        updateCpuStatsNow();
12784
12785        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12786        boolean doWakeKills = doKills;
12787        boolean doCpuKills = doKills;
12788        if (mLastPowerCheckRealtime == 0) {
12789            doWakeKills = false;
12790        }
12791        if (mLastPowerCheckUptime == 0) {
12792            doCpuKills = false;
12793        }
12794        if (stats.isScreenOn()) {
12795            doWakeKills = false;
12796        }
12797        final long curRealtime = SystemClock.elapsedRealtime();
12798        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12799        final long curUptime = SystemClock.uptimeMillis();
12800        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12801        mLastPowerCheckRealtime = curRealtime;
12802        mLastPowerCheckUptime = curUptime;
12803        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12804            doWakeKills = false;
12805        }
12806        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12807            doCpuKills = false;
12808        }
12809        int i = mLruProcesses.size();
12810        while (i > 0) {
12811            i--;
12812            ProcessRecord app = mLruProcesses.get(i);
12813            if (!app.keeping) {
12814                long wtime;
12815                synchronized (stats) {
12816                    wtime = stats.getProcessWakeTime(app.info.uid,
12817                            app.pid, curRealtime);
12818                }
12819                long wtimeUsed = wtime - app.lastWakeTime;
12820                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12821                if (DEBUG_POWER) {
12822                    StringBuilder sb = new StringBuilder(128);
12823                    sb.append("Wake for ");
12824                    app.toShortString(sb);
12825                    sb.append(": over ");
12826                    TimeUtils.formatDuration(realtimeSince, sb);
12827                    sb.append(" used ");
12828                    TimeUtils.formatDuration(wtimeUsed, sb);
12829                    sb.append(" (");
12830                    sb.append((wtimeUsed*100)/realtimeSince);
12831                    sb.append("%)");
12832                    Slog.i(TAG, sb.toString());
12833                    sb.setLength(0);
12834                    sb.append("CPU for ");
12835                    app.toShortString(sb);
12836                    sb.append(": over ");
12837                    TimeUtils.formatDuration(uptimeSince, sb);
12838                    sb.append(" used ");
12839                    TimeUtils.formatDuration(cputimeUsed, sb);
12840                    sb.append(" (");
12841                    sb.append((cputimeUsed*100)/uptimeSince);
12842                    sb.append("%)");
12843                    Slog.i(TAG, sb.toString());
12844                }
12845                // If a process has held a wake lock for more
12846                // than 50% of the time during this period,
12847                // that sounds bad.  Kill!
12848                if (doWakeKills && realtimeSince > 0
12849                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12850                    synchronized (stats) {
12851                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12852                                realtimeSince, wtimeUsed);
12853                    }
12854                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12855                            + " (pid " + app.pid + "): held " + wtimeUsed
12856                            + " during " + realtimeSince);
12857                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12858                            app.processName, app.setAdj, "excessive wake lock");
12859                    Process.killProcessQuiet(app.pid);
12860                } else if (doCpuKills && uptimeSince > 0
12861                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12862                    synchronized (stats) {
12863                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12864                                uptimeSince, cputimeUsed);
12865                    }
12866                    Slog.w(TAG, "Excessive CPU in " + app.processName
12867                            + " (pid " + app.pid + "): used " + cputimeUsed
12868                            + " during " + uptimeSince);
12869                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12870                            app.processName, app.setAdj, "excessive cpu");
12871                    Process.killProcessQuiet(app.pid);
12872                } else {
12873                    app.lastWakeTime = wtime;
12874                    app.lastCpuTime = app.curCpuTime;
12875                }
12876            }
12877        }
12878    }
12879
12880    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12881            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12882        app.hiddenAdj = hiddenAdj;
12883        app.emptyAdj = emptyAdj;
12884
12885        if (app.thread == null) {
12886            return false;
12887        }
12888
12889        final boolean wasKeeping = app.keeping;
12890
12891        boolean success = true;
12892
12893        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12894
12895        if (app.curRawAdj != app.setRawAdj) {
12896            if (wasKeeping && !app.keeping) {
12897                // This app is no longer something we want to keep.  Note
12898                // its current wake lock time to later know to kill it if
12899                // it is not behaving well.
12900                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12901                synchronized (stats) {
12902                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12903                            app.pid, SystemClock.elapsedRealtime());
12904                }
12905                app.lastCpuTime = app.curCpuTime;
12906            }
12907
12908            app.setRawAdj = app.curRawAdj;
12909        }
12910
12911        if (app.curAdj != app.setAdj) {
12912            if (Process.setOomAdj(app.pid, app.curAdj)) {
12913                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12914                    TAG, "Set " + app.pid + " " + app.processName +
12915                    " adj " + app.curAdj + ": " + app.adjType);
12916                app.setAdj = app.curAdj;
12917            } else {
12918                success = false;
12919                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12920            }
12921        }
12922        if (app.setSchedGroup != app.curSchedGroup) {
12923            app.setSchedGroup = app.curSchedGroup;
12924            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12925                    "Setting process group of " + app.processName
12926                    + " to " + app.curSchedGroup);
12927            if (app.waitingToKill != null &&
12928                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12929                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12930                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12931                        app.processName, app.setAdj, app.waitingToKill);
12932                app.killedBackground = true;
12933                Process.killProcessQuiet(app.pid);
12934                success = false;
12935            } else {
12936                if (true) {
12937                    long oldId = Binder.clearCallingIdentity();
12938                    try {
12939                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12940                    } catch (Exception e) {
12941                        Slog.w(TAG, "Failed setting process group of " + app.pid
12942                                + " to " + app.curSchedGroup);
12943                        e.printStackTrace();
12944                    } finally {
12945                        Binder.restoreCallingIdentity(oldId);
12946                    }
12947                } else {
12948                    if (app.thread != null) {
12949                        try {
12950                            app.thread.setSchedulingGroup(app.curSchedGroup);
12951                        } catch (RemoteException e) {
12952                        }
12953                    }
12954                }
12955            }
12956        }
12957        return success;
12958    }
12959
12960    private final ActivityRecord resumedAppLocked() {
12961        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12962        if (resumedActivity == null || resumedActivity.app == null) {
12963            resumedActivity = mMainStack.mPausingActivity;
12964            if (resumedActivity == null || resumedActivity.app == null) {
12965                resumedActivity = mMainStack.topRunningActivityLocked(null);
12966            }
12967        }
12968        return resumedActivity;
12969    }
12970
12971    final boolean updateOomAdjLocked(ProcessRecord app) {
12972        final ActivityRecord TOP_ACT = resumedAppLocked();
12973        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12974        int curAdj = app.curAdj;
12975        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12976            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12977
12978        mAdjSeq++;
12979
12980        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
12981                TOP_APP, false);
12982        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12983            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12984        if (nowHidden != wasHidden) {
12985            // Changed to/from hidden state, so apps after it in the LRU
12986            // list may also be changed.
12987            updateOomAdjLocked();
12988        }
12989        return success;
12990    }
12991
12992    final void updateOomAdjLocked() {
12993        final ActivityRecord TOP_ACT = resumedAppLocked();
12994        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12995
12996        if (false) {
12997            RuntimeException e = new RuntimeException();
12998            e.fillInStackTrace();
12999            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13000        }
13001
13002        mAdjSeq++;
13003        mNewNumServiceProcs = 0;
13004
13005        // Let's determine how many processes we have running vs.
13006        // how many slots we have for background processes; we may want
13007        // to put multiple processes in a slot of there are enough of
13008        // them.
13009        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13010                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13011        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13012        if (emptyFactor < 1) emptyFactor = 1;
13013        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13014        if (hiddenFactor < 1) hiddenFactor = 1;
13015        int stepHidden = 0;
13016        int stepEmpty = 0;
13017        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13018        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13019        int numHidden = 0;
13020        int numEmpty = 0;
13021        int numTrimming = 0;
13022
13023        mNumNonHiddenProcs = 0;
13024        mNumHiddenProcs = 0;
13025
13026        // First update the OOM adjustment for each of the
13027        // application processes based on their current state.
13028        int i = mLruProcesses.size();
13029        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13030        int nextHiddenAdj = curHiddenAdj+1;
13031        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13032        int nextEmptyAdj = curEmptyAdj+2;
13033        while (i > 0) {
13034            i--;
13035            ProcessRecord app = mLruProcesses.get(i);
13036            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13037            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13038            if (!app.killedBackground) {
13039                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13040                    // This process was assigned as a hidden process...  step the
13041                    // hidden level.
13042                    mNumHiddenProcs++;
13043                    if (curHiddenAdj != nextHiddenAdj) {
13044                        stepHidden++;
13045                        if (stepHidden >= hiddenFactor) {
13046                            stepHidden = 0;
13047                            curHiddenAdj = nextHiddenAdj;
13048                            nextHiddenAdj += 2;
13049                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13050                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13051                            }
13052                        }
13053                    }
13054                    numHidden++;
13055                    if (numHidden > hiddenProcessLimit) {
13056                        Slog.i(TAG, "No longer want " + app.processName
13057                                + " (pid " + app.pid + "): hidden #" + numHidden);
13058                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13059                                app.processName, app.setAdj, "too many background");
13060                        app.killedBackground = true;
13061                        Process.killProcessQuiet(app.pid);
13062                    }
13063                } else {
13064                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13065                        // This process was assigned as an empty process...  step the
13066                        // empty level.
13067                        if (curEmptyAdj != nextEmptyAdj) {
13068                            stepEmpty++;
13069                            if (stepEmpty >= emptyFactor) {
13070                                stepEmpty = 0;
13071                                curEmptyAdj = nextEmptyAdj;
13072                                nextEmptyAdj += 2;
13073                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13074                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13075                                }
13076                            }
13077                        }
13078                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13079                        mNumNonHiddenProcs++;
13080                    }
13081                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13082                        numEmpty++;
13083                        if (numEmpty > emptyProcessLimit) {
13084                            Slog.i(TAG, "No longer want " + app.processName
13085                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13086                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13087                                    app.processName, app.setAdj, "too many background");
13088                            app.killedBackground = true;
13089                            Process.killProcessQuiet(app.pid);
13090                        }
13091                    }
13092                }
13093                if (app.isolated && app.services.size() <= 0) {
13094                    // If this is an isolated process, and there are no
13095                    // services running in it, then the process is no longer
13096                    // needed.  We agressively kill these because we can by
13097                    // definition not re-use the same process again, and it is
13098                    // good to avoid having whatever code was running in them
13099                    // left sitting around after no longer needed.
13100                    Slog.i(TAG, "Isolated process " + app.processName
13101                            + " (pid " + app.pid + ") no longer needed");
13102                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13103                            app.processName, app.setAdj, "isolated not needed");
13104                    app.killedBackground = true;
13105                    Process.killProcessQuiet(app.pid);
13106                }
13107                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13108                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13109                        && !app.killedBackground) {
13110                    numTrimming++;
13111                }
13112            }
13113        }
13114
13115        mNumServiceProcs = mNewNumServiceProcs;
13116
13117        // Now determine the memory trimming level of background processes.
13118        // Unfortunately we need to start at the back of the list to do this
13119        // properly.  We only do this if the number of background apps we
13120        // are managing to keep around is less than half the maximum we desire;
13121        // if we are keeping a good number around, we'll let them use whatever
13122        // memory they want.
13123        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13124                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13125            final int numHiddenAndEmpty = numHidden + numEmpty;
13126            final int N = mLruProcesses.size();
13127            int factor = numTrimming/3;
13128            int minFactor = 2;
13129            if (mHomeProcess != null) minFactor++;
13130            if (mPreviousProcess != null) minFactor++;
13131            if (factor < minFactor) factor = minFactor;
13132            int step = 0;
13133            int fgTrimLevel;
13134            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13135                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13136            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13137                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13138            } else {
13139                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13140            }
13141            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13142            for (i=0; i<N; i++) {
13143                ProcessRecord app = mLruProcesses.get(i);
13144                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13145                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13146                        && !app.killedBackground) {
13147                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13148                        try {
13149                            app.thread.scheduleTrimMemory(curLevel);
13150                        } catch (RemoteException e) {
13151                        }
13152                        if (false) {
13153                            // For now we won't do this; our memory trimming seems
13154                            // to be good enough at this point that destroying
13155                            // activities causes more harm than good.
13156                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13157                                    && app != mHomeProcess && app != mPreviousProcess) {
13158                                // Need to do this on its own message because the stack may not
13159                                // be in a consistent state at this point.
13160                                // For these apps we will also finish their activities
13161                                // to help them free memory.
13162                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13163                            }
13164                        }
13165                    }
13166                    app.trimMemoryLevel = curLevel;
13167                    step++;
13168                    if (step >= factor) {
13169                        step = 0;
13170                        switch (curLevel) {
13171                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13172                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13173                                break;
13174                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13175                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13176                                break;
13177                        }
13178                    }
13179                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13180                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13181                            && app.thread != null) {
13182                        try {
13183                            app.thread.scheduleTrimMemory(
13184                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13185                        } catch (RemoteException e) {
13186                        }
13187                    }
13188                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13189                } else {
13190                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13191                            && app.pendingUiClean) {
13192                        // If this application is now in the background and it
13193                        // had done UI, then give it the special trim level to
13194                        // have it free UI resources.
13195                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13196                        if (app.trimMemoryLevel < level && app.thread != null) {
13197                            try {
13198                                app.thread.scheduleTrimMemory(level);
13199                            } catch (RemoteException e) {
13200                            }
13201                        }
13202                        app.pendingUiClean = false;
13203                    }
13204                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13205                        try {
13206                            app.thread.scheduleTrimMemory(fgTrimLevel);
13207                        } catch (RemoteException e) {
13208                        }
13209                    }
13210                    app.trimMemoryLevel = fgTrimLevel;
13211                }
13212            }
13213        } else {
13214            final int N = mLruProcesses.size();
13215            for (i=0; i<N; i++) {
13216                ProcessRecord app = mLruProcesses.get(i);
13217                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13218                        && app.pendingUiClean) {
13219                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13220                            && app.thread != null) {
13221                        try {
13222                            app.thread.scheduleTrimMemory(
13223                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13224                        } catch (RemoteException e) {
13225                        }
13226                    }
13227                    app.pendingUiClean = false;
13228                }
13229                app.trimMemoryLevel = 0;
13230            }
13231        }
13232
13233        if (mAlwaysFinishActivities) {
13234            // Need to do this on its own message because the stack may not
13235            // be in a consistent state at this point.
13236            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13237        }
13238    }
13239
13240    final void trimApplications() {
13241        synchronized (this) {
13242            int i;
13243
13244            // First remove any unused application processes whose package
13245            // has been removed.
13246            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13247                final ProcessRecord app = mRemovedProcesses.get(i);
13248                if (app.activities.size() == 0
13249                        && app.curReceiver == null && app.services.size() == 0) {
13250                    Slog.i(
13251                        TAG, "Exiting empty application process "
13252                        + app.processName + " ("
13253                        + (app.thread != null ? app.thread.asBinder() : null)
13254                        + ")\n");
13255                    if (app.pid > 0 && app.pid != MY_PID) {
13256                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13257                                app.processName, app.setAdj, "empty");
13258                        Process.killProcessQuiet(app.pid);
13259                    } else {
13260                        try {
13261                            app.thread.scheduleExit();
13262                        } catch (Exception e) {
13263                            // Ignore exceptions.
13264                        }
13265                    }
13266                    cleanUpApplicationRecordLocked(app, false, true, -1);
13267                    mRemovedProcesses.remove(i);
13268
13269                    if (app.persistent) {
13270                        if (app.persistent) {
13271                            addAppLocked(app.info, false);
13272                        }
13273                    }
13274                }
13275            }
13276
13277            // Now update the oom adj for all processes.
13278            updateOomAdjLocked();
13279        }
13280    }
13281
13282    /** This method sends the specified signal to each of the persistent apps */
13283    public void signalPersistentProcesses(int sig) throws RemoteException {
13284        if (sig != Process.SIGNAL_USR1) {
13285            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13286        }
13287
13288        synchronized (this) {
13289            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13290                    != PackageManager.PERMISSION_GRANTED) {
13291                throw new SecurityException("Requires permission "
13292                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13293            }
13294
13295            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13296                ProcessRecord r = mLruProcesses.get(i);
13297                if (r.thread != null && r.persistent) {
13298                    Process.sendSignal(r.pid, sig);
13299                }
13300            }
13301        }
13302    }
13303
13304    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13305        if (proc == null || proc == mProfileProc) {
13306            proc = mProfileProc;
13307            path = mProfileFile;
13308            profileType = mProfileType;
13309            clearProfilerLocked();
13310        }
13311        if (proc == null) {
13312            return;
13313        }
13314        try {
13315            proc.thread.profilerControl(false, path, null, profileType);
13316        } catch (RemoteException e) {
13317            throw new IllegalStateException("Process disappeared");
13318        }
13319    }
13320
13321    private void clearProfilerLocked() {
13322        if (mProfileFd != null) {
13323            try {
13324                mProfileFd.close();
13325            } catch (IOException e) {
13326            }
13327        }
13328        mProfileApp = null;
13329        mProfileProc = null;
13330        mProfileFile = null;
13331        mProfileType = 0;
13332        mAutoStopProfiler = false;
13333    }
13334
13335    public boolean profileControl(String process, boolean start,
13336            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13337
13338        try {
13339            synchronized (this) {
13340                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13341                // its own permission.
13342                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13343                        != PackageManager.PERMISSION_GRANTED) {
13344                    throw new SecurityException("Requires permission "
13345                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13346                }
13347
13348                if (start && fd == null) {
13349                    throw new IllegalArgumentException("null fd");
13350                }
13351
13352                ProcessRecord proc = null;
13353                if (process != null) {
13354                    try {
13355                        int pid = Integer.parseInt(process);
13356                        synchronized (mPidsSelfLocked) {
13357                            proc = mPidsSelfLocked.get(pid);
13358                        }
13359                    } catch (NumberFormatException e) {
13360                    }
13361
13362                    if (proc == null) {
13363                        HashMap<String, SparseArray<ProcessRecord>> all
13364                                = mProcessNames.getMap();
13365                        SparseArray<ProcessRecord> procs = all.get(process);
13366                        if (procs != null && procs.size() > 0) {
13367                            proc = procs.valueAt(0);
13368                        }
13369                    }
13370                }
13371
13372                if (start && (proc == null || proc.thread == null)) {
13373                    throw new IllegalArgumentException("Unknown process: " + process);
13374                }
13375
13376                if (start) {
13377                    stopProfilerLocked(null, null, 0);
13378                    setProfileApp(proc.info, proc.processName, path, fd, false);
13379                    mProfileProc = proc;
13380                    mProfileType = profileType;
13381                    try {
13382                        fd = fd.dup();
13383                    } catch (IOException e) {
13384                        fd = null;
13385                    }
13386                    proc.thread.profilerControl(start, path, fd, profileType);
13387                    fd = null;
13388                    mProfileFd = null;
13389                } else {
13390                    stopProfilerLocked(proc, path, profileType);
13391                    if (fd != null) {
13392                        try {
13393                            fd.close();
13394                        } catch (IOException e) {
13395                        }
13396                    }
13397                }
13398
13399                return true;
13400            }
13401        } catch (RemoteException e) {
13402            throw new IllegalStateException("Process disappeared");
13403        } finally {
13404            if (fd != null) {
13405                try {
13406                    fd.close();
13407                } catch (IOException e) {
13408                }
13409            }
13410        }
13411    }
13412
13413    public boolean dumpHeap(String process, boolean managed,
13414            String path, ParcelFileDescriptor fd) throws RemoteException {
13415
13416        try {
13417            synchronized (this) {
13418                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13419                // its own permission (same as profileControl).
13420                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13421                        != PackageManager.PERMISSION_GRANTED) {
13422                    throw new SecurityException("Requires permission "
13423                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13424                }
13425
13426                if (fd == null) {
13427                    throw new IllegalArgumentException("null fd");
13428                }
13429
13430                ProcessRecord proc = null;
13431                try {
13432                    int pid = Integer.parseInt(process);
13433                    synchronized (mPidsSelfLocked) {
13434                        proc = mPidsSelfLocked.get(pid);
13435                    }
13436                } catch (NumberFormatException e) {
13437                }
13438
13439                if (proc == null) {
13440                    HashMap<String, SparseArray<ProcessRecord>> all
13441                            = mProcessNames.getMap();
13442                    SparseArray<ProcessRecord> procs = all.get(process);
13443                    if (procs != null && procs.size() > 0) {
13444                        proc = procs.valueAt(0);
13445                    }
13446                }
13447
13448                if (proc == null || proc.thread == null) {
13449                    throw new IllegalArgumentException("Unknown process: " + process);
13450                }
13451
13452                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13453                if (!isDebuggable) {
13454                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13455                        throw new SecurityException("Process not debuggable: " + proc);
13456                    }
13457                }
13458
13459                proc.thread.dumpHeap(managed, path, fd);
13460                fd = null;
13461                return true;
13462            }
13463        } catch (RemoteException e) {
13464            throw new IllegalStateException("Process disappeared");
13465        } finally {
13466            if (fd != null) {
13467                try {
13468                    fd.close();
13469                } catch (IOException e) {
13470                }
13471            }
13472        }
13473    }
13474
13475    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13476    public void monitor() {
13477        synchronized (this) { }
13478    }
13479
13480    void onCoreSettingsChange(Bundle settings) {
13481        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13482            ProcessRecord processRecord = mLruProcesses.get(i);
13483            try {
13484                if (processRecord.thread != null) {
13485                    processRecord.thread.setCoreSettings(settings);
13486                }
13487            } catch (RemoteException re) {
13488                /* ignore */
13489            }
13490        }
13491    }
13492
13493    // Multi-user methods
13494
13495    public boolean switchUser(int userId) {
13496        final int callingUid = Binder.getCallingUid();
13497        if (callingUid != 0 && callingUid != Process.myUid()) {
13498            Slog.e(TAG, "Trying to switch user from unauthorized app");
13499            return false;
13500        }
13501        if (mCurrentUserId == userId)
13502            return true;
13503
13504        synchronized (this) {
13505            // Check if user is already logged in, otherwise check if user exists first before
13506            // adding to the list of logged in users.
13507            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13508                if (!userExists(userId)) {
13509                    return false;
13510                }
13511                mLoggedInUsers.append(userId, userId);
13512            }
13513
13514            mCurrentUserId = userId;
13515            boolean haveActivities = mMainStack.switchUser(userId);
13516            if (!haveActivities) {
13517                startHomeActivityLocked(userId);
13518            }
13519
13520        }
13521
13522        // Inform of user switch
13523        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13524        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13525        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
13526
13527        return true;
13528    }
13529
13530    @Override
13531    public UserInfo getCurrentUser() throws RemoteException {
13532        final int callingUid = Binder.getCallingUid();
13533        if (callingUid != 0 && callingUid != Process.myUid()) {
13534            Slog.e(TAG, "Trying to get user from unauthorized app");
13535            return null;
13536        }
13537        return getUserManager().getUserInfo(mCurrentUserId);
13538    }
13539
13540    private void onUserRemoved(Intent intent) {
13541        int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
13542        if (extraUserId < 1) return;
13543
13544        // Kill all the processes for the user
13545        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13546        synchronized (this) {
13547            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13548            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13549                SparseArray<ProcessRecord> uids = uidMap.getValue();
13550                for (int i = 0; i < uids.size(); i++) {
13551                    if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
13552                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13553                    }
13554                }
13555            }
13556
13557            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13558                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13559                        false, false, true, true, extraUserId);
13560            }
13561        }
13562    }
13563
13564    private boolean userExists(int userId) {
13565        UserInfo user = getUserManager().getUserInfo(userId);
13566        return user != null;
13567    }
13568
13569    UserManager getUserManager() {
13570        if (mUserManager == null) {
13571            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13572        }
13573        return mUserManager;
13574    }
13575
13576    private void checkValidCaller(int uid, int userId) {
13577        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13578
13579        throw new SecurityException("Caller uid=" + uid
13580                + " is not privileged to communicate with user=" + userId);
13581    }
13582
13583    private int applyUserId(int uid, int userId) {
13584        return UserHandle.getUid(userId, uid);
13585    }
13586
13587    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13588        if (info == null) return null;
13589        ApplicationInfo newInfo = new ApplicationInfo(info);
13590        newInfo.uid = applyUserId(info.uid, userId);
13591        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13592                + info.packageName;
13593        return newInfo;
13594    }
13595
13596    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13597        if (aInfo == null
13598                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13599            return aInfo;
13600        }
13601
13602        ActivityInfo info = new ActivityInfo(aInfo);
13603        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13604        return info;
13605    }
13606}
13607