ActivityManagerService.java revision 5f7979993979466c79ab4f38d83c6f2aca361662
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.ServiceManager;
109import android.os.StrictMode;
110import android.os.SystemClock;
111import android.os.SystemProperties;
112import android.os.UserHandle;
113import android.os.UserManager;
114import android.provider.Settings;
115import android.text.format.Time;
116import android.util.EventLog;
117import android.util.LocaleUtil;
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.setLocale(Locale.getDefault());
1514
1515        mConfigurationSeq = mConfiguration.seq = 1;
1516        mProcessStats.init();
1517
1518        mCompatModePackages = new CompatModePackages(this, systemDir);
1519
1520        // Add ourself to the Watchdog monitors.
1521        Watchdog.getInstance().addMonitor(this);
1522
1523        mProcessStatsThread = new Thread("ProcessStats") {
1524            public void run() {
1525                while (true) {
1526                    try {
1527                        try {
1528                            synchronized(this) {
1529                                final long now = SystemClock.uptimeMillis();
1530                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1531                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1532                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1533                                //        + ", write delay=" + nextWriteDelay);
1534                                if (nextWriteDelay < nextCpuDelay) {
1535                                    nextCpuDelay = nextWriteDelay;
1536                                }
1537                                if (nextCpuDelay > 0) {
1538                                    mProcessStatsMutexFree.set(true);
1539                                    this.wait(nextCpuDelay);
1540                                }
1541                            }
1542                        } catch (InterruptedException e) {
1543                        }
1544                        updateCpuStatsNow();
1545                    } catch (Exception e) {
1546                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1547                    }
1548                }
1549            }
1550        };
1551        mProcessStatsThread.start();
1552    }
1553
1554    @Override
1555    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1556            throws RemoteException {
1557        if (code == SYSPROPS_TRANSACTION) {
1558            // We need to tell all apps about the system property change.
1559            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1560            synchronized(this) {
1561                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1562                    final int NA = apps.size();
1563                    for (int ia=0; ia<NA; ia++) {
1564                        ProcessRecord app = apps.valueAt(ia);
1565                        if (app.thread != null) {
1566                            procs.add(app.thread.asBinder());
1567                        }
1568                    }
1569                }
1570            }
1571
1572            int N = procs.size();
1573            for (int i=0; i<N; i++) {
1574                Parcel data2 = Parcel.obtain();
1575                try {
1576                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1577                } catch (RemoteException e) {
1578                }
1579                data2.recycle();
1580            }
1581        }
1582        try {
1583            return super.onTransact(code, data, reply, flags);
1584        } catch (RuntimeException e) {
1585            // The activity manager only throws security exceptions, so let's
1586            // log all others.
1587            if (!(e instanceof SecurityException)) {
1588                Slog.e(TAG, "Activity Manager Crash", e);
1589            }
1590            throw e;
1591        }
1592    }
1593
1594    void updateCpuStats() {
1595        final long now = SystemClock.uptimeMillis();
1596        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1597            return;
1598        }
1599        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1600            synchronized (mProcessStatsThread) {
1601                mProcessStatsThread.notify();
1602            }
1603        }
1604    }
1605
1606    void updateCpuStatsNow() {
1607        synchronized (mProcessStatsThread) {
1608            mProcessStatsMutexFree.set(false);
1609            final long now = SystemClock.uptimeMillis();
1610            boolean haveNewCpuStats = false;
1611
1612            if (MONITOR_CPU_USAGE &&
1613                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1614                mLastCpuTime.set(now);
1615                haveNewCpuStats = true;
1616                mProcessStats.update();
1617                //Slog.i(TAG, mProcessStats.printCurrentState());
1618                //Slog.i(TAG, "Total CPU usage: "
1619                //        + mProcessStats.getTotalCpuPercent() + "%");
1620
1621                // Slog the cpu usage if the property is set.
1622                if ("true".equals(SystemProperties.get("events.cpu"))) {
1623                    int user = mProcessStats.getLastUserTime();
1624                    int system = mProcessStats.getLastSystemTime();
1625                    int iowait = mProcessStats.getLastIoWaitTime();
1626                    int irq = mProcessStats.getLastIrqTime();
1627                    int softIrq = mProcessStats.getLastSoftIrqTime();
1628                    int idle = mProcessStats.getLastIdleTime();
1629
1630                    int total = user + system + iowait + irq + softIrq + idle;
1631                    if (total == 0) total = 1;
1632
1633                    EventLog.writeEvent(EventLogTags.CPU,
1634                            ((user+system+iowait+irq+softIrq) * 100) / total,
1635                            (user * 100) / total,
1636                            (system * 100) / total,
1637                            (iowait * 100) / total,
1638                            (irq * 100) / total,
1639                            (softIrq * 100) / total);
1640                }
1641            }
1642
1643            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1644            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1645            synchronized(bstats) {
1646                synchronized(mPidsSelfLocked) {
1647                    if (haveNewCpuStats) {
1648                        if (mOnBattery) {
1649                            int perc = bstats.startAddingCpuLocked();
1650                            int totalUTime = 0;
1651                            int totalSTime = 0;
1652                            final int N = mProcessStats.countStats();
1653                            for (int i=0; i<N; i++) {
1654                                ProcessStats.Stats st = mProcessStats.getStats(i);
1655                                if (!st.working) {
1656                                    continue;
1657                                }
1658                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1659                                int otherUTime = (st.rel_utime*perc)/100;
1660                                int otherSTime = (st.rel_stime*perc)/100;
1661                                totalUTime += otherUTime;
1662                                totalSTime += otherSTime;
1663                                if (pr != null) {
1664                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1665                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1666                                            st.rel_stime-otherSTime);
1667                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1668                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1669                                } else {
1670                                    BatteryStatsImpl.Uid.Proc ps =
1671                                            bstats.getProcessStatsLocked(st.name, st.pid);
1672                                    if (ps != null) {
1673                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1674                                                st.rel_stime-otherSTime);
1675                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1676                                    }
1677                                }
1678                            }
1679                            bstats.finishAddingCpuLocked(perc, totalUTime,
1680                                    totalSTime, cpuSpeedTimes);
1681                        }
1682                    }
1683                }
1684
1685                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1686                    mLastWriteTime = now;
1687                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1688                }
1689            }
1690        }
1691    }
1692
1693    @Override
1694    public void batteryNeedsCpuUpdate() {
1695        updateCpuStatsNow();
1696    }
1697
1698    @Override
1699    public void batteryPowerChanged(boolean onBattery) {
1700        // When plugging in, update the CPU stats first before changing
1701        // the plug state.
1702        updateCpuStatsNow();
1703        synchronized (this) {
1704            synchronized(mPidsSelfLocked) {
1705                mOnBattery = DEBUG_POWER ? true : onBattery;
1706            }
1707        }
1708    }
1709
1710    /**
1711     * Initialize the application bind args. These are passed to each
1712     * process when the bindApplication() IPC is sent to the process. They're
1713     * lazily setup to make sure the services are running when they're asked for.
1714     */
1715    private HashMap<String, IBinder> getCommonServicesLocked() {
1716        if (mAppBindArgs == null) {
1717            mAppBindArgs = new HashMap<String, IBinder>();
1718
1719            // Setup the application init args
1720            mAppBindArgs.put("package", ServiceManager.getService("package"));
1721            mAppBindArgs.put("window", ServiceManager.getService("window"));
1722            mAppBindArgs.put(Context.ALARM_SERVICE,
1723                    ServiceManager.getService(Context.ALARM_SERVICE));
1724        }
1725        return mAppBindArgs;
1726    }
1727
1728    final void setFocusedActivityLocked(ActivityRecord r) {
1729        if (mFocusedActivity != r) {
1730            mFocusedActivity = r;
1731            if (r != null) {
1732                mWindowManager.setFocusedApp(r.appToken, true);
1733            }
1734        }
1735    }
1736
1737    private final void updateLruProcessInternalLocked(ProcessRecord app,
1738            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1739        // put it on the LRU to keep track of when it should be exited.
1740        int lrui = mLruProcesses.indexOf(app);
1741        if (lrui >= 0) mLruProcesses.remove(lrui);
1742
1743        int i = mLruProcesses.size()-1;
1744        int skipTop = 0;
1745
1746        app.lruSeq = mLruSeq;
1747
1748        // compute the new weight for this process.
1749        if (updateActivityTime) {
1750            app.lastActivityTime = SystemClock.uptimeMillis();
1751        }
1752        if (app.activities.size() > 0) {
1753            // If this process has activities, we more strongly want to keep
1754            // it around.
1755            app.lruWeight = app.lastActivityTime;
1756        } else if (app.pubProviders.size() > 0) {
1757            // If this process contains content providers, we want to keep
1758            // it a little more strongly.
1759            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1760            // Also don't let it kick out the first few "real" hidden processes.
1761            skipTop = ProcessList.MIN_HIDDEN_APPS;
1762        } else {
1763            // If this process doesn't have activities, we less strongly
1764            // want to keep it around, and generally want to avoid getting
1765            // in front of any very recently used activities.
1766            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1767            // Also don't let it kick out the first few "real" hidden processes.
1768            skipTop = ProcessList.MIN_HIDDEN_APPS;
1769        }
1770
1771        while (i >= 0) {
1772            ProcessRecord p = mLruProcesses.get(i);
1773            // If this app shouldn't be in front of the first N background
1774            // apps, then skip over that many that are currently hidden.
1775            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1776                skipTop--;
1777            }
1778            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1779                mLruProcesses.add(i+1, app);
1780                break;
1781            }
1782            i--;
1783        }
1784        if (i < 0) {
1785            mLruProcesses.add(0, app);
1786        }
1787
1788        // If the app is currently using a content provider or service,
1789        // bump those processes as well.
1790        if (app.connections.size() > 0) {
1791            for (ConnectionRecord cr : app.connections) {
1792                if (cr.binding != null && cr.binding.service != null
1793                        && cr.binding.service.app != null
1794                        && cr.binding.service.app.lruSeq != mLruSeq) {
1795                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1796                            updateActivityTime, i+1);
1797                }
1798            }
1799        }
1800        for (int j=app.conProviders.size()-1; j>=0; j--) {
1801            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1802            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1803                updateLruProcessInternalLocked(cpr.proc, false,
1804                        updateActivityTime, i+1);
1805            }
1806        }
1807
1808        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1809        if (oomAdj) {
1810            updateOomAdjLocked();
1811        }
1812    }
1813
1814    final void updateLruProcessLocked(ProcessRecord app,
1815            boolean oomAdj, boolean updateActivityTime) {
1816        mLruSeq++;
1817        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1818    }
1819
1820    final ProcessRecord getProcessRecordLocked(
1821            String processName, int uid) {
1822        if (uid == Process.SYSTEM_UID) {
1823            // The system gets to run in any process.  If there are multiple
1824            // processes with the same uid, just pick the first (this
1825            // should never happen).
1826            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1827                    processName);
1828            if (procs == null) return null;
1829            final int N = procs.size();
1830            for (int i = 0; i < N; i++) {
1831                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1832            }
1833        }
1834        ProcessRecord proc = mProcessNames.get(processName, uid);
1835        return proc;
1836    }
1837
1838    void ensurePackageDexOpt(String packageName) {
1839        IPackageManager pm = AppGlobals.getPackageManager();
1840        try {
1841            if (pm.performDexOpt(packageName)) {
1842                mDidDexOpt = true;
1843            }
1844        } catch (RemoteException e) {
1845        }
1846    }
1847
1848    boolean isNextTransitionForward() {
1849        int transit = mWindowManager.getPendingAppTransition();
1850        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1851                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1852                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1853    }
1854
1855    final ProcessRecord startProcessLocked(String processName,
1856            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1857            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1858            boolean isolated) {
1859        ProcessRecord app;
1860        if (!isolated) {
1861            app = getProcessRecordLocked(processName, info.uid);
1862        } else {
1863            // If this is an isolated process, it can't re-use an existing process.
1864            app = null;
1865        }
1866        // We don't have to do anything more if:
1867        // (1) There is an existing application record; and
1868        // (2) The caller doesn't think it is dead, OR there is no thread
1869        //     object attached to it so we know it couldn't have crashed; and
1870        // (3) There is a pid assigned to it, so it is either starting or
1871        //     already running.
1872        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1873                + " app=" + app + " knownToBeDead=" + knownToBeDead
1874                + " thread=" + (app != null ? app.thread : null)
1875                + " pid=" + (app != null ? app.pid : -1));
1876        if (app != null && app.pid > 0) {
1877            if (!knownToBeDead || app.thread == null) {
1878                // We already have the app running, or are waiting for it to
1879                // come up (we have a pid but not yet its thread), so keep it.
1880                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1881                // If this is a new package in the process, add the package to the list
1882                app.addPackage(info.packageName);
1883                return app;
1884            } else {
1885                // An application record is attached to a previous process,
1886                // clean it up now.
1887                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1888                handleAppDiedLocked(app, true, true);
1889            }
1890        }
1891
1892        String hostingNameStr = hostingName != null
1893                ? hostingName.flattenToShortString() : null;
1894
1895        if (!isolated) {
1896            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1897                // If we are in the background, then check to see if this process
1898                // is bad.  If so, we will just silently fail.
1899                if (mBadProcesses.get(info.processName, info.uid) != null) {
1900                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1901                            + "/" + info.processName);
1902                    return null;
1903                }
1904            } else {
1905                // When the user is explicitly starting a process, then clear its
1906                // crash count so that we won't make it bad until they see at
1907                // least one crash dialog again, and make the process good again
1908                // if it had been bad.
1909                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1910                        + "/" + info.processName);
1911                mProcessCrashTimes.remove(info.processName, info.uid);
1912                if (mBadProcesses.get(info.processName, info.uid) != null) {
1913                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1914                            info.processName);
1915                    mBadProcesses.remove(info.processName, info.uid);
1916                    if (app != null) {
1917                        app.bad = false;
1918                    }
1919                }
1920            }
1921        }
1922
1923        if (app == null) {
1924            app = newProcessRecordLocked(null, info, processName, isolated);
1925            if (app == null) {
1926                Slog.w(TAG, "Failed making new process record for "
1927                        + processName + "/" + info.uid + " isolated=" + isolated);
1928                return null;
1929            }
1930            mProcessNames.put(processName, app.uid, app);
1931            if (isolated) {
1932                mIsolatedProcesses.put(app.uid, app);
1933            }
1934        } else {
1935            // If this is a new package in the process, add the package to the list
1936            app.addPackage(info.packageName);
1937        }
1938
1939        // If the system is not ready yet, then hold off on starting this
1940        // process until it is.
1941        if (!mProcessesReady
1942                && !isAllowedWhileBooting(info)
1943                && !allowWhileBooting) {
1944            if (!mProcessesOnHold.contains(app)) {
1945                mProcessesOnHold.add(app);
1946            }
1947            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1948            return app;
1949        }
1950
1951        startProcessLocked(app, hostingType, hostingNameStr);
1952        return (app.pid != 0) ? app : null;
1953    }
1954
1955    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1956        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1957    }
1958
1959    private final void startProcessLocked(ProcessRecord app,
1960            String hostingType, String hostingNameStr) {
1961        if (app.pid > 0 && app.pid != MY_PID) {
1962            synchronized (mPidsSelfLocked) {
1963                mPidsSelfLocked.remove(app.pid);
1964                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1965            }
1966            app.setPid(0);
1967        }
1968
1969        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1970                "startProcessLocked removing on hold: " + app);
1971        mProcessesOnHold.remove(app);
1972
1973        updateCpuStats();
1974
1975        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1976        mProcDeaths[0] = 0;
1977
1978        try {
1979            int uid = app.uid;
1980
1981            int[] gids = null;
1982            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1983            if (!app.isolated) {
1984                try {
1985                    final PackageManager pm = mContext.getPackageManager();
1986                    gids = pm.getPackageGids(app.info.packageName);
1987                    if (pm.checkPermission(
1988                            android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName)
1989                            == PERMISSION_GRANTED) {
1990                        if (Environment.isExternalStorageEmulated()) {
1991                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
1992                        } else {
1993                            mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER;
1994                        }
1995                    }
1996                } catch (PackageManager.NameNotFoundException e) {
1997                    Slog.w(TAG, "Unable to retrieve gids", e);
1998                }
1999            }
2000            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2001                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2002                        && mTopComponent != null
2003                        && app.processName.equals(mTopComponent.getPackageName())) {
2004                    uid = 0;
2005                }
2006                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2007                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2008                    uid = 0;
2009                }
2010            }
2011            int debugFlags = 0;
2012            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2013                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2014                // Also turn on CheckJNI for debuggable apps. It's quite
2015                // awkward to turn on otherwise.
2016                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2017            }
2018            // Run the app in safe mode if its manifest requests so or the
2019            // system is booted in safe mode.
2020            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2021                Zygote.systemInSafeMode == true) {
2022                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2023            }
2024            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2025                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2026            }
2027            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2028                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2029            }
2030            if ("1".equals(SystemProperties.get("debug.assert"))) {
2031                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2032            }
2033
2034            // Start the process.  It will either succeed and return a result containing
2035            // the PID of the new process, or else throw a RuntimeException.
2036            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2037                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2038                    app.info.targetSdkVersion, null, null);
2039
2040            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2041            synchronized (bs) {
2042                if (bs.isOnBattery()) {
2043                    app.batteryStats.incStartsLocked();
2044                }
2045            }
2046
2047            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2048                    app.processName, hostingType,
2049                    hostingNameStr != null ? hostingNameStr : "");
2050
2051            if (app.persistent) {
2052                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2053            }
2054
2055            StringBuilder buf = mStringBuilder;
2056            buf.setLength(0);
2057            buf.append("Start proc ");
2058            buf.append(app.processName);
2059            buf.append(" for ");
2060            buf.append(hostingType);
2061            if (hostingNameStr != null) {
2062                buf.append(" ");
2063                buf.append(hostingNameStr);
2064            }
2065            buf.append(": pid=");
2066            buf.append(startResult.pid);
2067            buf.append(" uid=");
2068            buf.append(uid);
2069            buf.append(" gids={");
2070            if (gids != null) {
2071                for (int gi=0; gi<gids.length; gi++) {
2072                    if (gi != 0) buf.append(", ");
2073                    buf.append(gids[gi]);
2074
2075                }
2076            }
2077            buf.append("}");
2078            Slog.i(TAG, buf.toString());
2079            app.setPid(startResult.pid);
2080            app.usingWrapper = startResult.usingWrapper;
2081            app.removed = false;
2082            synchronized (mPidsSelfLocked) {
2083                this.mPidsSelfLocked.put(startResult.pid, app);
2084                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2085                msg.obj = app;
2086                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2087                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2088            }
2089        } catch (RuntimeException e) {
2090            // XXX do better error recovery.
2091            app.setPid(0);
2092            Slog.e(TAG, "Failure starting process " + app.processName, e);
2093        }
2094    }
2095
2096    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2097        if (resumed) {
2098            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2099        } else {
2100            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2101        }
2102    }
2103
2104    boolean startHomeActivityLocked(int userId) {
2105        if (mHeadless) {
2106            // Added because none of the other calls to ensureBootCompleted seem to fire
2107            // when running headless.
2108            ensureBootCompleted();
2109            return false;
2110        }
2111
2112        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2113                && mTopAction == null) {
2114            // We are running in factory test mode, but unable to find
2115            // the factory test app, so just sit around displaying the
2116            // error message and don't try to start anything.
2117            return false;
2118        }
2119        Intent intent = new Intent(
2120            mTopAction,
2121            mTopData != null ? Uri.parse(mTopData) : null);
2122        intent.setComponent(mTopComponent);
2123        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2124            intent.addCategory(Intent.CATEGORY_HOME);
2125        }
2126        ActivityInfo aInfo =
2127            intent.resolveActivityInfo(mContext.getPackageManager(),
2128                    STOCK_PM_FLAGS);
2129        if (aInfo != null) {
2130            intent.setComponent(new ComponentName(
2131                    aInfo.applicationInfo.packageName, aInfo.name));
2132            // Don't do this if the home app is currently being
2133            // instrumented.
2134            aInfo = new ActivityInfo(aInfo);
2135            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2136            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2137                    aInfo.applicationInfo.uid);
2138            if (app == null || app.instrumentationClass == null) {
2139                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2140                mMainStack.startActivityLocked(null, intent, null, aInfo,
2141                        null, null, 0, 0, 0, 0, null, false, null);
2142            }
2143        }
2144
2145        return true;
2146    }
2147
2148    /**
2149     * Starts the "new version setup screen" if appropriate.
2150     */
2151    void startSetupActivityLocked() {
2152        // Only do this once per boot.
2153        if (mCheckedForSetup) {
2154            return;
2155        }
2156
2157        // We will show this screen if the current one is a different
2158        // version than the last one shown, and we are not running in
2159        // low-level factory test mode.
2160        final ContentResolver resolver = mContext.getContentResolver();
2161        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2162                Settings.Secure.getInt(resolver,
2163                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2164            mCheckedForSetup = true;
2165
2166            // See if we should be showing the platform update setup UI.
2167            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2168            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2169                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2170
2171            // We don't allow third party apps to replace this.
2172            ResolveInfo ri = null;
2173            for (int i=0; ris != null && i<ris.size(); i++) {
2174                if ((ris.get(i).activityInfo.applicationInfo.flags
2175                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2176                    ri = ris.get(i);
2177                    break;
2178                }
2179            }
2180
2181            if (ri != null) {
2182                String vers = ri.activityInfo.metaData != null
2183                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2184                        : null;
2185                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2186                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2187                            Intent.METADATA_SETUP_VERSION);
2188                }
2189                String lastVers = Settings.Secure.getString(
2190                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2191                if (vers != null && !vers.equals(lastVers)) {
2192                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2193                    intent.setComponent(new ComponentName(
2194                            ri.activityInfo.packageName, ri.activityInfo.name));
2195                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2196                            null, null, 0, 0, 0, 0, null, false, null);
2197                }
2198            }
2199        }
2200    }
2201
2202    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2203        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2204    }
2205
2206    void enforceNotIsolatedCaller(String caller) {
2207        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2208            throw new SecurityException("Isolated process not allowed to call " + caller);
2209        }
2210    }
2211
2212    public int getFrontActivityScreenCompatMode() {
2213        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2214        synchronized (this) {
2215            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2216        }
2217    }
2218
2219    public void setFrontActivityScreenCompatMode(int mode) {
2220        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2221                "setFrontActivityScreenCompatMode");
2222        synchronized (this) {
2223            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2224        }
2225    }
2226
2227    public int getPackageScreenCompatMode(String packageName) {
2228        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2229        synchronized (this) {
2230            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2231        }
2232    }
2233
2234    public void setPackageScreenCompatMode(String packageName, int mode) {
2235        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2236                "setPackageScreenCompatMode");
2237        synchronized (this) {
2238            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2239        }
2240    }
2241
2242    public boolean getPackageAskScreenCompat(String packageName) {
2243        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2244        synchronized (this) {
2245            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2246        }
2247    }
2248
2249    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2250        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2251                "setPackageAskScreenCompat");
2252        synchronized (this) {
2253            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2254        }
2255    }
2256
2257    void reportResumedActivityLocked(ActivityRecord r) {
2258        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2259        updateUsageStats(r, true);
2260    }
2261
2262    private void dispatchProcessesChanged() {
2263        int N;
2264        synchronized (this) {
2265            N = mPendingProcessChanges.size();
2266            if (mActiveProcessChanges.length < N) {
2267                mActiveProcessChanges = new ProcessChangeItem[N];
2268            }
2269            mPendingProcessChanges.toArray(mActiveProcessChanges);
2270            mAvailProcessChanges.addAll(mPendingProcessChanges);
2271            mPendingProcessChanges.clear();
2272            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2273        }
2274        int i = mProcessObservers.beginBroadcast();
2275        while (i > 0) {
2276            i--;
2277            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2278            if (observer != null) {
2279                try {
2280                    for (int j=0; j<N; j++) {
2281                        ProcessChangeItem item = mActiveProcessChanges[j];
2282                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2283                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2284                                    + item.pid + " uid=" + item.uid + ": "
2285                                    + item.foregroundActivities);
2286                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2287                                    item.foregroundActivities);
2288                        }
2289                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2291                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2292                            observer.onImportanceChanged(item.pid, item.uid,
2293                                    item.importance);
2294                        }
2295                    }
2296                } catch (RemoteException e) {
2297                }
2298            }
2299        }
2300        mProcessObservers.finishBroadcast();
2301    }
2302
2303    private void dispatchProcessDied(int pid, int uid) {
2304        int i = mProcessObservers.beginBroadcast();
2305        while (i > 0) {
2306            i--;
2307            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2308            if (observer != null) {
2309                try {
2310                    observer.onProcessDied(pid, uid);
2311                } catch (RemoteException e) {
2312                }
2313            }
2314        }
2315        mProcessObservers.finishBroadcast();
2316    }
2317
2318    final void doPendingActivityLaunchesLocked(boolean doResume) {
2319        final int N = mPendingActivityLaunches.size();
2320        if (N <= 0) {
2321            return;
2322        }
2323        for (int i=0; i<N; i++) {
2324            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2325            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2326                    pal.startFlags, doResume && i == (N-1), null);
2327        }
2328        mPendingActivityLaunches.clear();
2329    }
2330
2331    public final int startActivity(IApplicationThread caller,
2332            Intent intent, String resolvedType, IBinder resultTo,
2333            String resultWho, int requestCode, int startFlags,
2334            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2335        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2336                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2337    }
2338
2339    public final int startActivityAsUser(IApplicationThread caller,
2340            Intent intent, String resolvedType, IBinder resultTo,
2341            String resultWho, int requestCode, int startFlags,
2342            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2343        enforceNotIsolatedCaller("startActivity");
2344        if (userId != UserHandle.getCallingUserId()) {
2345            // Requesting a different user, make sure that they have the permission
2346            if (checkComponentPermission(
2347                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2348                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2349                    == PackageManager.PERMISSION_GRANTED) {
2350                // Translate to the current user id, if caller wasn't aware
2351                if (userId == UserHandle.USER_CURRENT) {
2352                    userId = mCurrentUserId;
2353                }
2354            } else {
2355                String msg = "Permission Denial: "
2356                        + "Request to startActivity as user " + userId
2357                        + " but is calling from user " + UserHandle.getCallingUserId()
2358                        + "; this requires "
2359                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2360                Slog.w(TAG, msg);
2361                throw new SecurityException(msg);
2362            }
2363        } else {
2364            if (intent.getCategories() != null
2365                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2366                // Requesting home, set the identity to the current user
2367                // HACK!
2368                userId = mCurrentUserId;
2369            } else {
2370                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2371                // the current user's userId
2372                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2373                    userId = 0;
2374                } else {
2375                    userId = Binder.getOrigCallingUser();
2376                }
2377            }
2378        }
2379        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2380                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2381                null, null, options, userId);
2382    }
2383
2384    public final WaitResult startActivityAndWait(IApplicationThread caller,
2385            Intent intent, String resolvedType, IBinder resultTo,
2386            String resultWho, int requestCode, int startFlags, String profileFile,
2387            ParcelFileDescriptor profileFd, Bundle options) {
2388        enforceNotIsolatedCaller("startActivityAndWait");
2389        WaitResult res = new WaitResult();
2390        int userId = Binder.getOrigCallingUser();
2391        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2392                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2393                res, null, options, userId);
2394        return res;
2395    }
2396
2397    public final int startActivityWithConfig(IApplicationThread caller,
2398            Intent intent, String resolvedType, IBinder resultTo,
2399            String resultWho, int requestCode, int startFlags, Configuration config,
2400            Bundle options) {
2401        enforceNotIsolatedCaller("startActivityWithConfig");
2402        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2403                resultTo, resultWho, requestCode, startFlags,
2404                null, null, null, config, options, Binder.getOrigCallingUser());
2405        return ret;
2406    }
2407
2408    public int startActivityIntentSender(IApplicationThread caller,
2409            IntentSender intent, Intent fillInIntent, String resolvedType,
2410            IBinder resultTo, String resultWho, int requestCode,
2411            int flagsMask, int flagsValues, Bundle options) {
2412        enforceNotIsolatedCaller("startActivityIntentSender");
2413        // Refuse possible leaked file descriptors
2414        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2415            throw new IllegalArgumentException("File descriptors passed in Intent");
2416        }
2417
2418        IIntentSender sender = intent.getTarget();
2419        if (!(sender instanceof PendingIntentRecord)) {
2420            throw new IllegalArgumentException("Bad PendingIntent object");
2421        }
2422
2423        PendingIntentRecord pir = (PendingIntentRecord)sender;
2424
2425        synchronized (this) {
2426            // If this is coming from the currently resumed activity, it is
2427            // effectively saying that app switches are allowed at this point.
2428            if (mMainStack.mResumedActivity != null
2429                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2430                            Binder.getCallingUid()) {
2431                mAppSwitchesAllowedTime = 0;
2432            }
2433        }
2434        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2435                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2436        return ret;
2437    }
2438
2439    public boolean startNextMatchingActivity(IBinder callingActivity,
2440            Intent intent, Bundle options) {
2441        // Refuse possible leaked file descriptors
2442        if (intent != null && intent.hasFileDescriptors() == true) {
2443            throw new IllegalArgumentException("File descriptors passed in Intent");
2444        }
2445
2446        synchronized (this) {
2447            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2448            if (r == null) {
2449                ActivityOptions.abort(options);
2450                return false;
2451            }
2452            if (r.app == null || r.app.thread == null) {
2453                // The caller is not running...  d'oh!
2454                ActivityOptions.abort(options);
2455                return false;
2456            }
2457            intent = new Intent(intent);
2458            // The caller is not allowed to change the data.
2459            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2460            // And we are resetting to find the next component...
2461            intent.setComponent(null);
2462
2463            ActivityInfo aInfo = null;
2464            try {
2465                List<ResolveInfo> resolves =
2466                    AppGlobals.getPackageManager().queryIntentActivities(
2467                            intent, r.resolvedType,
2468                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2469                            UserHandle.getCallingUserId());
2470
2471                // Look for the original activity in the list...
2472                final int N = resolves != null ? resolves.size() : 0;
2473                for (int i=0; i<N; i++) {
2474                    ResolveInfo rInfo = resolves.get(i);
2475                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2476                            && rInfo.activityInfo.name.equals(r.info.name)) {
2477                        // We found the current one...  the next matching is
2478                        // after it.
2479                        i++;
2480                        if (i<N) {
2481                            aInfo = resolves.get(i).activityInfo;
2482                        }
2483                        break;
2484                    }
2485                }
2486            } catch (RemoteException e) {
2487            }
2488
2489            if (aInfo == null) {
2490                // Nobody who is next!
2491                ActivityOptions.abort(options);
2492                return false;
2493            }
2494
2495            intent.setComponent(new ComponentName(
2496                    aInfo.applicationInfo.packageName, aInfo.name));
2497            intent.setFlags(intent.getFlags()&~(
2498                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2499                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2500                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2501                    Intent.FLAG_ACTIVITY_NEW_TASK));
2502
2503            // Okay now we need to start the new activity, replacing the
2504            // currently running activity.  This is a little tricky because
2505            // we want to start the new one as if the current one is finished,
2506            // but not finish the current one first so that there is no flicker.
2507            // And thus...
2508            final boolean wasFinishing = r.finishing;
2509            r.finishing = true;
2510
2511            // Propagate reply information over to the new activity.
2512            final ActivityRecord resultTo = r.resultTo;
2513            final String resultWho = r.resultWho;
2514            final int requestCode = r.requestCode;
2515            r.resultTo = null;
2516            if (resultTo != null) {
2517                resultTo.removeResultsLocked(r, resultWho, requestCode);
2518            }
2519
2520            final long origId = Binder.clearCallingIdentity();
2521            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2522                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2523                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2524                    options, false, null);
2525            Binder.restoreCallingIdentity(origId);
2526
2527            r.finishing = wasFinishing;
2528            if (res != ActivityManager.START_SUCCESS) {
2529                return false;
2530            }
2531            return true;
2532        }
2533    }
2534
2535    public final int startActivityInPackage(int uid,
2536            Intent intent, String resolvedType, IBinder resultTo,
2537            String resultWho, int requestCode, int startFlags, Bundle options) {
2538
2539        // This is so super not safe, that only the system (or okay root)
2540        // can do it.
2541        final int callingUid = Binder.getCallingUid();
2542        if (callingUid != 0 && callingUid != Process.myUid()) {
2543            throw new SecurityException(
2544                    "startActivityInPackage only available to the system");
2545        }
2546
2547        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2548                resultTo, resultWho, requestCode, startFlags,
2549                null, null, null, null, options, UserHandle.getUserId(uid));
2550        return ret;
2551    }
2552
2553    public final int startActivities(IApplicationThread caller,
2554            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2555        enforceNotIsolatedCaller("startActivities");
2556        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2557                options, Binder.getOrigCallingUser());
2558        return ret;
2559    }
2560
2561    public final int startActivitiesInPackage(int uid,
2562            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2563            Bundle options) {
2564
2565        // This is so super not safe, that only the system (or okay root)
2566        // can do it.
2567        final int callingUid = Binder.getCallingUid();
2568        if (callingUid != 0 && callingUid != Process.myUid()) {
2569            throw new SecurityException(
2570                    "startActivityInPackage only available to the system");
2571        }
2572        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2573                options, UserHandle.getUserId(uid));
2574        return ret;
2575    }
2576
2577    final void addRecentTaskLocked(TaskRecord task) {
2578        int N = mRecentTasks.size();
2579        // Quick case: check if the top-most recent task is the same.
2580        if (N > 0 && mRecentTasks.get(0) == task) {
2581            return;
2582        }
2583        // Remove any existing entries that are the same kind of task.
2584        for (int i=0; i<N; i++) {
2585            TaskRecord tr = mRecentTasks.get(i);
2586            if (task.userId == tr.userId
2587                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2588                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2589                mRecentTasks.remove(i);
2590                i--;
2591                N--;
2592                if (task.intent == null) {
2593                    // If the new recent task we are adding is not fully
2594                    // specified, then replace it with the existing recent task.
2595                    task = tr;
2596                }
2597            }
2598        }
2599        if (N >= MAX_RECENT_TASKS) {
2600            mRecentTasks.remove(N-1);
2601        }
2602        mRecentTasks.add(0, task);
2603    }
2604
2605    public void setRequestedOrientation(IBinder token,
2606            int requestedOrientation) {
2607        synchronized (this) {
2608            ActivityRecord r = mMainStack.isInStackLocked(token);
2609            if (r == null) {
2610                return;
2611            }
2612            final long origId = Binder.clearCallingIdentity();
2613            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2614            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2615                    mConfiguration,
2616                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2617            if (config != null) {
2618                r.frozenBeforeDestroy = true;
2619                if (!updateConfigurationLocked(config, r, false, false)) {
2620                    mMainStack.resumeTopActivityLocked(null);
2621                }
2622            }
2623            Binder.restoreCallingIdentity(origId);
2624        }
2625    }
2626
2627    public int getRequestedOrientation(IBinder token) {
2628        synchronized (this) {
2629            ActivityRecord r = mMainStack.isInStackLocked(token);
2630            if (r == null) {
2631                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2632            }
2633            return mWindowManager.getAppOrientation(r.appToken);
2634        }
2635    }
2636
2637    /**
2638     * This is the internal entry point for handling Activity.finish().
2639     *
2640     * @param token The Binder token referencing the Activity we want to finish.
2641     * @param resultCode Result code, if any, from this Activity.
2642     * @param resultData Result data (Intent), if any, from this Activity.
2643     *
2644     * @return Returns true if the activity successfully finished, or false if it is still running.
2645     */
2646    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2647        // Refuse possible leaked file descriptors
2648        if (resultData != null && resultData.hasFileDescriptors() == true) {
2649            throw new IllegalArgumentException("File descriptors passed in Intent");
2650        }
2651
2652        synchronized(this) {
2653            if (mController != null) {
2654                // Find the first activity that is not finishing.
2655                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2656                if (next != null) {
2657                    // ask watcher if this is allowed
2658                    boolean resumeOK = true;
2659                    try {
2660                        resumeOK = mController.activityResuming(next.packageName);
2661                    } catch (RemoteException e) {
2662                        mController = null;
2663                    }
2664
2665                    if (!resumeOK) {
2666                        return false;
2667                    }
2668                }
2669            }
2670            final long origId = Binder.clearCallingIdentity();
2671            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2672                    resultData, "app-request");
2673            Binder.restoreCallingIdentity(origId);
2674            return res;
2675        }
2676    }
2677
2678    public final void finishHeavyWeightApp() {
2679        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2680                != PackageManager.PERMISSION_GRANTED) {
2681            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2682                    + Binder.getCallingPid()
2683                    + ", uid=" + Binder.getCallingUid()
2684                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2685            Slog.w(TAG, msg);
2686            throw new SecurityException(msg);
2687        }
2688
2689        synchronized(this) {
2690            if (mHeavyWeightProcess == null) {
2691                return;
2692            }
2693
2694            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2695                    mHeavyWeightProcess.activities);
2696            for (int i=0; i<activities.size(); i++) {
2697                ActivityRecord r = activities.get(i);
2698                if (!r.finishing) {
2699                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2700                    if (index >= 0) {
2701                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2702                                null, "finish-heavy");
2703                    }
2704                }
2705            }
2706
2707            mHeavyWeightProcess = null;
2708            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2709        }
2710    }
2711
2712    public void crashApplication(int uid, int initialPid, String packageName,
2713            String message) {
2714        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2715                != PackageManager.PERMISSION_GRANTED) {
2716            String msg = "Permission Denial: crashApplication() from pid="
2717                    + Binder.getCallingPid()
2718                    + ", uid=" + Binder.getCallingUid()
2719                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2720            Slog.w(TAG, msg);
2721            throw new SecurityException(msg);
2722        }
2723
2724        synchronized(this) {
2725            ProcessRecord proc = null;
2726
2727            // Figure out which process to kill.  We don't trust that initialPid
2728            // still has any relation to current pids, so must scan through the
2729            // list.
2730            synchronized (mPidsSelfLocked) {
2731                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2732                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2733                    if (p.uid != uid) {
2734                        continue;
2735                    }
2736                    if (p.pid == initialPid) {
2737                        proc = p;
2738                        break;
2739                    }
2740                    for (String str : p.pkgList) {
2741                        if (str.equals(packageName)) {
2742                            proc = p;
2743                        }
2744                    }
2745                }
2746            }
2747
2748            if (proc == null) {
2749                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2750                        + " initialPid=" + initialPid
2751                        + " packageName=" + packageName);
2752                return;
2753            }
2754
2755            if (proc.thread != null) {
2756                if (proc.pid == Process.myPid()) {
2757                    Log.w(TAG, "crashApplication: trying to crash self!");
2758                    return;
2759                }
2760                long ident = Binder.clearCallingIdentity();
2761                try {
2762                    proc.thread.scheduleCrash(message);
2763                } catch (RemoteException e) {
2764                }
2765                Binder.restoreCallingIdentity(ident);
2766            }
2767        }
2768    }
2769
2770    public final void finishSubActivity(IBinder token, String resultWho,
2771            int requestCode) {
2772        synchronized(this) {
2773            final long origId = Binder.clearCallingIdentity();
2774            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2775            Binder.restoreCallingIdentity(origId);
2776        }
2777    }
2778
2779    public boolean finishActivityAffinity(IBinder token) {
2780        synchronized(this) {
2781            final long origId = Binder.clearCallingIdentity();
2782            boolean res = mMainStack.finishActivityAffinityLocked(token);
2783            Binder.restoreCallingIdentity(origId);
2784            return res;
2785        }
2786    }
2787
2788    public boolean willActivityBeVisible(IBinder token) {
2789        synchronized(this) {
2790            int i;
2791            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2792                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2793                if (r.appToken == token) {
2794                    return true;
2795                }
2796                if (r.fullscreen && !r.finishing) {
2797                    return false;
2798                }
2799            }
2800            return true;
2801        }
2802    }
2803
2804    public void overridePendingTransition(IBinder token, String packageName,
2805            int enterAnim, int exitAnim) {
2806        synchronized(this) {
2807            ActivityRecord self = mMainStack.isInStackLocked(token);
2808            if (self == null) {
2809                return;
2810            }
2811
2812            final long origId = Binder.clearCallingIdentity();
2813
2814            if (self.state == ActivityState.RESUMED
2815                    || self.state == ActivityState.PAUSING) {
2816                mWindowManager.overridePendingAppTransition(packageName,
2817                        enterAnim, exitAnim, null);
2818            }
2819
2820            Binder.restoreCallingIdentity(origId);
2821        }
2822    }
2823
2824    /**
2825     * Main function for removing an existing process from the activity manager
2826     * as a result of that process going away.  Clears out all connections
2827     * to the process.
2828     */
2829    private final void handleAppDiedLocked(ProcessRecord app,
2830            boolean restarting, boolean allowRestart) {
2831        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2832        if (!restarting) {
2833            mLruProcesses.remove(app);
2834        }
2835
2836        if (mProfileProc == app) {
2837            clearProfilerLocked();
2838        }
2839
2840        // Just in case...
2841        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2842            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2843            mMainStack.mPausingActivity = null;
2844        }
2845        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2846            mMainStack.mLastPausedActivity = null;
2847        }
2848
2849        // Remove this application's activities from active lists.
2850        mMainStack.removeHistoryRecordsForAppLocked(app);
2851
2852        boolean atTop = true;
2853        boolean hasVisibleActivities = false;
2854
2855        // Clean out the history list.
2856        int i = mMainStack.mHistory.size();
2857        if (localLOGV) Slog.v(
2858            TAG, "Removing app " + app + " from history with " + i + " entries");
2859        while (i > 0) {
2860            i--;
2861            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2862            if (localLOGV) Slog.v(
2863                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2864            if (r.app == app) {
2865                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2866                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2867                        RuntimeException here = new RuntimeException("here");
2868                        here.fillInStackTrace();
2869                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2870                                + ": haveState=" + r.haveState
2871                                + " stateNotNeeded=" + r.stateNotNeeded
2872                                + " finishing=" + r.finishing
2873                                + " state=" + r.state, here);
2874                    }
2875                    if (!r.finishing) {
2876                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2877                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2878                                System.identityHashCode(r),
2879                                r.task.taskId, r.shortComponentName,
2880                                "proc died without state saved");
2881                    }
2882                    mMainStack.removeActivityFromHistoryLocked(r);
2883
2884                } else {
2885                    // We have the current state for this activity, so
2886                    // it can be restarted later when needed.
2887                    if (localLOGV) Slog.v(
2888                        TAG, "Keeping entry, setting app to null");
2889                    if (r.visible) {
2890                        hasVisibleActivities = true;
2891                    }
2892                    r.app = null;
2893                    r.nowVisible = false;
2894                    if (!r.haveState) {
2895                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2896                                "App died, clearing saved state of " + r);
2897                        r.icicle = null;
2898                    }
2899                }
2900
2901                r.stack.cleanUpActivityLocked(r, true, true);
2902            }
2903            atTop = false;
2904        }
2905
2906        app.activities.clear();
2907
2908        if (app.instrumentationClass != null) {
2909            Slog.w(TAG, "Crash of app " + app.processName
2910                  + " running instrumentation " + app.instrumentationClass);
2911            Bundle info = new Bundle();
2912            info.putString("shortMsg", "Process crashed.");
2913            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2914        }
2915
2916        if (!restarting) {
2917            if (!mMainStack.resumeTopActivityLocked(null)) {
2918                // If there was nothing to resume, and we are not already
2919                // restarting this process, but there is a visible activity that
2920                // is hosted by the process...  then make sure all visible
2921                // activities are running, taking care of restarting this
2922                // process.
2923                if (hasVisibleActivities) {
2924                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2925                }
2926            }
2927        }
2928    }
2929
2930    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2931        IBinder threadBinder = thread.asBinder();
2932        // Find the application record.
2933        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2934            ProcessRecord rec = mLruProcesses.get(i);
2935            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2936                return i;
2937            }
2938        }
2939        return -1;
2940    }
2941
2942    final ProcessRecord getRecordForAppLocked(
2943            IApplicationThread thread) {
2944        if (thread == null) {
2945            return null;
2946        }
2947
2948        int appIndex = getLRURecordIndexForAppLocked(thread);
2949        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2950    }
2951
2952    final void appDiedLocked(ProcessRecord app, int pid,
2953            IApplicationThread thread) {
2954
2955        mProcDeaths[0]++;
2956
2957        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2958        synchronized (stats) {
2959            stats.noteProcessDiedLocked(app.info.uid, pid);
2960        }
2961
2962        // Clean up already done if the process has been re-started.
2963        if (app.pid == pid && app.thread != null &&
2964                app.thread.asBinder() == thread.asBinder()) {
2965            if (!app.killedBackground) {
2966                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2967                        + ") has died.");
2968            }
2969            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2970            if (localLOGV) Slog.v(
2971                TAG, "Dying app: " + app + ", pid: " + pid
2972                + ", thread: " + thread.asBinder());
2973            boolean doLowMem = app.instrumentationClass == null;
2974            handleAppDiedLocked(app, false, true);
2975
2976            if (doLowMem) {
2977                // If there are no longer any background processes running,
2978                // and the app that died was not running instrumentation,
2979                // then tell everyone we are now low on memory.
2980                boolean haveBg = false;
2981                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2982                    ProcessRecord rec = mLruProcesses.get(i);
2983                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2984                        haveBg = true;
2985                        break;
2986                    }
2987                }
2988
2989                if (!haveBg) {
2990                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2991                    long now = SystemClock.uptimeMillis();
2992                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2993                        ProcessRecord rec = mLruProcesses.get(i);
2994                        if (rec != app && rec.thread != null &&
2995                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2996                            // The low memory report is overriding any current
2997                            // state for a GC request.  Make sure to do
2998                            // heavy/important/visible/foreground processes first.
2999                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3000                                rec.lastRequestedGc = 0;
3001                            } else {
3002                                rec.lastRequestedGc = rec.lastLowMemory;
3003                            }
3004                            rec.reportLowMemory = true;
3005                            rec.lastLowMemory = now;
3006                            mProcessesToGc.remove(rec);
3007                            addProcessToGcListLocked(rec);
3008                        }
3009                    }
3010                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3011                    scheduleAppGcsLocked();
3012                }
3013            }
3014        } else if (app.pid != pid) {
3015            // A new process has already been started.
3016            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3017                    + ") has died and restarted (pid " + app.pid + ").");
3018            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3019        } else if (DEBUG_PROCESSES) {
3020            Slog.d(TAG, "Received spurious death notification for thread "
3021                    + thread.asBinder());
3022        }
3023    }
3024
3025    /**
3026     * If a stack trace dump file is configured, dump process stack traces.
3027     * @param clearTraces causes the dump file to be erased prior to the new
3028     *    traces being written, if true; when false, the new traces will be
3029     *    appended to any existing file content.
3030     * @param firstPids of dalvik VM processes to dump stack traces for first
3031     * @param lastPids of dalvik VM processes to dump stack traces for last
3032     * @param nativeProcs optional list of native process names to dump stack crawls
3033     * @return file containing stack traces, or null if no dump file is configured
3034     */
3035    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3036            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3037        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3038        if (tracesPath == null || tracesPath.length() == 0) {
3039            return null;
3040        }
3041
3042        File tracesFile = new File(tracesPath);
3043        try {
3044            File tracesDir = tracesFile.getParentFile();
3045            if (!tracesDir.exists()) tracesFile.mkdirs();
3046            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3047
3048            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3049            tracesFile.createNewFile();
3050            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3051        } catch (IOException e) {
3052            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3053            return null;
3054        }
3055
3056        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3057        return tracesFile;
3058    }
3059
3060    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3061            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3062        // Use a FileObserver to detect when traces finish writing.
3063        // The order of traces is considered important to maintain for legibility.
3064        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3065            public synchronized void onEvent(int event, String path) { notify(); }
3066        };
3067
3068        try {
3069            observer.startWatching();
3070
3071            // First collect all of the stacks of the most important pids.
3072            if (firstPids != null) {
3073                try {
3074                    int num = firstPids.size();
3075                    for (int i = 0; i < num; i++) {
3076                        synchronized (observer) {
3077                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3078                            observer.wait(200);  // Wait for write-close, give up after 200msec
3079                        }
3080                    }
3081                } catch (InterruptedException e) {
3082                    Log.wtf(TAG, e);
3083                }
3084            }
3085
3086            // Next measure CPU usage.
3087            if (processStats != null) {
3088                processStats.init();
3089                System.gc();
3090                processStats.update();
3091                try {
3092                    synchronized (processStats) {
3093                        processStats.wait(500); // measure over 1/2 second.
3094                    }
3095                } catch (InterruptedException e) {
3096                }
3097                processStats.update();
3098
3099                // We'll take the stack crawls of just the top apps using CPU.
3100                final int N = processStats.countWorkingStats();
3101                int numProcs = 0;
3102                for (int i=0; i<N && numProcs<5; i++) {
3103                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3104                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3105                        numProcs++;
3106                        try {
3107                            synchronized (observer) {
3108                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3109                                observer.wait(200);  // Wait for write-close, give up after 200msec
3110                            }
3111                        } catch (InterruptedException e) {
3112                            Log.wtf(TAG, e);
3113                        }
3114
3115                    }
3116                }
3117            }
3118
3119        } finally {
3120            observer.stopWatching();
3121        }
3122
3123        if (nativeProcs != null) {
3124            int[] pids = Process.getPidsForCommands(nativeProcs);
3125            if (pids != null) {
3126                for (int pid : pids) {
3127                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3128                }
3129            }
3130        }
3131    }
3132
3133    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3134        if (true || IS_USER_BUILD) {
3135            return;
3136        }
3137        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3138        if (tracesPath == null || tracesPath.length() == 0) {
3139            return;
3140        }
3141
3142        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3143        StrictMode.allowThreadDiskWrites();
3144        try {
3145            final File tracesFile = new File(tracesPath);
3146            final File tracesDir = tracesFile.getParentFile();
3147            final File tracesTmp = new File(tracesDir, "__tmp__");
3148            try {
3149                if (!tracesDir.exists()) tracesFile.mkdirs();
3150                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3151
3152                if (tracesFile.exists()) {
3153                    tracesTmp.delete();
3154                    tracesFile.renameTo(tracesTmp);
3155                }
3156                StringBuilder sb = new StringBuilder();
3157                Time tobj = new Time();
3158                tobj.set(System.currentTimeMillis());
3159                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3160                sb.append(": ");
3161                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3162                sb.append(" since ");
3163                sb.append(msg);
3164                FileOutputStream fos = new FileOutputStream(tracesFile);
3165                fos.write(sb.toString().getBytes());
3166                if (app == null) {
3167                    fos.write("\n*** No application process!".getBytes());
3168                }
3169                fos.close();
3170                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3171            } catch (IOException e) {
3172                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3173                return;
3174            }
3175
3176            if (app != null) {
3177                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3178                firstPids.add(app.pid);
3179                dumpStackTraces(tracesPath, firstPids, null, null, null);
3180            }
3181
3182            File lastTracesFile = null;
3183            File curTracesFile = null;
3184            for (int i=9; i>=0; i--) {
3185                String name = String.format("slow%02d.txt", i);
3186                curTracesFile = new File(tracesDir, name);
3187                if (curTracesFile.exists()) {
3188                    if (lastTracesFile != null) {
3189                        curTracesFile.renameTo(lastTracesFile);
3190                    } else {
3191                        curTracesFile.delete();
3192                    }
3193                }
3194                lastTracesFile = curTracesFile;
3195            }
3196            tracesFile.renameTo(curTracesFile);
3197            if (tracesTmp.exists()) {
3198                tracesTmp.renameTo(tracesFile);
3199            }
3200        } finally {
3201            StrictMode.setThreadPolicy(oldPolicy);
3202        }
3203    }
3204
3205    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3206            ActivityRecord parent, final String annotation) {
3207        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3208        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3209
3210        if (mController != null) {
3211            try {
3212                // 0 == continue, -1 = kill process immediately
3213                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3214                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3215            } catch (RemoteException e) {
3216                mController = null;
3217            }
3218        }
3219
3220        long anrTime = SystemClock.uptimeMillis();
3221        if (MONITOR_CPU_USAGE) {
3222            updateCpuStatsNow();
3223        }
3224
3225        synchronized (this) {
3226            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3227            if (mShuttingDown) {
3228                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3229                return;
3230            } else if (app.notResponding) {
3231                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3232                return;
3233            } else if (app.crashing) {
3234                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3235                return;
3236            }
3237
3238            // In case we come through here for the same app before completing
3239            // this one, mark as anring now so we will bail out.
3240            app.notResponding = true;
3241
3242            // Log the ANR to the event log.
3243            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3244                    annotation);
3245
3246            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3247            firstPids.add(app.pid);
3248
3249            int parentPid = app.pid;
3250            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3251            if (parentPid != app.pid) firstPids.add(parentPid);
3252
3253            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3254
3255            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3256                ProcessRecord r = mLruProcesses.get(i);
3257                if (r != null && r.thread != null) {
3258                    int pid = r.pid;
3259                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3260                        if (r.persistent) {
3261                            firstPids.add(pid);
3262                        } else {
3263                            lastPids.put(pid, Boolean.TRUE);
3264                        }
3265                    }
3266                }
3267            }
3268        }
3269
3270        // Log the ANR to the main log.
3271        StringBuilder info = new StringBuilder();
3272        info.setLength(0);
3273        info.append("ANR in ").append(app.processName);
3274        if (activity != null && activity.shortComponentName != null) {
3275            info.append(" (").append(activity.shortComponentName).append(")");
3276        }
3277        info.append("\n");
3278        if (annotation != null) {
3279            info.append("Reason: ").append(annotation).append("\n");
3280        }
3281        if (parent != null && parent != activity) {
3282            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3283        }
3284
3285        final ProcessStats processStats = new ProcessStats(true);
3286
3287        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3288
3289        String cpuInfo = null;
3290        if (MONITOR_CPU_USAGE) {
3291            updateCpuStatsNow();
3292            synchronized (mProcessStatsThread) {
3293                cpuInfo = mProcessStats.printCurrentState(anrTime);
3294            }
3295            info.append(processStats.printCurrentLoad());
3296            info.append(cpuInfo);
3297        }
3298
3299        info.append(processStats.printCurrentState(anrTime));
3300
3301        Slog.e(TAG, info.toString());
3302        if (tracesFile == null) {
3303            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3304            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3305        }
3306
3307        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3308                cpuInfo, tracesFile, null);
3309
3310        if (mController != null) {
3311            try {
3312                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3313                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3314                if (res != 0) {
3315                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3316                    return;
3317                }
3318            } catch (RemoteException e) {
3319                mController = null;
3320            }
3321        }
3322
3323        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3324        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3325                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3326
3327        synchronized (this) {
3328            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3329                Slog.w(TAG, "Killing " + app + ": background ANR");
3330                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3331                        app.processName, app.setAdj, "background ANR");
3332                Process.killProcessQuiet(app.pid);
3333                return;
3334            }
3335
3336            // Set the app's notResponding state, and look up the errorReportReceiver
3337            makeAppNotRespondingLocked(app,
3338                    activity != null ? activity.shortComponentName : null,
3339                    annotation != null ? "ANR " + annotation : "ANR",
3340                    info.toString());
3341
3342            // Bring up the infamous App Not Responding dialog
3343            Message msg = Message.obtain();
3344            HashMap map = new HashMap();
3345            msg.what = SHOW_NOT_RESPONDING_MSG;
3346            msg.obj = map;
3347            map.put("app", app);
3348            if (activity != null) {
3349                map.put("activity", activity);
3350            }
3351
3352            mHandler.sendMessage(msg);
3353        }
3354    }
3355
3356    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3357        if (!mLaunchWarningShown) {
3358            mLaunchWarningShown = true;
3359            mHandler.post(new Runnable() {
3360                @Override
3361                public void run() {
3362                    synchronized (ActivityManagerService.this) {
3363                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3364                        d.show();
3365                        mHandler.postDelayed(new Runnable() {
3366                            @Override
3367                            public void run() {
3368                                synchronized (ActivityManagerService.this) {
3369                                    d.dismiss();
3370                                    mLaunchWarningShown = false;
3371                                }
3372                            }
3373                        }, 4000);
3374                    }
3375                }
3376            });
3377        }
3378    }
3379
3380    public boolean clearApplicationUserData(final String packageName,
3381            final IPackageDataObserver observer, final int userId) {
3382        enforceNotIsolatedCaller("clearApplicationUserData");
3383        int uid = Binder.getCallingUid();
3384        int pid = Binder.getCallingPid();
3385        long callingId = Binder.clearCallingIdentity();
3386        try {
3387            IPackageManager pm = AppGlobals.getPackageManager();
3388            int pkgUid = -1;
3389            synchronized(this) {
3390                try {
3391                    pkgUid = pm.getPackageUid(packageName, userId);
3392                } catch (RemoteException e) {
3393                }
3394                if (pkgUid == -1) {
3395                    Slog.w(TAG, "Invalid packageName:" + packageName);
3396                    return false;
3397                }
3398                if (uid == pkgUid || checkComponentPermission(
3399                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3400                        pid, uid, -1, true)
3401                        == PackageManager.PERMISSION_GRANTED) {
3402                    forceStopPackageLocked(packageName, pkgUid);
3403                } else {
3404                    throw new SecurityException(pid+" does not have permission:"+
3405                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3406                                    "for process:"+packageName);
3407                }
3408            }
3409
3410            try {
3411                //clear application user data
3412                pm.clearApplicationUserData(packageName, observer, userId);
3413                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3414                        Uri.fromParts("package", packageName, null));
3415                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3416                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3417                        null, null, 0, null, null, null, false, false, userId);
3418            } catch (RemoteException e) {
3419            }
3420        } finally {
3421            Binder.restoreCallingIdentity(callingId);
3422        }
3423        return true;
3424    }
3425
3426    public void killBackgroundProcesses(final String packageName) {
3427        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3428                != PackageManager.PERMISSION_GRANTED &&
3429                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3430                        != PackageManager.PERMISSION_GRANTED) {
3431            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3432                    + Binder.getCallingPid()
3433                    + ", uid=" + Binder.getCallingUid()
3434                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3435            Slog.w(TAG, msg);
3436            throw new SecurityException(msg);
3437        }
3438
3439        int userId = UserHandle.getCallingUserId();
3440        long callingId = Binder.clearCallingIdentity();
3441        try {
3442            IPackageManager pm = AppGlobals.getPackageManager();
3443            int pkgUid = -1;
3444            synchronized(this) {
3445                try {
3446                    pkgUid = pm.getPackageUid(packageName, userId);
3447                } catch (RemoteException e) {
3448                }
3449                if (pkgUid == -1) {
3450                    Slog.w(TAG, "Invalid packageName: " + packageName);
3451                    return;
3452                }
3453                killPackageProcessesLocked(packageName, pkgUid,
3454                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3455            }
3456        } finally {
3457            Binder.restoreCallingIdentity(callingId);
3458        }
3459    }
3460
3461    public void killAllBackgroundProcesses() {
3462        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3463                != PackageManager.PERMISSION_GRANTED) {
3464            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3465                    + Binder.getCallingPid()
3466                    + ", uid=" + Binder.getCallingUid()
3467                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3468            Slog.w(TAG, msg);
3469            throw new SecurityException(msg);
3470        }
3471
3472        long callingId = Binder.clearCallingIdentity();
3473        try {
3474            synchronized(this) {
3475                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3476                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3477                    final int NA = apps.size();
3478                    for (int ia=0; ia<NA; ia++) {
3479                        ProcessRecord app = apps.valueAt(ia);
3480                        if (app.persistent) {
3481                            // we don't kill persistent processes
3482                            continue;
3483                        }
3484                        if (app.removed) {
3485                            procs.add(app);
3486                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3487                            app.removed = true;
3488                            procs.add(app);
3489                        }
3490                    }
3491                }
3492
3493                int N = procs.size();
3494                for (int i=0; i<N; i++) {
3495                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3496                }
3497            }
3498        } finally {
3499            Binder.restoreCallingIdentity(callingId);
3500        }
3501    }
3502
3503    public void forceStopPackage(final String packageName) {
3504        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3505                != PackageManager.PERMISSION_GRANTED) {
3506            String msg = "Permission Denial: forceStopPackage() from pid="
3507                    + Binder.getCallingPid()
3508                    + ", uid=" + Binder.getCallingUid()
3509                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3510            Slog.w(TAG, msg);
3511            throw new SecurityException(msg);
3512        }
3513        final int userId = UserHandle.getCallingUserId();
3514        long callingId = Binder.clearCallingIdentity();
3515        try {
3516            IPackageManager pm = AppGlobals.getPackageManager();
3517            int pkgUid = -1;
3518            synchronized(this) {
3519                try {
3520                    pkgUid = pm.getPackageUid(packageName, userId);
3521                } catch (RemoteException e) {
3522                }
3523                if (pkgUid == -1) {
3524                    Slog.w(TAG, "Invalid packageName: " + packageName);
3525                    return;
3526                }
3527                forceStopPackageLocked(packageName, pkgUid);
3528                try {
3529                    pm.setPackageStoppedState(packageName, true, userId);
3530                } catch (RemoteException e) {
3531                } catch (IllegalArgumentException e) {
3532                    Slog.w(TAG, "Failed trying to unstop package "
3533                            + packageName + ": " + e);
3534                }
3535            }
3536        } finally {
3537            Binder.restoreCallingIdentity(callingId);
3538        }
3539    }
3540
3541    /*
3542     * The pkg name and uid have to be specified.
3543     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3544     */
3545    public void killApplicationWithUid(String pkg, int uid) {
3546        if (pkg == null) {
3547            return;
3548        }
3549        // Make sure the uid is valid.
3550        if (uid < 0) {
3551            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3552            return;
3553        }
3554        int callerUid = Binder.getCallingUid();
3555        // Only the system server can kill an application
3556        if (callerUid == Process.SYSTEM_UID) {
3557            // Post an aysnc message to kill the application
3558            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3559            msg.arg1 = uid;
3560            msg.arg2 = 0;
3561            msg.obj = pkg;
3562            mHandler.sendMessage(msg);
3563        } else {
3564            throw new SecurityException(callerUid + " cannot kill pkg: " +
3565                    pkg);
3566        }
3567    }
3568
3569    public void closeSystemDialogs(String reason) {
3570        enforceNotIsolatedCaller("closeSystemDialogs");
3571
3572        final int uid = Binder.getCallingUid();
3573        final long origId = Binder.clearCallingIdentity();
3574        synchronized (this) {
3575            closeSystemDialogsLocked(uid, reason);
3576        }
3577        Binder.restoreCallingIdentity(origId);
3578    }
3579
3580    void closeSystemDialogsLocked(int callingUid, String reason) {
3581        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3582        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3583        if (reason != null) {
3584            intent.putExtra("reason", reason);
3585        }
3586        mWindowManager.closeSystemDialogs(reason);
3587
3588        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3589            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3590            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3591                r.stack.finishActivityLocked(r, i,
3592                        Activity.RESULT_CANCELED, null, "close-sys");
3593            }
3594        }
3595
3596        broadcastIntentLocked(null, null, intent, null,
3597                null, 0, null, null, null, false, false, -1,
3598                callingUid, 0 /* TODO: Verify */);
3599    }
3600
3601    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3602            throws RemoteException {
3603        enforceNotIsolatedCaller("getProcessMemoryInfo");
3604        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3605        for (int i=pids.length-1; i>=0; i--) {
3606            infos[i] = new Debug.MemoryInfo();
3607            Debug.getMemoryInfo(pids[i], infos[i]);
3608        }
3609        return infos;
3610    }
3611
3612    public long[] getProcessPss(int[] pids) throws RemoteException {
3613        enforceNotIsolatedCaller("getProcessPss");
3614        long[] pss = new long[pids.length];
3615        for (int i=pids.length-1; i>=0; i--) {
3616            pss[i] = Debug.getPss(pids[i]);
3617        }
3618        return pss;
3619    }
3620
3621    public void killApplicationProcess(String processName, int uid) {
3622        if (processName == null) {
3623            return;
3624        }
3625
3626        int callerUid = Binder.getCallingUid();
3627        // Only the system server can kill an application
3628        if (callerUid == Process.SYSTEM_UID) {
3629            synchronized (this) {
3630                ProcessRecord app = getProcessRecordLocked(processName, uid);
3631                if (app != null && app.thread != null) {
3632                    try {
3633                        app.thread.scheduleSuicide();
3634                    } catch (RemoteException e) {
3635                        // If the other end already died, then our work here is done.
3636                    }
3637                } else {
3638                    Slog.w(TAG, "Process/uid not found attempting kill of "
3639                            + processName + " / " + uid);
3640                }
3641            }
3642        } else {
3643            throw new SecurityException(callerUid + " cannot kill app process: " +
3644                    processName);
3645        }
3646    }
3647
3648    private void forceStopPackageLocked(final String packageName, int uid) {
3649        forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
3650        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3651                Uri.fromParts("package", packageName, null));
3652        if (!mProcessesReady) {
3653            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3654        }
3655        intent.putExtra(Intent.EXTRA_UID, uid);
3656        broadcastIntentLocked(null, null, intent,
3657                null, null, 0, null, null, null,
3658                false, false,
3659                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3660    }
3661
3662    private final boolean killPackageProcessesLocked(String packageName, int uid,
3663            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3664            boolean evenPersistent, String reason) {
3665        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3666
3667        // Remove all processes this package may have touched: all with the
3668        // same UID (except for the system or root user), and all whose name
3669        // matches the package name.
3670        final String procNamePrefix = packageName + ":";
3671        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3672            final int NA = apps.size();
3673            for (int ia=0; ia<NA; ia++) {
3674                ProcessRecord app = apps.valueAt(ia);
3675                if (app.persistent && !evenPersistent) {
3676                    // we don't kill persistent processes
3677                    continue;
3678                }
3679                if (app.removed) {
3680                    if (doit) {
3681                        procs.add(app);
3682                    }
3683                // If uid is specified and the uid and process name match
3684                // Or, the uid is not specified and the process name matches
3685                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3686                            || ((app.processName.equals(packageName)
3687                                 || app.processName.startsWith(procNamePrefix))
3688                                && uid < 0))) {
3689                    if (app.setAdj >= minOomAdj) {
3690                        if (!doit) {
3691                            return true;
3692                        }
3693                        app.removed = true;
3694                        procs.add(app);
3695                    }
3696                }
3697            }
3698        }
3699
3700        int N = procs.size();
3701        for (int i=0; i<N; i++) {
3702            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3703        }
3704        return N > 0;
3705    }
3706
3707    private final boolean forceStopPackageLocked(String name, int uid,
3708            boolean callerWillRestart, boolean purgeCache, boolean doit,
3709            boolean evenPersistent, int userId) {
3710        int i;
3711        int N;
3712
3713        if (uid < 0) {
3714            try {
3715                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3716            } catch (RemoteException e) {
3717            }
3718        }
3719
3720        if (doit) {
3721            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3722
3723            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3724            while (badApps.hasNext()) {
3725                SparseArray<Long> ba = badApps.next();
3726                if (ba.get(uid) != null) {
3727                    badApps.remove();
3728                }
3729            }
3730        }
3731
3732        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3733                callerWillRestart, false, doit, evenPersistent, "force stop");
3734
3735        TaskRecord lastTask = null;
3736        for (i=0; i<mMainStack.mHistory.size(); i++) {
3737            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3738            final boolean samePackage = r.packageName.equals(name);
3739            if (r.userId == userId
3740                    && (samePackage || r.task == lastTask)
3741                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3742                if (!doit) {
3743                    if (r.finishing) {
3744                        // If this activity is just finishing, then it is not
3745                        // interesting as far as something to stop.
3746                        continue;
3747                    }
3748                    return true;
3749                }
3750                didSomething = true;
3751                Slog.i(TAG, "  Force finishing activity " + r);
3752                if (samePackage) {
3753                    if (r.app != null) {
3754                        r.app.removed = true;
3755                    }
3756                    r.app = null;
3757                }
3758                lastTask = r.task;
3759                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3760                        null, "force-stop", true)) {
3761                    i--;
3762                }
3763            }
3764        }
3765
3766        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3767            if (!doit) {
3768                return true;
3769            }
3770            didSomething = true;
3771        }
3772
3773        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3774        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3775            if (provider.info.packageName.equals(name)
3776                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3777                if (!doit) {
3778                    return true;
3779                }
3780                didSomething = true;
3781                providers.add(provider);
3782            }
3783        }
3784
3785        N = providers.size();
3786        for (i=0; i<N; i++) {
3787            removeDyingProviderLocked(null, providers.get(i), true);
3788        }
3789
3790        if (doit) {
3791            if (purgeCache) {
3792                AttributeCache ac = AttributeCache.instance();
3793                if (ac != null) {
3794                    ac.removePackage(name);
3795                }
3796            }
3797            if (mBooted) {
3798                mMainStack.resumeTopActivityLocked(null);
3799                mMainStack.scheduleIdleLocked();
3800            }
3801        }
3802
3803        return didSomething;
3804    }
3805
3806    private final boolean removeProcessLocked(ProcessRecord app,
3807            boolean callerWillRestart, boolean allowRestart, String reason) {
3808        final String name = app.processName;
3809        final int uid = app.uid;
3810        if (DEBUG_PROCESSES) Slog.d(
3811            TAG, "Force removing proc " + app.toShortString() + " (" + name
3812            + "/" + uid + ")");
3813
3814        mProcessNames.remove(name, uid);
3815        mIsolatedProcesses.remove(app.uid);
3816        if (mHeavyWeightProcess == app) {
3817            mHeavyWeightProcess = null;
3818            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3819        }
3820        boolean needRestart = false;
3821        if (app.pid > 0 && app.pid != MY_PID) {
3822            int pid = app.pid;
3823            synchronized (mPidsSelfLocked) {
3824                mPidsSelfLocked.remove(pid);
3825                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3826            }
3827            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3828            handleAppDiedLocked(app, true, allowRestart);
3829            mLruProcesses.remove(app);
3830            Process.killProcessQuiet(pid);
3831
3832            if (app.persistent && !app.isolated) {
3833                if (!callerWillRestart) {
3834                    addAppLocked(app.info, false);
3835                } else {
3836                    needRestart = true;
3837                }
3838            }
3839        } else {
3840            mRemovedProcesses.add(app);
3841        }
3842
3843        return needRestart;
3844    }
3845
3846    private final void processStartTimedOutLocked(ProcessRecord app) {
3847        final int pid = app.pid;
3848        boolean gone = false;
3849        synchronized (mPidsSelfLocked) {
3850            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3851            if (knownApp != null && knownApp.thread == null) {
3852                mPidsSelfLocked.remove(pid);
3853                gone = true;
3854            }
3855        }
3856
3857        if (gone) {
3858            Slog.w(TAG, "Process " + app + " failed to attach");
3859            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3860                    app.processName);
3861            mProcessNames.remove(app.processName, app.uid);
3862            mIsolatedProcesses.remove(app.uid);
3863            if (mHeavyWeightProcess == app) {
3864                mHeavyWeightProcess = null;
3865                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3866            }
3867            // Take care of any launching providers waiting for this process.
3868            checkAppInLaunchingProvidersLocked(app, true);
3869            // Take care of any services that are waiting for the process.
3870            mServices.processStartTimedOutLocked(app);
3871            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3872                    app.processName, app.setAdj, "start timeout");
3873            Process.killProcessQuiet(pid);
3874            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3875                Slog.w(TAG, "Unattached app died before backup, skipping");
3876                try {
3877                    IBackupManager bm = IBackupManager.Stub.asInterface(
3878                            ServiceManager.getService(Context.BACKUP_SERVICE));
3879                    bm.agentDisconnected(app.info.packageName);
3880                } catch (RemoteException e) {
3881                    // Can't happen; the backup manager is local
3882                }
3883            }
3884            if (isPendingBroadcastProcessLocked(pid)) {
3885                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3886                skipPendingBroadcastLocked(pid);
3887            }
3888        } else {
3889            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3890        }
3891    }
3892
3893    private final boolean attachApplicationLocked(IApplicationThread thread,
3894            int pid) {
3895
3896        // Find the application record that is being attached...  either via
3897        // the pid if we are running in multiple processes, or just pull the
3898        // next app record if we are emulating process with anonymous threads.
3899        ProcessRecord app;
3900        if (pid != MY_PID && pid >= 0) {
3901            synchronized (mPidsSelfLocked) {
3902                app = mPidsSelfLocked.get(pid);
3903            }
3904        } else {
3905            app = null;
3906        }
3907
3908        if (app == null) {
3909            Slog.w(TAG, "No pending application record for pid " + pid
3910                    + " (IApplicationThread " + thread + "); dropping process");
3911            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3912            if (pid > 0 && pid != MY_PID) {
3913                Process.killProcessQuiet(pid);
3914            } else {
3915                try {
3916                    thread.scheduleExit();
3917                } catch (Exception e) {
3918                    // Ignore exceptions.
3919                }
3920            }
3921            return false;
3922        }
3923
3924        // If this application record is still attached to a previous
3925        // process, clean it up now.
3926        if (app.thread != null) {
3927            handleAppDiedLocked(app, true, true);
3928        }
3929
3930        // Tell the process all about itself.
3931
3932        if (localLOGV) Slog.v(
3933                TAG, "Binding process pid " + pid + " to record " + app);
3934
3935        String processName = app.processName;
3936        try {
3937            AppDeathRecipient adr = new AppDeathRecipient(
3938                    app, pid, thread);
3939            thread.asBinder().linkToDeath(adr, 0);
3940            app.deathRecipient = adr;
3941        } catch (RemoteException e) {
3942            app.resetPackageList();
3943            startProcessLocked(app, "link fail", processName);
3944            return false;
3945        }
3946
3947        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3948
3949        app.thread = thread;
3950        app.curAdj = app.setAdj = -100;
3951        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3952        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3953        app.forcingToForeground = null;
3954        app.foregroundServices = false;
3955        app.hasShownUi = false;
3956        app.debugging = false;
3957
3958        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3959
3960        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3961        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3962
3963        if (!normalMode) {
3964            Slog.i(TAG, "Launching preboot mode app: " + app);
3965        }
3966
3967        if (localLOGV) Slog.v(
3968            TAG, "New app record " + app
3969            + " thread=" + thread.asBinder() + " pid=" + pid);
3970        try {
3971            int testMode = IApplicationThread.DEBUG_OFF;
3972            if (mDebugApp != null && mDebugApp.equals(processName)) {
3973                testMode = mWaitForDebugger
3974                    ? IApplicationThread.DEBUG_WAIT
3975                    : IApplicationThread.DEBUG_ON;
3976                app.debugging = true;
3977                if (mDebugTransient) {
3978                    mDebugApp = mOrigDebugApp;
3979                    mWaitForDebugger = mOrigWaitForDebugger;
3980                }
3981            }
3982            String profileFile = app.instrumentationProfileFile;
3983            ParcelFileDescriptor profileFd = null;
3984            boolean profileAutoStop = false;
3985            if (mProfileApp != null && mProfileApp.equals(processName)) {
3986                mProfileProc = app;
3987                profileFile = mProfileFile;
3988                profileFd = mProfileFd;
3989                profileAutoStop = mAutoStopProfiler;
3990            }
3991            boolean enableOpenGlTrace = false;
3992            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3993                enableOpenGlTrace = true;
3994                mOpenGlTraceApp = null;
3995            }
3996
3997            // If the app is being launched for restore or full backup, set it up specially
3998            boolean isRestrictedBackupMode = false;
3999            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4000                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4001                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4002                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4003            }
4004
4005            ensurePackageDexOpt(app.instrumentationInfo != null
4006                    ? app.instrumentationInfo.packageName
4007                    : app.info.packageName);
4008            if (app.instrumentationClass != null) {
4009                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4010            }
4011            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4012                    + processName + " with config " + mConfiguration);
4013            ApplicationInfo appInfo = app.instrumentationInfo != null
4014                    ? app.instrumentationInfo : app.info;
4015            app.compat = compatibilityInfoForPackageLocked(appInfo);
4016            if (profileFd != null) {
4017                profileFd = profileFd.dup();
4018            }
4019            thread.bindApplication(processName, appInfo, providers,
4020                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4021                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4022                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4023                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4024                    mCoreSettingsObserver.getCoreSettingsLocked());
4025            updateLruProcessLocked(app, false, true);
4026            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4027        } catch (Exception e) {
4028            // todo: Yikes!  What should we do?  For now we will try to
4029            // start another process, but that could easily get us in
4030            // an infinite loop of restarting processes...
4031            Slog.w(TAG, "Exception thrown during bind!", e);
4032
4033            app.resetPackageList();
4034            app.unlinkDeathRecipient();
4035            startProcessLocked(app, "bind fail", processName);
4036            return false;
4037        }
4038
4039        // Remove this record from the list of starting applications.
4040        mPersistentStartingProcesses.remove(app);
4041        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4042                "Attach application locked removing on hold: " + app);
4043        mProcessesOnHold.remove(app);
4044
4045        boolean badApp = false;
4046        boolean didSomething = false;
4047
4048        // See if the top visible activity is waiting to run in this process...
4049        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4050        if (hr != null && normalMode) {
4051            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4052                    && processName.equals(hr.processName)) {
4053                try {
4054                    if (mHeadless) {
4055                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4056                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4057                        didSomething = true;
4058                    }
4059                } catch (Exception e) {
4060                    Slog.w(TAG, "Exception in new application when starting activity "
4061                          + hr.intent.getComponent().flattenToShortString(), e);
4062                    badApp = true;
4063                }
4064            } else {
4065                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4066            }
4067        }
4068
4069        // Find any services that should be running in this process...
4070        if (!badApp) {
4071            try {
4072                didSomething |= mServices.attachApplicationLocked(app, processName);
4073            } catch (Exception e) {
4074                badApp = true;
4075            }
4076        }
4077
4078        // Check if a next-broadcast receiver is in this process...
4079        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4080            try {
4081                didSomething = sendPendingBroadcastsLocked(app);
4082            } catch (Exception e) {
4083                // If the app died trying to launch the receiver we declare it 'bad'
4084                badApp = true;
4085            }
4086        }
4087
4088        // Check whether the next backup agent is in this process...
4089        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4090            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4091            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4092            try {
4093                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4094                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4095                        mBackupTarget.backupMode);
4096            } catch (Exception e) {
4097                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4098                e.printStackTrace();
4099            }
4100        }
4101
4102        if (badApp) {
4103            // todo: Also need to kill application to deal with all
4104            // kinds of exceptions.
4105            handleAppDiedLocked(app, false, true);
4106            return false;
4107        }
4108
4109        if (!didSomething) {
4110            updateOomAdjLocked();
4111        }
4112
4113        return true;
4114    }
4115
4116    public final void attachApplication(IApplicationThread thread) {
4117        synchronized (this) {
4118            int callingPid = Binder.getCallingPid();
4119            final long origId = Binder.clearCallingIdentity();
4120            attachApplicationLocked(thread, callingPid);
4121            Binder.restoreCallingIdentity(origId);
4122        }
4123    }
4124
4125    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4126        final long origId = Binder.clearCallingIdentity();
4127        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4128        if (stopProfiling) {
4129            synchronized (this) {
4130                if (mProfileProc == r.app) {
4131                    if (mProfileFd != null) {
4132                        try {
4133                            mProfileFd.close();
4134                        } catch (IOException e) {
4135                        }
4136                        clearProfilerLocked();
4137                    }
4138                }
4139            }
4140        }
4141        Binder.restoreCallingIdentity(origId);
4142    }
4143
4144    void enableScreenAfterBoot() {
4145        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4146                SystemClock.uptimeMillis());
4147        mWindowManager.enableScreenAfterBoot();
4148
4149        synchronized (this) {
4150            updateEventDispatchingLocked();
4151        }
4152    }
4153
4154    public void showBootMessage(final CharSequence msg, final boolean always) {
4155        enforceNotIsolatedCaller("showBootMessage");
4156        mWindowManager.showBootMessage(msg, always);
4157    }
4158
4159    public void dismissKeyguardOnNextActivity() {
4160        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4161        final long token = Binder.clearCallingIdentity();
4162        try {
4163            synchronized (this) {
4164                if (mLockScreenShown) {
4165                    mLockScreenShown = false;
4166                    comeOutOfSleepIfNeededLocked();
4167                }
4168                mMainStack.dismissKeyguardOnNextActivityLocked();
4169            }
4170        } finally {
4171            Binder.restoreCallingIdentity(token);
4172        }
4173    }
4174
4175    final void finishBooting() {
4176        IntentFilter pkgFilter = new IntentFilter();
4177        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4178        pkgFilter.addDataScheme("package");
4179        mContext.registerReceiver(new BroadcastReceiver() {
4180            @Override
4181            public void onReceive(Context context, Intent intent) {
4182                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4183                if (pkgs != null) {
4184                    for (String pkg : pkgs) {
4185                        synchronized (ActivityManagerService.this) {
4186                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4187                                setResultCode(Activity.RESULT_OK);
4188                                return;
4189                            }
4190                        }
4191                    }
4192                }
4193            }
4194        }, pkgFilter);
4195
4196        IntentFilter userFilter = new IntentFilter();
4197        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4198        mContext.registerReceiver(new BroadcastReceiver() {
4199            @Override
4200            public void onReceive(Context context, Intent intent) {
4201                onUserRemoved(intent);
4202            }
4203        }, userFilter);
4204
4205        synchronized (this) {
4206            // Ensure that any processes we had put on hold are now started
4207            // up.
4208            final int NP = mProcessesOnHold.size();
4209            if (NP > 0) {
4210                ArrayList<ProcessRecord> procs =
4211                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4212                for (int ip=0; ip<NP; ip++) {
4213                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4214                            + procs.get(ip));
4215                    startProcessLocked(procs.get(ip), "on-hold", null);
4216                }
4217            }
4218
4219            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4220                // Start looking for apps that are abusing wake locks.
4221                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4222                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4223                // Tell anyone interested that we are done booting!
4224                SystemProperties.set("sys.boot_completed", "1");
4225                SystemProperties.set("dev.bootcomplete", "1");
4226                List<UserInfo> users = getUserManager().getUsers();
4227                for (UserInfo user : users) {
4228                    broadcastIntentLocked(null, null,
4229                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4230                            null, null, 0, null, null,
4231                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4232                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4233                }
4234            }
4235        }
4236    }
4237
4238    final void ensureBootCompleted() {
4239        boolean booting;
4240        boolean enableScreen;
4241        synchronized (this) {
4242            booting = mBooting;
4243            mBooting = false;
4244            enableScreen = !mBooted;
4245            mBooted = true;
4246        }
4247
4248        if (booting) {
4249            finishBooting();
4250        }
4251
4252        if (enableScreen) {
4253            enableScreenAfterBoot();
4254        }
4255    }
4256
4257    public final void activityPaused(IBinder token) {
4258        final long origId = Binder.clearCallingIdentity();
4259        mMainStack.activityPaused(token, false);
4260        Binder.restoreCallingIdentity(origId);
4261    }
4262
4263    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4264            CharSequence description) {
4265        if (localLOGV) Slog.v(
4266            TAG, "Activity stopped: token=" + token);
4267
4268        // Refuse possible leaked file descriptors
4269        if (icicle != null && icicle.hasFileDescriptors()) {
4270            throw new IllegalArgumentException("File descriptors passed in Bundle");
4271        }
4272
4273        ActivityRecord r = null;
4274
4275        final long origId = Binder.clearCallingIdentity();
4276
4277        synchronized (this) {
4278            r = mMainStack.isInStackLocked(token);
4279            if (r != null) {
4280                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4281            }
4282        }
4283
4284        if (r != null) {
4285            sendPendingThumbnail(r, null, null, null, false);
4286        }
4287
4288        trimApplications();
4289
4290        Binder.restoreCallingIdentity(origId);
4291    }
4292
4293    public final void activityDestroyed(IBinder token) {
4294        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4295        mMainStack.activityDestroyed(token);
4296    }
4297
4298    public String getCallingPackage(IBinder token) {
4299        synchronized (this) {
4300            ActivityRecord r = getCallingRecordLocked(token);
4301            return r != null && r.app != null ? r.info.packageName : null;
4302        }
4303    }
4304
4305    public ComponentName getCallingActivity(IBinder token) {
4306        synchronized (this) {
4307            ActivityRecord r = getCallingRecordLocked(token);
4308            return r != null ? r.intent.getComponent() : null;
4309        }
4310    }
4311
4312    private ActivityRecord getCallingRecordLocked(IBinder token) {
4313        ActivityRecord r = mMainStack.isInStackLocked(token);
4314        if (r == null) {
4315            return null;
4316        }
4317        return r.resultTo;
4318    }
4319
4320    public ComponentName getActivityClassForToken(IBinder token) {
4321        synchronized(this) {
4322            ActivityRecord r = mMainStack.isInStackLocked(token);
4323            if (r == null) {
4324                return null;
4325            }
4326            return r.intent.getComponent();
4327        }
4328    }
4329
4330    public String getPackageForToken(IBinder token) {
4331        synchronized(this) {
4332            ActivityRecord r = mMainStack.isInStackLocked(token);
4333            if (r == null) {
4334                return null;
4335            }
4336            return r.packageName;
4337        }
4338    }
4339
4340    public IIntentSender getIntentSender(int type,
4341            String packageName, IBinder token, String resultWho,
4342            int requestCode, Intent[] intents, String[] resolvedTypes,
4343            int flags, Bundle options) {
4344        enforceNotIsolatedCaller("getIntentSender");
4345        // Refuse possible leaked file descriptors
4346        if (intents != null) {
4347            if (intents.length < 1) {
4348                throw new IllegalArgumentException("Intents array length must be >= 1");
4349            }
4350            for (int i=0; i<intents.length; i++) {
4351                Intent intent = intents[i];
4352                if (intent != null) {
4353                    if (intent.hasFileDescriptors()) {
4354                        throw new IllegalArgumentException("File descriptors passed in Intent");
4355                    }
4356                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4357                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4358                        throw new IllegalArgumentException(
4359                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4360                    }
4361                    intents[i] = new Intent(intent);
4362                }
4363            }
4364            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4365                throw new IllegalArgumentException(
4366                        "Intent array length does not match resolvedTypes length");
4367            }
4368        }
4369        if (options != null) {
4370            if (options.hasFileDescriptors()) {
4371                throw new IllegalArgumentException("File descriptors passed in options");
4372            }
4373        }
4374
4375        synchronized(this) {
4376            int callingUid = Binder.getCallingUid();
4377            try {
4378                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4379                    int uid = AppGlobals.getPackageManager()
4380                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4381                    if (!UserHandle.isSameApp(callingUid, uid)) {
4382                        String msg = "Permission Denial: getIntentSender() from pid="
4383                            + Binder.getCallingPid()
4384                            + ", uid=" + Binder.getCallingUid()
4385                            + ", (need uid=" + uid + ")"
4386                            + " is not allowed to send as package " + packageName;
4387                        Slog.w(TAG, msg);
4388                        throw new SecurityException(msg);
4389                    }
4390                }
4391
4392                if (DEBUG_MU)
4393                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4394                            + Binder.getOrigCallingUid());
4395                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4396                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4397
4398            } catch (RemoteException e) {
4399                throw new SecurityException(e);
4400            }
4401        }
4402    }
4403
4404    IIntentSender getIntentSenderLocked(int type,
4405            String packageName, int callingUid, IBinder token, String resultWho,
4406            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4407            Bundle options) {
4408        if (DEBUG_MU)
4409            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4410        ActivityRecord activity = null;
4411        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4412            activity = mMainStack.isInStackLocked(token);
4413            if (activity == null) {
4414                return null;
4415            }
4416            if (activity.finishing) {
4417                return null;
4418            }
4419        }
4420
4421        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4422        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4423        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4424        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4425                |PendingIntent.FLAG_UPDATE_CURRENT);
4426
4427        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4428                type, packageName, activity, resultWho,
4429                requestCode, intents, resolvedTypes, flags, options);
4430        WeakReference<PendingIntentRecord> ref;
4431        ref = mIntentSenderRecords.get(key);
4432        PendingIntentRecord rec = ref != null ? ref.get() : null;
4433        if (rec != null) {
4434            if (!cancelCurrent) {
4435                if (updateCurrent) {
4436                    if (rec.key.requestIntent != null) {
4437                        rec.key.requestIntent.replaceExtras(intents != null ?
4438                                intents[intents.length - 1] : null);
4439                    }
4440                    if (intents != null) {
4441                        intents[intents.length-1] = rec.key.requestIntent;
4442                        rec.key.allIntents = intents;
4443                        rec.key.allResolvedTypes = resolvedTypes;
4444                    } else {
4445                        rec.key.allIntents = null;
4446                        rec.key.allResolvedTypes = null;
4447                    }
4448                }
4449                return rec;
4450            }
4451            rec.canceled = true;
4452            mIntentSenderRecords.remove(key);
4453        }
4454        if (noCreate) {
4455            return rec;
4456        }
4457        rec = new PendingIntentRecord(this, key, callingUid);
4458        mIntentSenderRecords.put(key, rec.ref);
4459        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4460            if (activity.pendingResults == null) {
4461                activity.pendingResults
4462                        = new HashSet<WeakReference<PendingIntentRecord>>();
4463            }
4464            activity.pendingResults.add(rec.ref);
4465        }
4466        return rec;
4467    }
4468
4469    public void cancelIntentSender(IIntentSender sender) {
4470        if (!(sender instanceof PendingIntentRecord)) {
4471            return;
4472        }
4473        synchronized(this) {
4474            PendingIntentRecord rec = (PendingIntentRecord)sender;
4475            try {
4476                int uid = AppGlobals.getPackageManager()
4477                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4478                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4479                    String msg = "Permission Denial: cancelIntentSender() from pid="
4480                        + Binder.getCallingPid()
4481                        + ", uid=" + Binder.getCallingUid()
4482                        + " is not allowed to cancel packges "
4483                        + rec.key.packageName;
4484                    Slog.w(TAG, msg);
4485                    throw new SecurityException(msg);
4486                }
4487            } catch (RemoteException e) {
4488                throw new SecurityException(e);
4489            }
4490            cancelIntentSenderLocked(rec, true);
4491        }
4492    }
4493
4494    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4495        rec.canceled = true;
4496        mIntentSenderRecords.remove(rec.key);
4497        if (cleanActivity && rec.key.activity != null) {
4498            rec.key.activity.pendingResults.remove(rec.ref);
4499        }
4500    }
4501
4502    public String getPackageForIntentSender(IIntentSender pendingResult) {
4503        if (!(pendingResult instanceof PendingIntentRecord)) {
4504            return null;
4505        }
4506        try {
4507            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4508            return res.key.packageName;
4509        } catch (ClassCastException e) {
4510        }
4511        return null;
4512    }
4513
4514    public int getUidForIntentSender(IIntentSender sender) {
4515        if (sender instanceof PendingIntentRecord) {
4516            try {
4517                PendingIntentRecord res = (PendingIntentRecord)sender;
4518                return res.uid;
4519            } catch (ClassCastException e) {
4520            }
4521        }
4522        return -1;
4523    }
4524
4525    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4526        if (!(pendingResult instanceof PendingIntentRecord)) {
4527            return false;
4528        }
4529        try {
4530            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4531            if (res.key.allIntents == null) {
4532                return false;
4533            }
4534            for (int i=0; i<res.key.allIntents.length; i++) {
4535                Intent intent = res.key.allIntents[i];
4536                if (intent.getPackage() != null && intent.getComponent() != null) {
4537                    return false;
4538                }
4539            }
4540            return true;
4541        } catch (ClassCastException e) {
4542        }
4543        return false;
4544    }
4545
4546    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4547        if (!(pendingResult instanceof PendingIntentRecord)) {
4548            return false;
4549        }
4550        try {
4551            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4552            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4553                return true;
4554            }
4555            return false;
4556        } catch (ClassCastException e) {
4557        }
4558        return false;
4559    }
4560
4561    public void setProcessLimit(int max) {
4562        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4563                "setProcessLimit()");
4564        synchronized (this) {
4565            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4566            mProcessLimitOverride = max;
4567        }
4568        trimApplications();
4569    }
4570
4571    public int getProcessLimit() {
4572        synchronized (this) {
4573            return mProcessLimitOverride;
4574        }
4575    }
4576
4577    void foregroundTokenDied(ForegroundToken token) {
4578        synchronized (ActivityManagerService.this) {
4579            synchronized (mPidsSelfLocked) {
4580                ForegroundToken cur
4581                    = mForegroundProcesses.get(token.pid);
4582                if (cur != token) {
4583                    return;
4584                }
4585                mForegroundProcesses.remove(token.pid);
4586                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4587                if (pr == null) {
4588                    return;
4589                }
4590                pr.forcingToForeground = null;
4591                pr.foregroundServices = false;
4592            }
4593            updateOomAdjLocked();
4594        }
4595    }
4596
4597    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4598        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4599                "setProcessForeground()");
4600        synchronized(this) {
4601            boolean changed = false;
4602
4603            synchronized (mPidsSelfLocked) {
4604                ProcessRecord pr = mPidsSelfLocked.get(pid);
4605                if (pr == null && isForeground) {
4606                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4607                    return;
4608                }
4609                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4610                if (oldToken != null) {
4611                    oldToken.token.unlinkToDeath(oldToken, 0);
4612                    mForegroundProcesses.remove(pid);
4613                    if (pr != null) {
4614                        pr.forcingToForeground = null;
4615                    }
4616                    changed = true;
4617                }
4618                if (isForeground && token != null) {
4619                    ForegroundToken newToken = new ForegroundToken() {
4620                        public void binderDied() {
4621                            foregroundTokenDied(this);
4622                        }
4623                    };
4624                    newToken.pid = pid;
4625                    newToken.token = token;
4626                    try {
4627                        token.linkToDeath(newToken, 0);
4628                        mForegroundProcesses.put(pid, newToken);
4629                        pr.forcingToForeground = token;
4630                        changed = true;
4631                    } catch (RemoteException e) {
4632                        // If the process died while doing this, we will later
4633                        // do the cleanup with the process death link.
4634                    }
4635                }
4636            }
4637
4638            if (changed) {
4639                updateOomAdjLocked();
4640            }
4641        }
4642    }
4643
4644    // =========================================================
4645    // PERMISSIONS
4646    // =========================================================
4647
4648    static class PermissionController extends IPermissionController.Stub {
4649        ActivityManagerService mActivityManagerService;
4650        PermissionController(ActivityManagerService activityManagerService) {
4651            mActivityManagerService = activityManagerService;
4652        }
4653
4654        public boolean checkPermission(String permission, int pid, int uid) {
4655            return mActivityManagerService.checkPermission(permission, pid,
4656                    uid) == PackageManager.PERMISSION_GRANTED;
4657        }
4658    }
4659
4660    /**
4661     * This can be called with or without the global lock held.
4662     */
4663    int checkComponentPermission(String permission, int pid, int uid,
4664            int owningUid, boolean exported) {
4665        // We might be performing an operation on behalf of an indirect binder
4666        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4667        // client identity accordingly before proceeding.
4668        Identity tlsIdentity = sCallerIdentity.get();
4669        if (tlsIdentity != null) {
4670            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4671                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4672            uid = tlsIdentity.uid;
4673            pid = tlsIdentity.pid;
4674        }
4675
4676        if (pid == MY_PID) {
4677            return PackageManager.PERMISSION_GRANTED;
4678        }
4679
4680        return ActivityManager.checkComponentPermission(permission, uid,
4681                owningUid, exported);
4682    }
4683
4684    /**
4685     * As the only public entry point for permissions checking, this method
4686     * can enforce the semantic that requesting a check on a null global
4687     * permission is automatically denied.  (Internally a null permission
4688     * string is used when calling {@link #checkComponentPermission} in cases
4689     * when only uid-based security is needed.)
4690     *
4691     * This can be called with or without the global lock held.
4692     */
4693    public int checkPermission(String permission, int pid, int uid) {
4694        if (permission == null) {
4695            return PackageManager.PERMISSION_DENIED;
4696        }
4697        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4698    }
4699
4700    /**
4701     * Binder IPC calls go through the public entry point.
4702     * This can be called with or without the global lock held.
4703     */
4704    int checkCallingPermission(String permission) {
4705        return checkPermission(permission,
4706                Binder.getCallingPid(),
4707                UserHandle.getAppId(Binder.getCallingUid()));
4708    }
4709
4710    /**
4711     * This can be called with or without the global lock held.
4712     */
4713    void enforceCallingPermission(String permission, String func) {
4714        if (checkCallingPermission(permission)
4715                == PackageManager.PERMISSION_GRANTED) {
4716            return;
4717        }
4718
4719        String msg = "Permission Denial: " + func + " from pid="
4720                + Binder.getCallingPid()
4721                + ", uid=" + Binder.getCallingUid()
4722                + " requires " + permission;
4723        Slog.w(TAG, msg);
4724        throw new SecurityException(msg);
4725    }
4726
4727    /**
4728     * Determine if UID is holding permissions required to access {@link Uri} in
4729     * the given {@link ProviderInfo}. Final permission checking is always done
4730     * in {@link ContentProvider}.
4731     */
4732    private final boolean checkHoldingPermissionsLocked(
4733            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4734        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4735                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4736
4737        if (pi.applicationInfo.uid == uid) {
4738            return true;
4739        } else if (!pi.exported) {
4740            return false;
4741        }
4742
4743        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4744        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4745        try {
4746            // check if target holds top-level <provider> permissions
4747            if (!readMet && pi.readPermission != null
4748                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4749                readMet = true;
4750            }
4751            if (!writeMet && pi.writePermission != null
4752                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4753                writeMet = true;
4754            }
4755
4756            // track if unprotected read/write is allowed; any denied
4757            // <path-permission> below removes this ability
4758            boolean allowDefaultRead = pi.readPermission == null;
4759            boolean allowDefaultWrite = pi.writePermission == null;
4760
4761            // check if target holds any <path-permission> that match uri
4762            final PathPermission[] pps = pi.pathPermissions;
4763            if (pps != null) {
4764                final String path = uri.getPath();
4765                int i = pps.length;
4766                while (i > 0 && (!readMet || !writeMet)) {
4767                    i--;
4768                    PathPermission pp = pps[i];
4769                    if (pp.match(path)) {
4770                        if (!readMet) {
4771                            final String pprperm = pp.getReadPermission();
4772                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4773                                    + pprperm + " for " + pp.getPath()
4774                                    + ": match=" + pp.match(path)
4775                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4776                            if (pprperm != null) {
4777                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4778                                    readMet = true;
4779                                } else {
4780                                    allowDefaultRead = false;
4781                                }
4782                            }
4783                        }
4784                        if (!writeMet) {
4785                            final String ppwperm = pp.getWritePermission();
4786                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4787                                    + ppwperm + " for " + pp.getPath()
4788                                    + ": match=" + pp.match(path)
4789                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4790                            if (ppwperm != null) {
4791                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4792                                    writeMet = true;
4793                                } else {
4794                                    allowDefaultWrite = false;
4795                                }
4796                            }
4797                        }
4798                    }
4799                }
4800            }
4801
4802            // grant unprotected <provider> read/write, if not blocked by
4803            // <path-permission> above
4804            if (allowDefaultRead) readMet = true;
4805            if (allowDefaultWrite) writeMet = true;
4806
4807        } catch (RemoteException e) {
4808            return false;
4809        }
4810
4811        return readMet && writeMet;
4812    }
4813
4814    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4815            int modeFlags) {
4816        // Root gets to do everything.
4817        if (uid == 0) {
4818            return true;
4819        }
4820        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4821        if (perms == null) return false;
4822        UriPermission perm = perms.get(uri);
4823        if (perm == null) return false;
4824        return (modeFlags&perm.modeFlags) == modeFlags;
4825    }
4826
4827    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4828        enforceNotIsolatedCaller("checkUriPermission");
4829
4830        // Another redirected-binder-call permissions check as in
4831        // {@link checkComponentPermission}.
4832        Identity tlsIdentity = sCallerIdentity.get();
4833        if (tlsIdentity != null) {
4834            uid = tlsIdentity.uid;
4835            pid = tlsIdentity.pid;
4836        }
4837
4838        uid = UserHandle.getAppId(uid);
4839        // Our own process gets to do everything.
4840        if (pid == MY_PID) {
4841            return PackageManager.PERMISSION_GRANTED;
4842        }
4843        synchronized(this) {
4844            return checkUriPermissionLocked(uri, uid, modeFlags)
4845                    ? PackageManager.PERMISSION_GRANTED
4846                    : PackageManager.PERMISSION_DENIED;
4847        }
4848    }
4849
4850    /**
4851     * Check if the targetPkg can be granted permission to access uri by
4852     * the callingUid using the given modeFlags.  Throws a security exception
4853     * if callingUid is not allowed to do this.  Returns the uid of the target
4854     * if the URI permission grant should be performed; returns -1 if it is not
4855     * needed (for example targetPkg already has permission to access the URI).
4856     * If you already know the uid of the target, you can supply it in
4857     * lastTargetUid else set that to -1.
4858     */
4859    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4860            Uri uri, int modeFlags, int lastTargetUid) {
4861        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4862                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4863        if (modeFlags == 0) {
4864            return -1;
4865        }
4866
4867        if (targetPkg != null) {
4868            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4869                    "Checking grant " + targetPkg + " permission to " + uri);
4870        }
4871
4872        final IPackageManager pm = AppGlobals.getPackageManager();
4873
4874        // If this is not a content: uri, we can't do anything with it.
4875        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4876            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4877                    "Can't grant URI permission for non-content URI: " + uri);
4878            return -1;
4879        }
4880
4881        String name = uri.getAuthority();
4882        ProviderInfo pi = null;
4883        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4884                UserHandle.getUserId(callingUid));
4885        if (cpr != null) {
4886            pi = cpr.info;
4887        } else {
4888            try {
4889                pi = pm.resolveContentProvider(name,
4890                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4891            } catch (RemoteException ex) {
4892            }
4893        }
4894        if (pi == null) {
4895            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4896            return -1;
4897        }
4898
4899        int targetUid = lastTargetUid;
4900        if (targetUid < 0 && targetPkg != null) {
4901            try {
4902                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4903                if (targetUid < 0) {
4904                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4905                            "Can't grant URI permission no uid for: " + targetPkg);
4906                    return -1;
4907                }
4908            } catch (RemoteException ex) {
4909                return -1;
4910            }
4911        }
4912
4913        if (targetUid >= 0) {
4914            // First...  does the target actually need this permission?
4915            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4916                // No need to grant the target this permission.
4917                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4918                        "Target " + targetPkg + " already has full permission to " + uri);
4919                return -1;
4920            }
4921        } else {
4922            // First...  there is no target package, so can anyone access it?
4923            boolean allowed = pi.exported;
4924            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4925                if (pi.readPermission != null) {
4926                    allowed = false;
4927                }
4928            }
4929            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4930                if (pi.writePermission != null) {
4931                    allowed = false;
4932                }
4933            }
4934            if (allowed) {
4935                return -1;
4936            }
4937        }
4938
4939        // Second...  is the provider allowing granting of URI permissions?
4940        if (!pi.grantUriPermissions) {
4941            throw new SecurityException("Provider " + pi.packageName
4942                    + "/" + pi.name
4943                    + " does not allow granting of Uri permissions (uri "
4944                    + uri + ")");
4945        }
4946        if (pi.uriPermissionPatterns != null) {
4947            final int N = pi.uriPermissionPatterns.length;
4948            boolean allowed = false;
4949            for (int i=0; i<N; i++) {
4950                if (pi.uriPermissionPatterns[i] != null
4951                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4952                    allowed = true;
4953                    break;
4954                }
4955            }
4956            if (!allowed) {
4957                throw new SecurityException("Provider " + pi.packageName
4958                        + "/" + pi.name
4959                        + " does not allow granting of permission to path of Uri "
4960                        + uri);
4961            }
4962        }
4963
4964        // Third...  does the caller itself have permission to access
4965        // this uri?
4966        if (callingUid != Process.myUid()) {
4967            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4968                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4969                    throw new SecurityException("Uid " + callingUid
4970                            + " does not have permission to uri " + uri);
4971                }
4972            }
4973        }
4974
4975        return targetUid;
4976    }
4977
4978    public int checkGrantUriPermission(int callingUid, String targetPkg,
4979            Uri uri, int modeFlags) {
4980        enforceNotIsolatedCaller("checkGrantUriPermission");
4981        synchronized(this) {
4982            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4983        }
4984    }
4985
4986    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4987            Uri uri, int modeFlags, UriPermissionOwner owner) {
4988        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4989                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4990        if (modeFlags == 0) {
4991            return;
4992        }
4993
4994        // So here we are: the caller has the assumed permission
4995        // to the uri, and the target doesn't.  Let's now give this to
4996        // the target.
4997
4998        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4999                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5000
5001        HashMap<Uri, UriPermission> targetUris
5002                = mGrantedUriPermissions.get(targetUid);
5003        if (targetUris == null) {
5004            targetUris = new HashMap<Uri, UriPermission>();
5005            mGrantedUriPermissions.put(targetUid, targetUris);
5006        }
5007
5008        UriPermission perm = targetUris.get(uri);
5009        if (perm == null) {
5010            perm = new UriPermission(targetUid, uri);
5011            targetUris.put(uri, perm);
5012        }
5013
5014        perm.modeFlags |= modeFlags;
5015        if (owner == null) {
5016            perm.globalModeFlags |= modeFlags;
5017        } else {
5018            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5019                 perm.readOwners.add(owner);
5020                 owner.addReadPermission(perm);
5021            }
5022            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5023                 perm.writeOwners.add(owner);
5024                 owner.addWritePermission(perm);
5025            }
5026        }
5027    }
5028
5029    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5030            int modeFlags, UriPermissionOwner owner) {
5031        if (targetPkg == null) {
5032            throw new NullPointerException("targetPkg");
5033        }
5034
5035        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5036        if (targetUid < 0) {
5037            return;
5038        }
5039
5040        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5041    }
5042
5043    static class NeededUriGrants extends ArrayList<Uri> {
5044        final String targetPkg;
5045        final int targetUid;
5046        final int flags;
5047
5048        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5049            targetPkg = _targetPkg;
5050            targetUid = _targetUid;
5051            flags = _flags;
5052        }
5053    }
5054
5055    /**
5056     * Like checkGrantUriPermissionLocked, but takes an Intent.
5057     */
5058    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5059            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5060        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5061                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5062                + " clip=" + (intent != null ? intent.getClipData() : null)
5063                + " from " + intent + "; flags=0x"
5064                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5065
5066        if (targetPkg == null) {
5067            throw new NullPointerException("targetPkg");
5068        }
5069
5070        if (intent == null) {
5071            return null;
5072        }
5073        Uri data = intent.getData();
5074        ClipData clip = intent.getClipData();
5075        if (data == null && clip == null) {
5076            return null;
5077        }
5078        if (data != null) {
5079            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5080                mode, needed != null ? needed.targetUid : -1);
5081            if (target > 0) {
5082                if (needed == null) {
5083                    needed = new NeededUriGrants(targetPkg, target, mode);
5084                }
5085                needed.add(data);
5086            }
5087        }
5088        if (clip != null) {
5089            for (int i=0; i<clip.getItemCount(); i++) {
5090                Uri uri = clip.getItemAt(i).getUri();
5091                if (uri != null) {
5092                    int target = -1;
5093                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5094                            mode, needed != null ? needed.targetUid : -1);
5095                    if (target > 0) {
5096                        if (needed == null) {
5097                            needed = new NeededUriGrants(targetPkg, target, mode);
5098                        }
5099                        needed.add(uri);
5100                    }
5101                } else {
5102                    Intent clipIntent = clip.getItemAt(i).getIntent();
5103                    if (clipIntent != null) {
5104                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5105                                callingUid, targetPkg, clipIntent, mode, needed);
5106                        if (newNeeded != null) {
5107                            needed = newNeeded;
5108                        }
5109                    }
5110                }
5111            }
5112        }
5113
5114        return needed;
5115    }
5116
5117    /**
5118     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5119     */
5120    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5121            UriPermissionOwner owner) {
5122        if (needed != null) {
5123            for (int i=0; i<needed.size(); i++) {
5124                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5125                        needed.get(i), needed.flags, owner);
5126            }
5127        }
5128    }
5129
5130    void grantUriPermissionFromIntentLocked(int callingUid,
5131            String targetPkg, Intent intent, UriPermissionOwner owner) {
5132        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5133                intent, intent != null ? intent.getFlags() : 0, null);
5134        if (needed == null) {
5135            return;
5136        }
5137
5138        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5139    }
5140
5141    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5142            Uri uri, int modeFlags) {
5143        enforceNotIsolatedCaller("grantUriPermission");
5144        synchronized(this) {
5145            final ProcessRecord r = getRecordForAppLocked(caller);
5146            if (r == null) {
5147                throw new SecurityException("Unable to find app for caller "
5148                        + caller
5149                        + " when granting permission to uri " + uri);
5150            }
5151            if (targetPkg == null) {
5152                throw new IllegalArgumentException("null target");
5153            }
5154            if (uri == null) {
5155                throw new IllegalArgumentException("null uri");
5156            }
5157
5158            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5159                    null);
5160        }
5161    }
5162
5163    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5164        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5165                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5166            HashMap<Uri, UriPermission> perms
5167                    = mGrantedUriPermissions.get(perm.uid);
5168            if (perms != null) {
5169                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5170                        "Removing " + perm.uid + " permission to " + perm.uri);
5171                perms.remove(perm.uri);
5172                if (perms.size() == 0) {
5173                    mGrantedUriPermissions.remove(perm.uid);
5174                }
5175            }
5176        }
5177    }
5178
5179    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5180            int modeFlags) {
5181        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5182                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5183        if (modeFlags == 0) {
5184            return;
5185        }
5186
5187        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5188                "Revoking all granted permissions to " + uri);
5189
5190        final IPackageManager pm = AppGlobals.getPackageManager();
5191
5192        final String authority = uri.getAuthority();
5193        ProviderInfo pi = null;
5194        int userId = UserHandle.getUserId(callingUid);
5195        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5196        if (cpr != null) {
5197            pi = cpr.info;
5198        } else {
5199            try {
5200                pi = pm.resolveContentProvider(authority,
5201                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5202            } catch (RemoteException ex) {
5203            }
5204        }
5205        if (pi == null) {
5206            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5207            return;
5208        }
5209
5210        // Does the caller have this permission on the URI?
5211        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5212            // Right now, if you are not the original owner of the permission,
5213            // you are not allowed to revoke it.
5214            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5215                throw new SecurityException("Uid " + callingUid
5216                        + " does not have permission to uri " + uri);
5217            //}
5218        }
5219
5220        // Go through all of the permissions and remove any that match.
5221        final List<String> SEGMENTS = uri.getPathSegments();
5222        if (SEGMENTS != null) {
5223            final int NS = SEGMENTS.size();
5224            int N = mGrantedUriPermissions.size();
5225            for (int i=0; i<N; i++) {
5226                HashMap<Uri, UriPermission> perms
5227                        = mGrantedUriPermissions.valueAt(i);
5228                Iterator<UriPermission> it = perms.values().iterator();
5229            toploop:
5230                while (it.hasNext()) {
5231                    UriPermission perm = it.next();
5232                    Uri targetUri = perm.uri;
5233                    if (!authority.equals(targetUri.getAuthority())) {
5234                        continue;
5235                    }
5236                    List<String> targetSegments = targetUri.getPathSegments();
5237                    if (targetSegments == null) {
5238                        continue;
5239                    }
5240                    if (targetSegments.size() < NS) {
5241                        continue;
5242                    }
5243                    for (int j=0; j<NS; j++) {
5244                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5245                            continue toploop;
5246                        }
5247                    }
5248                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5249                            "Revoking " + perm.uid + " permission to " + perm.uri);
5250                    perm.clearModes(modeFlags);
5251                    if (perm.modeFlags == 0) {
5252                        it.remove();
5253                    }
5254                }
5255                if (perms.size() == 0) {
5256                    mGrantedUriPermissions.remove(
5257                            mGrantedUriPermissions.keyAt(i));
5258                    N--;
5259                    i--;
5260                }
5261            }
5262        }
5263    }
5264
5265    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5266            int modeFlags) {
5267        enforceNotIsolatedCaller("revokeUriPermission");
5268        synchronized(this) {
5269            final ProcessRecord r = getRecordForAppLocked(caller);
5270            if (r == null) {
5271                throw new SecurityException("Unable to find app for caller "
5272                        + caller
5273                        + " when revoking permission to uri " + uri);
5274            }
5275            if (uri == null) {
5276                Slog.w(TAG, "revokeUriPermission: null uri");
5277                return;
5278            }
5279
5280            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5281                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5282            if (modeFlags == 0) {
5283                return;
5284            }
5285
5286            final IPackageManager pm = AppGlobals.getPackageManager();
5287
5288            final String authority = uri.getAuthority();
5289            ProviderInfo pi = null;
5290            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5291            if (cpr != null) {
5292                pi = cpr.info;
5293            } else {
5294                try {
5295                    pi = pm.resolveContentProvider(authority,
5296                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5297                } catch (RemoteException ex) {
5298                }
5299            }
5300            if (pi == null) {
5301                Slog.w(TAG, "No content provider found for permission revoke: "
5302                        + uri.toSafeString());
5303                return;
5304            }
5305
5306            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5307        }
5308    }
5309
5310    @Override
5311    public IBinder newUriPermissionOwner(String name) {
5312        enforceNotIsolatedCaller("newUriPermissionOwner");
5313        synchronized(this) {
5314            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5315            return owner.getExternalTokenLocked();
5316        }
5317    }
5318
5319    @Override
5320    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5321            Uri uri, int modeFlags) {
5322        synchronized(this) {
5323            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5324            if (owner == null) {
5325                throw new IllegalArgumentException("Unknown owner: " + token);
5326            }
5327            if (fromUid != Binder.getCallingUid()) {
5328                if (Binder.getCallingUid() != Process.myUid()) {
5329                    // Only system code can grant URI permissions on behalf
5330                    // of other users.
5331                    throw new SecurityException("nice try");
5332                }
5333            }
5334            if (targetPkg == null) {
5335                throw new IllegalArgumentException("null target");
5336            }
5337            if (uri == null) {
5338                throw new IllegalArgumentException("null uri");
5339            }
5340
5341            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5342        }
5343    }
5344
5345    @Override
5346    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5347        synchronized(this) {
5348            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5349            if (owner == null) {
5350                throw new IllegalArgumentException("Unknown owner: " + token);
5351            }
5352
5353            if (uri == null) {
5354                owner.removeUriPermissionsLocked(mode);
5355            } else {
5356                owner.removeUriPermissionLocked(uri, mode);
5357            }
5358        }
5359    }
5360
5361    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5362        synchronized (this) {
5363            ProcessRecord app =
5364                who != null ? getRecordForAppLocked(who) : null;
5365            if (app == null) return;
5366
5367            Message msg = Message.obtain();
5368            msg.what = WAIT_FOR_DEBUGGER_MSG;
5369            msg.obj = app;
5370            msg.arg1 = waiting ? 1 : 0;
5371            mHandler.sendMessage(msg);
5372        }
5373    }
5374
5375    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5376        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5377        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5378        outInfo.availMem = Process.getFreeMemory();
5379        outInfo.totalMem = Process.getTotalMemory();
5380        outInfo.threshold = homeAppMem;
5381        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5382        outInfo.hiddenAppThreshold = hiddenAppMem;
5383        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5384                ProcessList.SERVICE_ADJ);
5385        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5386                ProcessList.VISIBLE_APP_ADJ);
5387        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5388                ProcessList.FOREGROUND_APP_ADJ);
5389    }
5390
5391    // =========================================================
5392    // TASK MANAGEMENT
5393    // =========================================================
5394
5395    public List getTasks(int maxNum, int flags,
5396                         IThumbnailReceiver receiver) {
5397        ArrayList list = new ArrayList();
5398
5399        PendingThumbnailsRecord pending = null;
5400        IApplicationThread topThumbnail = null;
5401        ActivityRecord topRecord = null;
5402
5403        synchronized(this) {
5404            if (localLOGV) Slog.v(
5405                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5406                + ", receiver=" + receiver);
5407
5408            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5409                    != PackageManager.PERMISSION_GRANTED) {
5410                if (receiver != null) {
5411                    // If the caller wants to wait for pending thumbnails,
5412                    // it ain't gonna get them.
5413                    try {
5414                        receiver.finished();
5415                    } catch (RemoteException ex) {
5416                    }
5417                }
5418                String msg = "Permission Denial: getTasks() from pid="
5419                        + Binder.getCallingPid()
5420                        + ", uid=" + Binder.getCallingUid()
5421                        + " requires " + android.Manifest.permission.GET_TASKS;
5422                Slog.w(TAG, msg);
5423                throw new SecurityException(msg);
5424            }
5425
5426            int pos = mMainStack.mHistory.size()-1;
5427            ActivityRecord next =
5428                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5429            ActivityRecord top = null;
5430            TaskRecord curTask = null;
5431            int numActivities = 0;
5432            int numRunning = 0;
5433            while (pos >= 0 && maxNum > 0) {
5434                final ActivityRecord r = next;
5435                pos--;
5436                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5437
5438                // Initialize state for next task if needed.
5439                if (top == null ||
5440                        (top.state == ActivityState.INITIALIZING
5441                            && top.task == r.task)) {
5442                    top = r;
5443                    curTask = r.task;
5444                    numActivities = numRunning = 0;
5445                }
5446
5447                // Add 'r' into the current task.
5448                numActivities++;
5449                if (r.app != null && r.app.thread != null) {
5450                    numRunning++;
5451                }
5452
5453                if (localLOGV) Slog.v(
5454                    TAG, r.intent.getComponent().flattenToShortString()
5455                    + ": task=" + r.task);
5456
5457                // If the next one is a different task, generate a new
5458                // TaskInfo entry for what we have.
5459                if (next == null || next.task != curTask) {
5460                    ActivityManager.RunningTaskInfo ci
5461                            = new ActivityManager.RunningTaskInfo();
5462                    ci.id = curTask.taskId;
5463                    ci.baseActivity = r.intent.getComponent();
5464                    ci.topActivity = top.intent.getComponent();
5465                    if (top.thumbHolder != null) {
5466                        ci.description = top.thumbHolder.lastDescription;
5467                    }
5468                    ci.numActivities = numActivities;
5469                    ci.numRunning = numRunning;
5470                    //System.out.println(
5471                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5472                    if (ci.thumbnail == null && receiver != null) {
5473                        if (localLOGV) Slog.v(
5474                            TAG, "State=" + top.state + "Idle=" + top.idle
5475                            + " app=" + top.app
5476                            + " thr=" + (top.app != null ? top.app.thread : null));
5477                        if (top.state == ActivityState.RESUMED
5478                                || top.state == ActivityState.PAUSING) {
5479                            if (top.idle && top.app != null
5480                                && top.app.thread != null) {
5481                                topRecord = top;
5482                                topThumbnail = top.app.thread;
5483                            } else {
5484                                top.thumbnailNeeded = true;
5485                            }
5486                        }
5487                        if (pending == null) {
5488                            pending = new PendingThumbnailsRecord(receiver);
5489                        }
5490                        pending.pendingRecords.add(top);
5491                    }
5492                    list.add(ci);
5493                    maxNum--;
5494                    top = null;
5495                }
5496            }
5497
5498            if (pending != null) {
5499                mPendingThumbnails.add(pending);
5500            }
5501        }
5502
5503        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5504
5505        if (topThumbnail != null) {
5506            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5507            try {
5508                topThumbnail.requestThumbnail(topRecord.appToken);
5509            } catch (Exception e) {
5510                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5511                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5512            }
5513        }
5514
5515        if (pending == null && receiver != null) {
5516            // In this case all thumbnails were available and the client
5517            // is being asked to be told when the remaining ones come in...
5518            // which is unusually, since the top-most currently running
5519            // activity should never have a canned thumbnail!  Oh well.
5520            try {
5521                receiver.finished();
5522            } catch (RemoteException ex) {
5523            }
5524        }
5525
5526        return list;
5527    }
5528
5529    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5530            int flags, int userId) {
5531        final int callingUid = Binder.getCallingUid();
5532        if (userId != UserHandle.getCallingUserId()) {
5533            // Check if the caller is holding permissions for cross-user requests.
5534            if (checkComponentPermission(
5535                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5536                    Binder.getCallingPid(), callingUid, -1, true)
5537                    != PackageManager.PERMISSION_GRANTED) {
5538                String msg = "Permission Denial: "
5539                        + "Request to get recent tasks for user " + userId
5540                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5541                        + "; this requires "
5542                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5543                Slog.w(TAG, msg);
5544                throw new SecurityException(msg);
5545            } else {
5546                if (userId == UserHandle.USER_CURRENT) {
5547                    userId = mCurrentUserId;
5548                }
5549            }
5550        }
5551
5552        synchronized (this) {
5553            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5554                    "getRecentTasks()");
5555            final boolean detailed = checkCallingPermission(
5556                    android.Manifest.permission.GET_DETAILED_TASKS)
5557                    == PackageManager.PERMISSION_GRANTED;
5558
5559            IPackageManager pm = AppGlobals.getPackageManager();
5560
5561            final int N = mRecentTasks.size();
5562            ArrayList<ActivityManager.RecentTaskInfo> res
5563                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5564                            maxNum < N ? maxNum : N);
5565            for (int i=0; i<N && maxNum > 0; i++) {
5566                TaskRecord tr = mRecentTasks.get(i);
5567                // Only add calling user's recent tasks
5568                if (tr.userId != userId) continue;
5569                // Return the entry if desired by the caller.  We always return
5570                // the first entry, because callers always expect this to be the
5571                // foreground app.  We may filter others if the caller has
5572                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5573                // we should exclude the entry.
5574
5575                if (i == 0
5576                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5577                        || (tr.intent == null)
5578                        || ((tr.intent.getFlags()
5579                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5580                    ActivityManager.RecentTaskInfo rti
5581                            = new ActivityManager.RecentTaskInfo();
5582                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5583                    rti.persistentId = tr.taskId;
5584                    rti.baseIntent = new Intent(
5585                            tr.intent != null ? tr.intent : tr.affinityIntent);
5586                    if (!detailed) {
5587                        rti.baseIntent.replaceExtras((Bundle)null);
5588                    }
5589                    rti.origActivity = tr.origActivity;
5590                    rti.description = tr.lastDescription;
5591
5592                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5593                        // Check whether this activity is currently available.
5594                        try {
5595                            if (rti.origActivity != null) {
5596                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5597                                        == null) {
5598                                    continue;
5599                                }
5600                            } else if (rti.baseIntent != null) {
5601                                if (pm.queryIntentActivities(rti.baseIntent,
5602                                        null, 0, userId) == null) {
5603                                    continue;
5604                                }
5605                            }
5606                        } catch (RemoteException e) {
5607                            // Will never happen.
5608                        }
5609                    }
5610
5611                    res.add(rti);
5612                    maxNum--;
5613                }
5614            }
5615            return res;
5616        }
5617    }
5618
5619    private TaskRecord taskForIdLocked(int id) {
5620        final int N = mRecentTasks.size();
5621        for (int i=0; i<N; i++) {
5622            TaskRecord tr = mRecentTasks.get(i);
5623            if (tr.taskId == id) {
5624                return tr;
5625            }
5626        }
5627        return null;
5628    }
5629
5630    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5631        synchronized (this) {
5632            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5633                    "getTaskThumbnails()");
5634            TaskRecord tr = taskForIdLocked(id);
5635            if (tr != null) {
5636                return mMainStack.getTaskThumbnailsLocked(tr);
5637            }
5638        }
5639        return null;
5640    }
5641
5642    public boolean removeSubTask(int taskId, int subTaskIndex) {
5643        synchronized (this) {
5644            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5645                    "removeSubTask()");
5646            long ident = Binder.clearCallingIdentity();
5647            try {
5648                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5649                        true) != null;
5650            } finally {
5651                Binder.restoreCallingIdentity(ident);
5652            }
5653        }
5654    }
5655
5656    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5657        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5658        Intent baseIntent = new Intent(
5659                tr.intent != null ? tr.intent : tr.affinityIntent);
5660        ComponentName component = baseIntent.getComponent();
5661        if (component == null) {
5662            Slog.w(TAG, "Now component for base intent of task: " + tr);
5663            return;
5664        }
5665
5666        // Find any running services associated with this app.
5667        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5668
5669        if (killProcesses) {
5670            // Find any running processes associated with this app.
5671            final String pkg = component.getPackageName();
5672            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5673            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5674            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5675                for (int i=0; i<uids.size(); i++) {
5676                    ProcessRecord proc = uids.valueAt(i);
5677                    if (proc.userId != tr.userId) {
5678                        continue;
5679                    }
5680                    if (!proc.pkgList.contains(pkg)) {
5681                        continue;
5682                    }
5683                    procs.add(proc);
5684                }
5685            }
5686
5687            // Kill the running processes.
5688            for (int i=0; i<procs.size(); i++) {
5689                ProcessRecord pr = procs.get(i);
5690                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5691                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5692                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5693                            pr.processName, pr.setAdj, "remove task");
5694                    pr.killedBackground = true;
5695                    Process.killProcessQuiet(pr.pid);
5696                } else {
5697                    pr.waitingToKill = "remove task";
5698                }
5699            }
5700        }
5701    }
5702
5703    public boolean removeTask(int taskId, int flags) {
5704        synchronized (this) {
5705            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5706                    "removeTask()");
5707            long ident = Binder.clearCallingIdentity();
5708            try {
5709                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5710                        false);
5711                if (r != null) {
5712                    mRecentTasks.remove(r.task);
5713                    cleanUpRemovedTaskLocked(r.task, flags);
5714                    return true;
5715                } else {
5716                    TaskRecord tr = null;
5717                    int i=0;
5718                    while (i < mRecentTasks.size()) {
5719                        TaskRecord t = mRecentTasks.get(i);
5720                        if (t.taskId == taskId) {
5721                            tr = t;
5722                            break;
5723                        }
5724                        i++;
5725                    }
5726                    if (tr != null) {
5727                        if (tr.numActivities <= 0) {
5728                            // Caller is just removing a recent task that is
5729                            // not actively running.  That is easy!
5730                            mRecentTasks.remove(i);
5731                            cleanUpRemovedTaskLocked(tr, flags);
5732                            return true;
5733                        } else {
5734                            Slog.w(TAG, "removeTask: task " + taskId
5735                                    + " does not have activities to remove, "
5736                                    + " but numActivities=" + tr.numActivities
5737                                    + ": " + tr);
5738                        }
5739                    }
5740                }
5741            } finally {
5742                Binder.restoreCallingIdentity(ident);
5743            }
5744        }
5745        return false;
5746    }
5747
5748    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5749        int j;
5750        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5751        TaskRecord jt = startTask;
5752
5753        // First look backwards
5754        for (j=startIndex-1; j>=0; j--) {
5755            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5756            if (r.task != jt) {
5757                jt = r.task;
5758                if (affinity.equals(jt.affinity)) {
5759                    return j;
5760                }
5761            }
5762        }
5763
5764        // Now look forwards
5765        final int N = mMainStack.mHistory.size();
5766        jt = startTask;
5767        for (j=startIndex+1; j<N; j++) {
5768            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5769            if (r.task != jt) {
5770                if (affinity.equals(jt.affinity)) {
5771                    return j;
5772                }
5773                jt = r.task;
5774            }
5775        }
5776
5777        // Might it be at the top?
5778        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5779            return N-1;
5780        }
5781
5782        return -1;
5783    }
5784
5785    /**
5786     * TODO: Add mController hook
5787     */
5788    public void moveTaskToFront(int task, int flags, Bundle options) {
5789        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5790                "moveTaskToFront()");
5791
5792        synchronized(this) {
5793            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5794                    Binder.getCallingUid(), "Task to front")) {
5795                ActivityOptions.abort(options);
5796                return;
5797            }
5798            final long origId = Binder.clearCallingIdentity();
5799            try {
5800                TaskRecord tr = taskForIdLocked(task);
5801                if (tr != null) {
5802                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5803                        mMainStack.mUserLeaving = true;
5804                    }
5805                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5806                        // Caller wants the home activity moved with it.  To accomplish this,
5807                        // we'll just move the home task to the top first.
5808                        mMainStack.moveHomeToFrontLocked();
5809                    }
5810                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5811                    return;
5812                }
5813                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5814                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5815                    if (hr.task.taskId == task) {
5816                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5817                            mMainStack.mUserLeaving = true;
5818                        }
5819                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5820                            // Caller wants the home activity moved with it.  To accomplish this,
5821                            // we'll just move the home task to the top first.
5822                            mMainStack.moveHomeToFrontLocked();
5823                        }
5824                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5825                        return;
5826                    }
5827                }
5828            } finally {
5829                Binder.restoreCallingIdentity(origId);
5830            }
5831            ActivityOptions.abort(options);
5832        }
5833    }
5834
5835    public void moveTaskToBack(int task) {
5836        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5837                "moveTaskToBack()");
5838
5839        synchronized(this) {
5840            if (mMainStack.mResumedActivity != null
5841                    && mMainStack.mResumedActivity.task.taskId == task) {
5842                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5843                        Binder.getCallingUid(), "Task to back")) {
5844                    return;
5845                }
5846            }
5847            final long origId = Binder.clearCallingIdentity();
5848            mMainStack.moveTaskToBackLocked(task, null);
5849            Binder.restoreCallingIdentity(origId);
5850        }
5851    }
5852
5853    /**
5854     * Moves an activity, and all of the other activities within the same task, to the bottom
5855     * of the history stack.  The activity's order within the task is unchanged.
5856     *
5857     * @param token A reference to the activity we wish to move
5858     * @param nonRoot If false then this only works if the activity is the root
5859     *                of a task; if true it will work for any activity in a task.
5860     * @return Returns true if the move completed, false if not.
5861     */
5862    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5863        enforceNotIsolatedCaller("moveActivityTaskToBack");
5864        synchronized(this) {
5865            final long origId = Binder.clearCallingIdentity();
5866            int taskId = getTaskForActivityLocked(token, !nonRoot);
5867            if (taskId >= 0) {
5868                return mMainStack.moveTaskToBackLocked(taskId, null);
5869            }
5870            Binder.restoreCallingIdentity(origId);
5871        }
5872        return false;
5873    }
5874
5875    public void moveTaskBackwards(int task) {
5876        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5877                "moveTaskBackwards()");
5878
5879        synchronized(this) {
5880            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5881                    Binder.getCallingUid(), "Task backwards")) {
5882                return;
5883            }
5884            final long origId = Binder.clearCallingIdentity();
5885            moveTaskBackwardsLocked(task);
5886            Binder.restoreCallingIdentity(origId);
5887        }
5888    }
5889
5890    private final void moveTaskBackwardsLocked(int task) {
5891        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5892    }
5893
5894    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5895        synchronized(this) {
5896            return getTaskForActivityLocked(token, onlyRoot);
5897        }
5898    }
5899
5900    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5901        final int N = mMainStack.mHistory.size();
5902        TaskRecord lastTask = null;
5903        for (int i=0; i<N; i++) {
5904            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5905            if (r.appToken == token) {
5906                if (!onlyRoot || lastTask != r.task) {
5907                    return r.task.taskId;
5908                }
5909                return -1;
5910            }
5911            lastTask = r.task;
5912        }
5913
5914        return -1;
5915    }
5916
5917    // =========================================================
5918    // THUMBNAILS
5919    // =========================================================
5920
5921    public void reportThumbnail(IBinder token,
5922            Bitmap thumbnail, CharSequence description) {
5923        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5924        final long origId = Binder.clearCallingIdentity();
5925        sendPendingThumbnail(null, token, thumbnail, description, true);
5926        Binder.restoreCallingIdentity(origId);
5927    }
5928
5929    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5930            Bitmap thumbnail, CharSequence description, boolean always) {
5931        TaskRecord task = null;
5932        ArrayList receivers = null;
5933
5934        //System.out.println("Send pending thumbnail: " + r);
5935
5936        synchronized(this) {
5937            if (r == null) {
5938                r = mMainStack.isInStackLocked(token);
5939                if (r == null) {
5940                    return;
5941                }
5942            }
5943            if (thumbnail == null && r.thumbHolder != null) {
5944                thumbnail = r.thumbHolder.lastThumbnail;
5945                description = r.thumbHolder.lastDescription;
5946            }
5947            if (thumbnail == null && !always) {
5948                // If there is no thumbnail, and this entry is not actually
5949                // going away, then abort for now and pick up the next
5950                // thumbnail we get.
5951                return;
5952            }
5953            task = r.task;
5954
5955            int N = mPendingThumbnails.size();
5956            int i=0;
5957            while (i<N) {
5958                PendingThumbnailsRecord pr =
5959                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5960                //System.out.println("Looking in " + pr.pendingRecords);
5961                if (pr.pendingRecords.remove(r)) {
5962                    if (receivers == null) {
5963                        receivers = new ArrayList();
5964                    }
5965                    receivers.add(pr);
5966                    if (pr.pendingRecords.size() == 0) {
5967                        pr.finished = true;
5968                        mPendingThumbnails.remove(i);
5969                        N--;
5970                        continue;
5971                    }
5972                }
5973                i++;
5974            }
5975        }
5976
5977        if (receivers != null) {
5978            final int N = receivers.size();
5979            for (int i=0; i<N; i++) {
5980                try {
5981                    PendingThumbnailsRecord pr =
5982                        (PendingThumbnailsRecord)receivers.get(i);
5983                    pr.receiver.newThumbnail(
5984                        task != null ? task.taskId : -1, thumbnail, description);
5985                    if (pr.finished) {
5986                        pr.receiver.finished();
5987                    }
5988                } catch (Exception e) {
5989                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5990                }
5991            }
5992        }
5993    }
5994
5995    // =========================================================
5996    // CONTENT PROVIDERS
5997    // =========================================================
5998
5999    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6000        List<ProviderInfo> providers = null;
6001        try {
6002            providers = AppGlobals.getPackageManager().
6003                queryContentProviders(app.processName, app.uid,
6004                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6005        } catch (RemoteException ex) {
6006        }
6007        if (DEBUG_MU)
6008            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6009        int userId = app.userId;
6010        if (providers != null) {
6011            int N = providers.size();
6012            for (int i=0; i<N; i++) {
6013                ProviderInfo cpi =
6014                    (ProviderInfo)providers.get(i);
6015                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6016                        cpi.name, cpi.flags);
6017                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6018                    // This is a singleton provider, but a user besides the
6019                    // default user is asking to initialize a process it runs
6020                    // in...  well, no, it doesn't actually run in this process,
6021                    // it runs in the process of the default user.  Get rid of it.
6022                    providers.remove(i);
6023                    N--;
6024                    continue;
6025                }
6026
6027                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6028                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6029                if (cpr == null) {
6030                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6031                    mProviderMap.putProviderByClass(comp, cpr);
6032                }
6033                if (DEBUG_MU)
6034                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6035                app.pubProviders.put(cpi.name, cpr);
6036                app.addPackage(cpi.applicationInfo.packageName);
6037                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6038            }
6039        }
6040        return providers;
6041    }
6042
6043    /**
6044     * Check if {@link ProcessRecord} has a possible chance at accessing the
6045     * given {@link ProviderInfo}. Final permission checking is always done
6046     * in {@link ContentProvider}.
6047     */
6048    private final String checkContentProviderPermissionLocked(
6049            ProviderInfo cpi, ProcessRecord r) {
6050        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6051        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6052        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6053                cpi.applicationInfo.uid, cpi.exported)
6054                == PackageManager.PERMISSION_GRANTED) {
6055            return null;
6056        }
6057        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6058                cpi.applicationInfo.uid, cpi.exported)
6059                == PackageManager.PERMISSION_GRANTED) {
6060            return null;
6061        }
6062
6063        PathPermission[] pps = cpi.pathPermissions;
6064        if (pps != null) {
6065            int i = pps.length;
6066            while (i > 0) {
6067                i--;
6068                PathPermission pp = pps[i];
6069                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6070                        cpi.applicationInfo.uid, cpi.exported)
6071                        == PackageManager.PERMISSION_GRANTED) {
6072                    return null;
6073                }
6074                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6075                        cpi.applicationInfo.uid, cpi.exported)
6076                        == PackageManager.PERMISSION_GRANTED) {
6077                    return null;
6078                }
6079            }
6080        }
6081
6082        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6083        if (perms != null) {
6084            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6085                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6086                    return null;
6087                }
6088            }
6089        }
6090
6091        String msg;
6092        if (!cpi.exported) {
6093            msg = "Permission Denial: opening provider " + cpi.name
6094                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6095                    + ", uid=" + callingUid + ") that is not exported from uid "
6096                    + cpi.applicationInfo.uid;
6097        } else {
6098            msg = "Permission Denial: opening provider " + cpi.name
6099                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6100                    + ", uid=" + callingUid + ") requires "
6101                    + cpi.readPermission + " or " + cpi.writePermission;
6102        }
6103        Slog.w(TAG, msg);
6104        return msg;
6105    }
6106
6107    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6108            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6109        if (r != null) {
6110            for (int i=0; i<r.conProviders.size(); i++) {
6111                ContentProviderConnection conn = r.conProviders.get(i);
6112                if (conn.provider == cpr) {
6113                    if (DEBUG_PROVIDER) Slog.v(TAG,
6114                            "Adding provider requested by "
6115                            + r.processName + " from process "
6116                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6117                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6118                    if (stable) {
6119                        conn.stableCount++;
6120                        conn.numStableIncs++;
6121                    } else {
6122                        conn.unstableCount++;
6123                        conn.numUnstableIncs++;
6124                    }
6125                    return conn;
6126                }
6127            }
6128            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6129            if (stable) {
6130                conn.stableCount = 1;
6131                conn.numStableIncs = 1;
6132            } else {
6133                conn.unstableCount = 1;
6134                conn.numUnstableIncs = 1;
6135            }
6136            cpr.connections.add(conn);
6137            r.conProviders.add(conn);
6138            return conn;
6139        }
6140        cpr.addExternalProcessHandleLocked(externalProcessToken);
6141        return null;
6142    }
6143
6144    boolean decProviderCountLocked(ContentProviderConnection conn,
6145            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6146        if (conn != null) {
6147            cpr = conn.provider;
6148            if (DEBUG_PROVIDER) Slog.v(TAG,
6149                    "Removing provider requested by "
6150                    + conn.client.processName + " from process "
6151                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6152                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6153            if (stable) {
6154                conn.stableCount--;
6155            } else {
6156                conn.unstableCount--;
6157            }
6158            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6159                cpr.connections.remove(conn);
6160                conn.client.conProviders.remove(conn);
6161                return true;
6162            }
6163            return false;
6164        }
6165        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6166        return false;
6167    }
6168
6169    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6170            String name, IBinder token, boolean stable) {
6171        ContentProviderRecord cpr;
6172        ContentProviderConnection conn = null;
6173        ProviderInfo cpi = null;
6174
6175        synchronized(this) {
6176            ProcessRecord r = null;
6177            if (caller != null) {
6178                r = getRecordForAppLocked(caller);
6179                if (r == null) {
6180                    throw new SecurityException(
6181                            "Unable to find app for caller " + caller
6182                          + " (pid=" + Binder.getCallingPid()
6183                          + ") when getting content provider " + name);
6184                }
6185            }
6186
6187            // First check if this content provider has been published...
6188            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6189            cpr = mProviderMap.getProviderByName(name, userId);
6190            boolean providerRunning = cpr != null;
6191            if (providerRunning) {
6192                cpi = cpr.info;
6193                String msg;
6194                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6195                    throw new SecurityException(msg);
6196                }
6197
6198                if (r != null && cpr.canRunHere(r)) {
6199                    // This provider has been published or is in the process
6200                    // of being published...  but it is also allowed to run
6201                    // in the caller's process, so don't make a connection
6202                    // and just let the caller instantiate its own instance.
6203                    ContentProviderHolder holder = cpr.newHolder(null);
6204                    // don't give caller the provider object, it needs
6205                    // to make its own.
6206                    holder.provider = null;
6207                    return holder;
6208                }
6209
6210                final long origId = Binder.clearCallingIdentity();
6211
6212                // In this case the provider instance already exists, so we can
6213                // return it right away.
6214                conn = incProviderCountLocked(r, cpr, token, stable);
6215                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6216                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6217                        // If this is a perceptible app accessing the provider,
6218                        // make sure to count it as being accessed and thus
6219                        // back up on the LRU list.  This is good because
6220                        // content providers are often expensive to start.
6221                        updateLruProcessLocked(cpr.proc, false, true);
6222                    }
6223                }
6224
6225                if (cpr.proc != null) {
6226                    if (false) {
6227                        if (cpr.name.flattenToShortString().equals(
6228                                "com.android.providers.calendar/.CalendarProvider2")) {
6229                            Slog.v(TAG, "****************** KILLING "
6230                                + cpr.name.flattenToShortString());
6231                            Process.killProcess(cpr.proc.pid);
6232                        }
6233                    }
6234                    boolean success = updateOomAdjLocked(cpr.proc);
6235                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6236                    // NOTE: there is still a race here where a signal could be
6237                    // pending on the process even though we managed to update its
6238                    // adj level.  Not sure what to do about this, but at least
6239                    // the race is now smaller.
6240                    if (!success) {
6241                        // Uh oh...  it looks like the provider's process
6242                        // has been killed on us.  We need to wait for a new
6243                        // process to be started, and make sure its death
6244                        // doesn't kill our process.
6245                        Slog.i(TAG,
6246                                "Existing provider " + cpr.name.flattenToShortString()
6247                                + " is crashing; detaching " + r);
6248                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6249                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6250                        if (!lastRef) {
6251                            // This wasn't the last ref our process had on
6252                            // the provider...  we have now been killed, bail.
6253                            return null;
6254                        }
6255                        providerRunning = false;
6256                        conn = null;
6257                    }
6258                }
6259
6260                Binder.restoreCallingIdentity(origId);
6261            }
6262
6263            boolean singleton;
6264            if (!providerRunning) {
6265                try {
6266                    cpi = AppGlobals.getPackageManager().
6267                        resolveContentProvider(name,
6268                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6269                } catch (RemoteException ex) {
6270                }
6271                if (cpi == null) {
6272                    return null;
6273                }
6274                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6275                        cpi.name, cpi.flags);
6276                if (singleton) {
6277                    userId = 0;
6278                }
6279                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6280
6281                String msg;
6282                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6283                    throw new SecurityException(msg);
6284                }
6285
6286                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6287                        && !cpi.processName.equals("system")) {
6288                    // If this content provider does not run in the system
6289                    // process, and the system is not yet ready to run other
6290                    // processes, then fail fast instead of hanging.
6291                    throw new IllegalArgumentException(
6292                            "Attempt to launch content provider before system ready");
6293                }
6294
6295                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6296                cpr = mProviderMap.getProviderByClass(comp, userId);
6297                final boolean firstClass = cpr == null;
6298                if (firstClass) {
6299                    try {
6300                        ApplicationInfo ai =
6301                            AppGlobals.getPackageManager().
6302                                getApplicationInfo(
6303                                        cpi.applicationInfo.packageName,
6304                                        STOCK_PM_FLAGS, userId);
6305                        if (ai == null) {
6306                            Slog.w(TAG, "No package info for content provider "
6307                                    + cpi.name);
6308                            return null;
6309                        }
6310                        ai = getAppInfoForUser(ai, userId);
6311                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6312                    } catch (RemoteException ex) {
6313                        // pm is in same process, this will never happen.
6314                    }
6315                }
6316
6317                if (r != null && cpr.canRunHere(r)) {
6318                    // If this is a multiprocess provider, then just return its
6319                    // info and allow the caller to instantiate it.  Only do
6320                    // this if the provider is the same user as the caller's
6321                    // process, or can run as root (so can be in any process).
6322                    return cpr.newHolder(null);
6323                }
6324
6325                if (DEBUG_PROVIDER) {
6326                    RuntimeException e = new RuntimeException("here");
6327                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6328                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6329                }
6330
6331                // This is single process, and our app is now connecting to it.
6332                // See if we are already in the process of launching this
6333                // provider.
6334                final int N = mLaunchingProviders.size();
6335                int i;
6336                for (i=0; i<N; i++) {
6337                    if (mLaunchingProviders.get(i) == cpr) {
6338                        break;
6339                    }
6340                }
6341
6342                // If the provider is not already being launched, then get it
6343                // started.
6344                if (i >= N) {
6345                    final long origId = Binder.clearCallingIdentity();
6346
6347                    try {
6348                        // Content provider is now in use, its package can't be stopped.
6349                        try {
6350                            AppGlobals.getPackageManager().setPackageStoppedState(
6351                                    cpr.appInfo.packageName, false, userId);
6352                        } catch (RemoteException e) {
6353                        } catch (IllegalArgumentException e) {
6354                            Slog.w(TAG, "Failed trying to unstop package "
6355                                    + cpr.appInfo.packageName + ": " + e);
6356                        }
6357
6358                        ProcessRecord proc = startProcessLocked(cpi.processName,
6359                                cpr.appInfo, false, 0, "content provider",
6360                                new ComponentName(cpi.applicationInfo.packageName,
6361                                        cpi.name), false, false);
6362                        if (proc == null) {
6363                            Slog.w(TAG, "Unable to launch app "
6364                                    + cpi.applicationInfo.packageName + "/"
6365                                    + cpi.applicationInfo.uid + " for provider "
6366                                    + name + ": process is bad");
6367                            return null;
6368                        }
6369                        cpr.launchingApp = proc;
6370                        mLaunchingProviders.add(cpr);
6371                    } finally {
6372                        Binder.restoreCallingIdentity(origId);
6373                    }
6374                }
6375
6376                // Make sure the provider is published (the same provider class
6377                // may be published under multiple names).
6378                if (firstClass) {
6379                    mProviderMap.putProviderByClass(comp, cpr);
6380                }
6381
6382                mProviderMap.putProviderByName(name, cpr);
6383                conn = incProviderCountLocked(r, cpr, token, stable);
6384                if (conn != null) {
6385                    conn.waiting = true;
6386                }
6387            }
6388        }
6389
6390        // Wait for the provider to be published...
6391        synchronized (cpr) {
6392            while (cpr.provider == null) {
6393                if (cpr.launchingApp == null) {
6394                    Slog.w(TAG, "Unable to launch app "
6395                            + cpi.applicationInfo.packageName + "/"
6396                            + cpi.applicationInfo.uid + " for provider "
6397                            + name + ": launching app became null");
6398                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6399                            cpi.applicationInfo.packageName,
6400                            cpi.applicationInfo.uid, name);
6401                    return null;
6402                }
6403                try {
6404                    if (DEBUG_MU) {
6405                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6406                                + cpr.launchingApp);
6407                    }
6408                    if (conn != null) {
6409                        conn.waiting = true;
6410                    }
6411                    cpr.wait();
6412                } catch (InterruptedException ex) {
6413                } finally {
6414                    if (conn != null) {
6415                        conn.waiting = false;
6416                    }
6417                }
6418            }
6419        }
6420        return cpr != null ? cpr.newHolder(conn) : null;
6421    }
6422
6423    public final ContentProviderHolder getContentProvider(
6424            IApplicationThread caller, String name, boolean stable) {
6425        enforceNotIsolatedCaller("getContentProvider");
6426        if (caller == null) {
6427            String msg = "null IApplicationThread when getting content provider "
6428                    + name;
6429            Slog.w(TAG, msg);
6430            throw new SecurityException(msg);
6431        }
6432
6433        return getContentProviderImpl(caller, name, null, stable);
6434    }
6435
6436    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6437        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6438            "Do not have permission in call getContentProviderExternal()");
6439        return getContentProviderExternalUnchecked(name, token);
6440    }
6441
6442    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6443        return getContentProviderImpl(null, name, token, true);
6444    }
6445
6446    /**
6447     * Drop a content provider from a ProcessRecord's bookkeeping
6448     * @param cpr
6449     */
6450    public void removeContentProvider(IBinder connection, boolean stable) {
6451        enforceNotIsolatedCaller("removeContentProvider");
6452        synchronized (this) {
6453            ContentProviderConnection conn;
6454            try {
6455                conn = (ContentProviderConnection)connection;
6456            } catch (ClassCastException e) {
6457                String msg ="removeContentProvider: " + connection
6458                        + " not a ContentProviderConnection";
6459                Slog.w(TAG, msg);
6460                throw new IllegalArgumentException(msg);
6461            }
6462            if (conn == null) {
6463                throw new NullPointerException("connection is null");
6464            }
6465            if (decProviderCountLocked(conn, null, null, stable)) {
6466                updateOomAdjLocked();
6467            }
6468        }
6469    }
6470
6471    public void removeContentProviderExternal(String name, IBinder token) {
6472        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6473            "Do not have permission in call removeContentProviderExternal()");
6474        removeContentProviderExternalUnchecked(name, token);
6475    }
6476
6477    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6478        synchronized (this) {
6479            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6480                    Binder.getOrigCallingUser());
6481            if(cpr == null) {
6482                //remove from mProvidersByClass
6483                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6484                return;
6485            }
6486
6487            //update content provider record entry info
6488            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6489            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6490                    Binder.getOrigCallingUser());
6491            if (localCpr.hasExternalProcessHandles()) {
6492                if (localCpr.removeExternalProcessHandleLocked(token)) {
6493                    updateOomAdjLocked();
6494                } else {
6495                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6496                            + " with no external reference for token: "
6497                            + token + ".");
6498                }
6499            } else {
6500                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6501                        + " with no external references.");
6502            }
6503        }
6504    }
6505
6506    public final void publishContentProviders(IApplicationThread caller,
6507            List<ContentProviderHolder> providers) {
6508        if (providers == null) {
6509            return;
6510        }
6511
6512        enforceNotIsolatedCaller("publishContentProviders");
6513        synchronized (this) {
6514            final ProcessRecord r = getRecordForAppLocked(caller);
6515            if (DEBUG_MU)
6516                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6517            if (r == null) {
6518                throw new SecurityException(
6519                        "Unable to find app for caller " + caller
6520                      + " (pid=" + Binder.getCallingPid()
6521                      + ") when publishing content providers");
6522            }
6523
6524            final long origId = Binder.clearCallingIdentity();
6525
6526            final int N = providers.size();
6527            for (int i=0; i<N; i++) {
6528                ContentProviderHolder src = providers.get(i);
6529                if (src == null || src.info == null || src.provider == null) {
6530                    continue;
6531                }
6532                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6533                if (DEBUG_MU)
6534                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6535                if (dst != null) {
6536                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6537                    mProviderMap.putProviderByClass(comp, dst);
6538                    String names[] = dst.info.authority.split(";");
6539                    for (int j = 0; j < names.length; j++) {
6540                        mProviderMap.putProviderByName(names[j], dst);
6541                    }
6542
6543                    int NL = mLaunchingProviders.size();
6544                    int j;
6545                    for (j=0; j<NL; j++) {
6546                        if (mLaunchingProviders.get(j) == dst) {
6547                            mLaunchingProviders.remove(j);
6548                            j--;
6549                            NL--;
6550                        }
6551                    }
6552                    synchronized (dst) {
6553                        dst.provider = src.provider;
6554                        dst.proc = r;
6555                        dst.notifyAll();
6556                    }
6557                    updateOomAdjLocked(r);
6558                }
6559            }
6560
6561            Binder.restoreCallingIdentity(origId);
6562        }
6563    }
6564
6565    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6566        ContentProviderConnection conn;
6567        try {
6568            conn = (ContentProviderConnection)connection;
6569        } catch (ClassCastException e) {
6570            String msg ="refContentProvider: " + connection
6571                    + " not a ContentProviderConnection";
6572            Slog.w(TAG, msg);
6573            throw new IllegalArgumentException(msg);
6574        }
6575        if (conn == null) {
6576            throw new NullPointerException("connection is null");
6577        }
6578
6579        synchronized (this) {
6580            if (stable > 0) {
6581                conn.numStableIncs += stable;
6582            }
6583            stable = conn.stableCount + stable;
6584            if (stable < 0) {
6585                throw new IllegalStateException("stableCount < 0: " + stable);
6586            }
6587
6588            if (unstable > 0) {
6589                conn.numUnstableIncs += unstable;
6590            }
6591            unstable = conn.unstableCount + unstable;
6592            if (unstable < 0) {
6593                throw new IllegalStateException("unstableCount < 0: " + unstable);
6594            }
6595
6596            if ((stable+unstable) <= 0) {
6597                throw new IllegalStateException("ref counts can't go to zero here: stable="
6598                        + stable + " unstable=" + unstable);
6599            }
6600            conn.stableCount = stable;
6601            conn.unstableCount = unstable;
6602            return !conn.dead;
6603        }
6604    }
6605
6606    public void unstableProviderDied(IBinder connection) {
6607        ContentProviderConnection conn;
6608        try {
6609            conn = (ContentProviderConnection)connection;
6610        } catch (ClassCastException e) {
6611            String msg ="refContentProvider: " + connection
6612                    + " not a ContentProviderConnection";
6613            Slog.w(TAG, msg);
6614            throw new IllegalArgumentException(msg);
6615        }
6616        if (conn == null) {
6617            throw new NullPointerException("connection is null");
6618        }
6619
6620        // Safely retrieve the content provider associated with the connection.
6621        IContentProvider provider;
6622        synchronized (this) {
6623            provider = conn.provider.provider;
6624        }
6625
6626        if (provider == null) {
6627            // Um, yeah, we're way ahead of you.
6628            return;
6629        }
6630
6631        // Make sure the caller is being honest with us.
6632        if (provider.asBinder().pingBinder()) {
6633            // Er, no, still looks good to us.
6634            synchronized (this) {
6635                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6636                        + " says " + conn + " died, but we don't agree");
6637                return;
6638            }
6639        }
6640
6641        // Well look at that!  It's dead!
6642        synchronized (this) {
6643            if (conn.provider.provider != provider) {
6644                // But something changed...  good enough.
6645                return;
6646            }
6647
6648            ProcessRecord proc = conn.provider.proc;
6649            if (proc == null || proc.thread == null) {
6650                // Seems like the process is already cleaned up.
6651                return;
6652            }
6653
6654            // As far as we're concerned, this is just like receiving a
6655            // death notification...  just a bit prematurely.
6656            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6657                    + ") early provider death");
6658            final long ident = Binder.clearCallingIdentity();
6659            try {
6660                appDiedLocked(proc, proc.pid, proc.thread);
6661            } finally {
6662                Binder.restoreCallingIdentity(ident);
6663            }
6664        }
6665    }
6666
6667    public static final void installSystemProviders() {
6668        List<ProviderInfo> providers;
6669        synchronized (mSelf) {
6670            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6671            providers = mSelf.generateApplicationProvidersLocked(app);
6672            if (providers != null) {
6673                for (int i=providers.size()-1; i>=0; i--) {
6674                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6675                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6676                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6677                                + ": not system .apk");
6678                        providers.remove(i);
6679                    }
6680                }
6681            }
6682        }
6683        if (providers != null) {
6684            mSystemThread.installSystemProviders(providers);
6685        }
6686
6687        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6688
6689        mSelf.mUsageStatsService.monitorPackages();
6690    }
6691
6692    /**
6693     * Allows app to retrieve the MIME type of a URI without having permission
6694     * to access its content provider.
6695     *
6696     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6697     *
6698     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6699     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6700     */
6701    public String getProviderMimeType(Uri uri) {
6702        enforceNotIsolatedCaller("getProviderMimeType");
6703        final String name = uri.getAuthority();
6704        final long ident = Binder.clearCallingIdentity();
6705        ContentProviderHolder holder = null;
6706
6707        try {
6708            holder = getContentProviderExternalUnchecked(name, null);
6709            if (holder != null) {
6710                return holder.provider.getType(uri);
6711            }
6712        } catch (RemoteException e) {
6713            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6714            return null;
6715        } finally {
6716            if (holder != null) {
6717                removeContentProviderExternalUnchecked(name, null);
6718            }
6719            Binder.restoreCallingIdentity(ident);
6720        }
6721
6722        return null;
6723    }
6724
6725    // =========================================================
6726    // GLOBAL MANAGEMENT
6727    // =========================================================
6728
6729    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6730            ApplicationInfo info, String customProcess, boolean isolated) {
6731        String proc = customProcess != null ? customProcess : info.processName;
6732        BatteryStatsImpl.Uid.Proc ps = null;
6733        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6734        int uid = info.uid;
6735        if (isolated) {
6736            int userId = UserHandle.getUserId(uid);
6737            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6738            uid = 0;
6739            while (true) {
6740                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6741                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6742                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6743                }
6744                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6745                mNextIsolatedProcessUid++;
6746                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6747                    // No process for this uid, use it.
6748                    break;
6749                }
6750                stepsLeft--;
6751                if (stepsLeft <= 0) {
6752                    return null;
6753                }
6754            }
6755        }
6756        synchronized (stats) {
6757            ps = stats.getProcessStatsLocked(info.uid, proc);
6758        }
6759        return new ProcessRecord(ps, thread, info, proc, uid);
6760    }
6761
6762    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6763        ProcessRecord app;
6764        if (!isolated) {
6765            app = getProcessRecordLocked(info.processName, info.uid);
6766        } else {
6767            app = null;
6768        }
6769
6770        if (app == null) {
6771            app = newProcessRecordLocked(null, info, null, isolated);
6772            mProcessNames.put(info.processName, app.uid, app);
6773            if (isolated) {
6774                mIsolatedProcesses.put(app.uid, app);
6775            }
6776            updateLruProcessLocked(app, true, true);
6777        }
6778
6779        // This package really, really can not be stopped.
6780        try {
6781            AppGlobals.getPackageManager().setPackageStoppedState(
6782                    info.packageName, false, UserHandle.getUserId(app.uid));
6783        } catch (RemoteException e) {
6784        } catch (IllegalArgumentException e) {
6785            Slog.w(TAG, "Failed trying to unstop package "
6786                    + info.packageName + ": " + e);
6787        }
6788
6789        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6790                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6791            app.persistent = true;
6792            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6793        }
6794        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6795            mPersistentStartingProcesses.add(app);
6796            startProcessLocked(app, "added application", app.processName);
6797        }
6798
6799        return app;
6800    }
6801
6802    public void unhandledBack() {
6803        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6804                "unhandledBack()");
6805
6806        synchronized(this) {
6807            int count = mMainStack.mHistory.size();
6808            if (DEBUG_SWITCH) Slog.d(
6809                TAG, "Performing unhandledBack(): stack size = " + count);
6810            if (count > 1) {
6811                final long origId = Binder.clearCallingIdentity();
6812                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6813                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6814                Binder.restoreCallingIdentity(origId);
6815            }
6816        }
6817    }
6818
6819    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6820        enforceNotIsolatedCaller("openContentUri");
6821        String name = uri.getAuthority();
6822        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6823        ParcelFileDescriptor pfd = null;
6824        if (cph != null) {
6825            // We record the binder invoker's uid in thread-local storage before
6826            // going to the content provider to open the file.  Later, in the code
6827            // that handles all permissions checks, we look for this uid and use
6828            // that rather than the Activity Manager's own uid.  The effect is that
6829            // we do the check against the caller's permissions even though it looks
6830            // to the content provider like the Activity Manager itself is making
6831            // the request.
6832            sCallerIdentity.set(new Identity(
6833                    Binder.getCallingPid(), Binder.getCallingUid()));
6834            try {
6835                pfd = cph.provider.openFile(uri, "r");
6836            } catch (FileNotFoundException e) {
6837                // do nothing; pfd will be returned null
6838            } finally {
6839                // Ensure that whatever happens, we clean up the identity state
6840                sCallerIdentity.remove();
6841            }
6842
6843            // We've got the fd now, so we're done with the provider.
6844            removeContentProviderExternalUnchecked(name, null);
6845        } else {
6846            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6847        }
6848        return pfd;
6849    }
6850
6851    // Actually is sleeping or shutting down or whatever else in the future
6852    // is an inactive state.
6853    public boolean isSleeping() {
6854        return mSleeping || mShuttingDown;
6855    }
6856
6857    public void goingToSleep() {
6858        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6859                != PackageManager.PERMISSION_GRANTED) {
6860            throw new SecurityException("Requires permission "
6861                    + android.Manifest.permission.DEVICE_POWER);
6862        }
6863
6864        synchronized(this) {
6865            mWentToSleep = true;
6866            updateEventDispatchingLocked();
6867
6868            if (!mSleeping) {
6869                mSleeping = true;
6870                mMainStack.stopIfSleepingLocked();
6871
6872                // Initialize the wake times of all processes.
6873                checkExcessivePowerUsageLocked(false);
6874                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6875                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6876                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6877            }
6878        }
6879    }
6880
6881    public boolean shutdown(int timeout) {
6882        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6883                != PackageManager.PERMISSION_GRANTED) {
6884            throw new SecurityException("Requires permission "
6885                    + android.Manifest.permission.SHUTDOWN);
6886        }
6887
6888        boolean timedout = false;
6889
6890        synchronized(this) {
6891            mShuttingDown = true;
6892            updateEventDispatchingLocked();
6893
6894            if (mMainStack.mResumedActivity != null) {
6895                mMainStack.stopIfSleepingLocked();
6896                final long endTime = System.currentTimeMillis() + timeout;
6897                while (mMainStack.mResumedActivity != null
6898                        || mMainStack.mPausingActivity != null) {
6899                    long delay = endTime - System.currentTimeMillis();
6900                    if (delay <= 0) {
6901                        Slog.w(TAG, "Activity manager shutdown timed out");
6902                        timedout = true;
6903                        break;
6904                    }
6905                    try {
6906                        this.wait();
6907                    } catch (InterruptedException e) {
6908                    }
6909                }
6910            }
6911        }
6912
6913        mUsageStatsService.shutdown();
6914        mBatteryStatsService.shutdown();
6915
6916        return timedout;
6917    }
6918
6919    public final void activitySlept(IBinder token) {
6920        if (localLOGV) Slog.v(
6921            TAG, "Activity slept: token=" + token);
6922
6923        ActivityRecord r = null;
6924
6925        final long origId = Binder.clearCallingIdentity();
6926
6927        synchronized (this) {
6928            r = mMainStack.isInStackLocked(token);
6929            if (r != null) {
6930                mMainStack.activitySleptLocked(r);
6931            }
6932        }
6933
6934        Binder.restoreCallingIdentity(origId);
6935    }
6936
6937    private void comeOutOfSleepIfNeededLocked() {
6938        if (!mWentToSleep && !mLockScreenShown) {
6939            if (mSleeping) {
6940                mSleeping = false;
6941                mMainStack.awakeFromSleepingLocked();
6942                mMainStack.resumeTopActivityLocked(null);
6943            }
6944        }
6945    }
6946
6947    public void wakingUp() {
6948        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6949                != PackageManager.PERMISSION_GRANTED) {
6950            throw new SecurityException("Requires permission "
6951                    + android.Manifest.permission.DEVICE_POWER);
6952        }
6953
6954        synchronized(this) {
6955            mWentToSleep = false;
6956            updateEventDispatchingLocked();
6957            comeOutOfSleepIfNeededLocked();
6958        }
6959    }
6960
6961    private void updateEventDispatchingLocked() {
6962        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6963    }
6964
6965    public void setLockScreenShown(boolean shown) {
6966        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6967                != PackageManager.PERMISSION_GRANTED) {
6968            throw new SecurityException("Requires permission "
6969                    + android.Manifest.permission.DEVICE_POWER);
6970        }
6971
6972        synchronized(this) {
6973            mLockScreenShown = shown;
6974            comeOutOfSleepIfNeededLocked();
6975        }
6976    }
6977
6978    public void stopAppSwitches() {
6979        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6980                != PackageManager.PERMISSION_GRANTED) {
6981            throw new SecurityException("Requires permission "
6982                    + android.Manifest.permission.STOP_APP_SWITCHES);
6983        }
6984
6985        synchronized(this) {
6986            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6987                    + APP_SWITCH_DELAY_TIME;
6988            mDidAppSwitch = false;
6989            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6990            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6991            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6992        }
6993    }
6994
6995    public void resumeAppSwitches() {
6996        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6997                != PackageManager.PERMISSION_GRANTED) {
6998            throw new SecurityException("Requires permission "
6999                    + android.Manifest.permission.STOP_APP_SWITCHES);
7000        }
7001
7002        synchronized(this) {
7003            // Note that we don't execute any pending app switches... we will
7004            // let those wait until either the timeout, or the next start
7005            // activity request.
7006            mAppSwitchesAllowedTime = 0;
7007        }
7008    }
7009
7010    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7011            String name) {
7012        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7013            return true;
7014        }
7015
7016        final int perm = checkComponentPermission(
7017                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7018                callingUid, -1, true);
7019        if (perm == PackageManager.PERMISSION_GRANTED) {
7020            return true;
7021        }
7022
7023        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7024        return false;
7025    }
7026
7027    public void setDebugApp(String packageName, boolean waitForDebugger,
7028            boolean persistent) {
7029        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7030                "setDebugApp()");
7031
7032        // Note that this is not really thread safe if there are multiple
7033        // callers into it at the same time, but that's not a situation we
7034        // care about.
7035        if (persistent) {
7036            final ContentResolver resolver = mContext.getContentResolver();
7037            Settings.System.putString(
7038                resolver, Settings.System.DEBUG_APP,
7039                packageName);
7040            Settings.System.putInt(
7041                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7042                waitForDebugger ? 1 : 0);
7043        }
7044
7045        synchronized (this) {
7046            if (!persistent) {
7047                mOrigDebugApp = mDebugApp;
7048                mOrigWaitForDebugger = mWaitForDebugger;
7049            }
7050            mDebugApp = packageName;
7051            mWaitForDebugger = waitForDebugger;
7052            mDebugTransient = !persistent;
7053            if (packageName != null) {
7054                final long origId = Binder.clearCallingIdentity();
7055                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7056                Binder.restoreCallingIdentity(origId);
7057            }
7058        }
7059    }
7060
7061    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7062        synchronized (this) {
7063            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7064            if (!isDebuggable) {
7065                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7066                    throw new SecurityException("Process not debuggable: " + app.packageName);
7067                }
7068            }
7069
7070            mOpenGlTraceApp = processName;
7071        }
7072    }
7073
7074    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7075            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7076        synchronized (this) {
7077            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7078            if (!isDebuggable) {
7079                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7080                    throw new SecurityException("Process not debuggable: " + app.packageName);
7081                }
7082            }
7083            mProfileApp = processName;
7084            mProfileFile = profileFile;
7085            if (mProfileFd != null) {
7086                try {
7087                    mProfileFd.close();
7088                } catch (IOException e) {
7089                }
7090                mProfileFd = null;
7091            }
7092            mProfileFd = profileFd;
7093            mProfileType = 0;
7094            mAutoStopProfiler = autoStopProfiler;
7095        }
7096    }
7097
7098    public void setAlwaysFinish(boolean enabled) {
7099        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7100                "setAlwaysFinish()");
7101
7102        Settings.System.putInt(
7103                mContext.getContentResolver(),
7104                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7105
7106        synchronized (this) {
7107            mAlwaysFinishActivities = enabled;
7108        }
7109    }
7110
7111    public void setActivityController(IActivityController controller) {
7112        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7113                "setActivityController()");
7114        synchronized (this) {
7115            mController = controller;
7116        }
7117    }
7118
7119    public boolean isUserAMonkey() {
7120        // For now the fact that there is a controller implies
7121        // we have a monkey.
7122        synchronized (this) {
7123            return mController != null;
7124        }
7125    }
7126
7127    public void registerProcessObserver(IProcessObserver observer) {
7128        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7129                "registerProcessObserver()");
7130        synchronized (this) {
7131            mProcessObservers.register(observer);
7132        }
7133    }
7134
7135    public void unregisterProcessObserver(IProcessObserver observer) {
7136        synchronized (this) {
7137            mProcessObservers.unregister(observer);
7138        }
7139    }
7140
7141    public void setImmersive(IBinder token, boolean immersive) {
7142        synchronized(this) {
7143            ActivityRecord r = mMainStack.isInStackLocked(token);
7144            if (r == null) {
7145                throw new IllegalArgumentException();
7146            }
7147            r.immersive = immersive;
7148        }
7149    }
7150
7151    public boolean isImmersive(IBinder token) {
7152        synchronized (this) {
7153            ActivityRecord r = mMainStack.isInStackLocked(token);
7154            if (r == null) {
7155                throw new IllegalArgumentException();
7156            }
7157            return r.immersive;
7158        }
7159    }
7160
7161    public boolean isTopActivityImmersive() {
7162        enforceNotIsolatedCaller("startActivity");
7163        synchronized (this) {
7164            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7165            return (r != null) ? r.immersive : false;
7166        }
7167    }
7168
7169    public final void enterSafeMode() {
7170        synchronized(this) {
7171            // It only makes sense to do this before the system is ready
7172            // and started launching other packages.
7173            if (!mSystemReady) {
7174                try {
7175                    AppGlobals.getPackageManager().enterSafeMode();
7176                } catch (RemoteException e) {
7177                }
7178            }
7179        }
7180    }
7181
7182    public final void showSafeModeOverlay() {
7183        View v = LayoutInflater.from(mContext).inflate(
7184                com.android.internal.R.layout.safe_mode, null);
7185        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7186        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7187        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7188        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7189        lp.gravity = Gravity.BOTTOM | Gravity.START;
7190        lp.format = v.getBackground().getOpacity();
7191        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7192                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7193        ((WindowManager)mContext.getSystemService(
7194                Context.WINDOW_SERVICE)).addView(v, lp);
7195    }
7196
7197    public void noteWakeupAlarm(IIntentSender sender) {
7198        if (!(sender instanceof PendingIntentRecord)) {
7199            return;
7200        }
7201        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7202        synchronized (stats) {
7203            if (mBatteryStatsService.isOnBattery()) {
7204                mBatteryStatsService.enforceCallingPermission();
7205                PendingIntentRecord rec = (PendingIntentRecord)sender;
7206                int MY_UID = Binder.getCallingUid();
7207                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7208                BatteryStatsImpl.Uid.Pkg pkg =
7209                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7210                pkg.incWakeupsLocked();
7211            }
7212        }
7213    }
7214
7215    public boolean killPids(int[] pids, String pReason, boolean secure) {
7216        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7217            throw new SecurityException("killPids only available to the system");
7218        }
7219        String reason = (pReason == null) ? "Unknown" : pReason;
7220        // XXX Note: don't acquire main activity lock here, because the window
7221        // manager calls in with its locks held.
7222
7223        boolean killed = false;
7224        synchronized (mPidsSelfLocked) {
7225            int[] types = new int[pids.length];
7226            int worstType = 0;
7227            for (int i=0; i<pids.length; i++) {
7228                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7229                if (proc != null) {
7230                    int type = proc.setAdj;
7231                    types[i] = type;
7232                    if (type > worstType) {
7233                        worstType = type;
7234                    }
7235                }
7236            }
7237
7238            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7239            // then constrain it so we will kill all hidden procs.
7240            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7241                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7242                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7243            }
7244
7245            // If this is not a secure call, don't let it kill processes that
7246            // are important.
7247            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7248                worstType = ProcessList.SERVICE_ADJ;
7249            }
7250
7251            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7252            for (int i=0; i<pids.length; i++) {
7253                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7254                if (proc == null) {
7255                    continue;
7256                }
7257                int adj = proc.setAdj;
7258                if (adj >= worstType && !proc.killedBackground) {
7259                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7260                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7261                            proc.processName, adj, reason);
7262                    killed = true;
7263                    proc.killedBackground = true;
7264                    Process.killProcessQuiet(pids[i]);
7265                }
7266            }
7267        }
7268        return killed;
7269    }
7270
7271    @Override
7272    public boolean killProcessesBelowForeground(String reason) {
7273        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7274            throw new SecurityException("killProcessesBelowForeground() only available to system");
7275        }
7276
7277        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7278    }
7279
7280    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7281        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7282            throw new SecurityException("killProcessesBelowAdj() only available to system");
7283        }
7284
7285        boolean killed = false;
7286        synchronized (mPidsSelfLocked) {
7287            final int size = mPidsSelfLocked.size();
7288            for (int i = 0; i < size; i++) {
7289                final int pid = mPidsSelfLocked.keyAt(i);
7290                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7291                if (proc == null) continue;
7292
7293                final int adj = proc.setAdj;
7294                if (adj > belowAdj && !proc.killedBackground) {
7295                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7296                    EventLog.writeEvent(
7297                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7298                    killed = true;
7299                    proc.killedBackground = true;
7300                    Process.killProcessQuiet(pid);
7301                }
7302            }
7303        }
7304        return killed;
7305    }
7306
7307    public final void startRunning(String pkg, String cls, String action,
7308            String data) {
7309        synchronized(this) {
7310            if (mStartRunning) {
7311                return;
7312            }
7313            mStartRunning = true;
7314            mTopComponent = pkg != null && cls != null
7315                    ? new ComponentName(pkg, cls) : null;
7316            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7317            mTopData = data;
7318            if (!mSystemReady) {
7319                return;
7320            }
7321        }
7322
7323        systemReady(null);
7324    }
7325
7326    private void retrieveSettings() {
7327        final ContentResolver resolver = mContext.getContentResolver();
7328        String debugApp = Settings.System.getString(
7329            resolver, Settings.System.DEBUG_APP);
7330        boolean waitForDebugger = Settings.System.getInt(
7331            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7332        boolean alwaysFinishActivities = Settings.System.getInt(
7333            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7334
7335        Configuration configuration = new Configuration();
7336        Settings.System.getConfiguration(resolver, configuration);
7337
7338        synchronized (this) {
7339            mDebugApp = mOrigDebugApp = debugApp;
7340            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7341            mAlwaysFinishActivities = alwaysFinishActivities;
7342            // This happens before any activities are started, so we can
7343            // change mConfiguration in-place.
7344            updateConfigurationLocked(configuration, null, false, true);
7345            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7346        }
7347    }
7348
7349    public boolean testIsSystemReady() {
7350        // no need to synchronize(this) just to read & return the value
7351        return mSystemReady;
7352    }
7353
7354    private static File getCalledPreBootReceiversFile() {
7355        File dataDir = Environment.getDataDirectory();
7356        File systemDir = new File(dataDir, "system");
7357        File fname = new File(systemDir, "called_pre_boots.dat");
7358        return fname;
7359    }
7360
7361    static final int LAST_DONE_VERSION = 10000;
7362
7363    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7364        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7365        File file = getCalledPreBootReceiversFile();
7366        FileInputStream fis = null;
7367        try {
7368            fis = new FileInputStream(file);
7369            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7370            int fvers = dis.readInt();
7371            if (fvers == LAST_DONE_VERSION) {
7372                String vers = dis.readUTF();
7373                String codename = dis.readUTF();
7374                String build = dis.readUTF();
7375                if (android.os.Build.VERSION.RELEASE.equals(vers)
7376                        && android.os.Build.VERSION.CODENAME.equals(codename)
7377                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7378                    int num = dis.readInt();
7379                    while (num > 0) {
7380                        num--;
7381                        String pkg = dis.readUTF();
7382                        String cls = dis.readUTF();
7383                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7384                    }
7385                }
7386            }
7387        } catch (FileNotFoundException e) {
7388        } catch (IOException e) {
7389            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7390        } finally {
7391            if (fis != null) {
7392                try {
7393                    fis.close();
7394                } catch (IOException e) {
7395                }
7396            }
7397        }
7398        return lastDoneReceivers;
7399    }
7400
7401    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7402        File file = getCalledPreBootReceiversFile();
7403        FileOutputStream fos = null;
7404        DataOutputStream dos = null;
7405        try {
7406            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7407            fos = new FileOutputStream(file);
7408            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7409            dos.writeInt(LAST_DONE_VERSION);
7410            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7411            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7412            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7413            dos.writeInt(list.size());
7414            for (int i=0; i<list.size(); i++) {
7415                dos.writeUTF(list.get(i).getPackageName());
7416                dos.writeUTF(list.get(i).getClassName());
7417            }
7418        } catch (IOException e) {
7419            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7420            file.delete();
7421        } finally {
7422            FileUtils.sync(fos);
7423            if (dos != null) {
7424                try {
7425                    dos.close();
7426                } catch (IOException e) {
7427                    // TODO Auto-generated catch block
7428                    e.printStackTrace();
7429                }
7430            }
7431        }
7432    }
7433
7434    public void systemReady(final Runnable goingCallback) {
7435        synchronized(this) {
7436            if (mSystemReady) {
7437                if (goingCallback != null) goingCallback.run();
7438                return;
7439            }
7440
7441            // Check to see if there are any update receivers to run.
7442            if (!mDidUpdate) {
7443                if (mWaitingUpdate) {
7444                    return;
7445                }
7446                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7447                List<ResolveInfo> ris = null;
7448                try {
7449                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7450                            intent, null, 0, 0);
7451                } catch (RemoteException e) {
7452                }
7453                if (ris != null) {
7454                    for (int i=ris.size()-1; i>=0; i--) {
7455                        if ((ris.get(i).activityInfo.applicationInfo.flags
7456                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7457                            ris.remove(i);
7458                        }
7459                    }
7460                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7461
7462                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7463
7464                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7465                    for (int i=0; i<ris.size(); i++) {
7466                        ActivityInfo ai = ris.get(i).activityInfo;
7467                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7468                        if (lastDoneReceivers.contains(comp)) {
7469                            ris.remove(i);
7470                            i--;
7471                        }
7472                    }
7473
7474                    for (int i=0; i<ris.size(); i++) {
7475                        ActivityInfo ai = ris.get(i).activityInfo;
7476                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7477                        doneReceivers.add(comp);
7478                        intent.setComponent(comp);
7479                        IIntentReceiver finisher = null;
7480                        if (i == ris.size()-1) {
7481                            finisher = new IIntentReceiver.Stub() {
7482                                public void performReceive(Intent intent, int resultCode,
7483                                        String data, Bundle extras, boolean ordered,
7484                                        boolean sticky) {
7485                                    // The raw IIntentReceiver interface is called
7486                                    // with the AM lock held, so redispatch to
7487                                    // execute our code without the lock.
7488                                    mHandler.post(new Runnable() {
7489                                        public void run() {
7490                                            synchronized (ActivityManagerService.this) {
7491                                                mDidUpdate = true;
7492                                            }
7493                                            writeLastDonePreBootReceivers(doneReceivers);
7494                                            showBootMessage(mContext.getText(
7495                                                    R.string.android_upgrading_complete),
7496                                                    false);
7497                                            systemReady(goingCallback);
7498                                        }
7499                                    });
7500                                }
7501                            };
7502                        }
7503                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7504                        /* TODO: Send this to all users */
7505                        broadcastIntentLocked(null, null, intent, null, finisher,
7506                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7507                                0 /* UserId zero */);
7508                        if (finisher != null) {
7509                            mWaitingUpdate = true;
7510                        }
7511                    }
7512                }
7513                if (mWaitingUpdate) {
7514                    return;
7515                }
7516                mDidUpdate = true;
7517            }
7518
7519            mSystemReady = true;
7520            if (!mStartRunning) {
7521                return;
7522            }
7523        }
7524
7525        ArrayList<ProcessRecord> procsToKill = null;
7526        synchronized(mPidsSelfLocked) {
7527            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7528                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7529                if (!isAllowedWhileBooting(proc.info)){
7530                    if (procsToKill == null) {
7531                        procsToKill = new ArrayList<ProcessRecord>();
7532                    }
7533                    procsToKill.add(proc);
7534                }
7535            }
7536        }
7537
7538        synchronized(this) {
7539            if (procsToKill != null) {
7540                for (int i=procsToKill.size()-1; i>=0; i--) {
7541                    ProcessRecord proc = procsToKill.get(i);
7542                    Slog.i(TAG, "Removing system update proc: " + proc);
7543                    removeProcessLocked(proc, true, false, "system update done");
7544                }
7545            }
7546
7547            // Now that we have cleaned up any update processes, we
7548            // are ready to start launching real processes and know that
7549            // we won't trample on them any more.
7550            mProcessesReady = true;
7551        }
7552
7553        Slog.i(TAG, "System now ready");
7554        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7555            SystemClock.uptimeMillis());
7556
7557        synchronized(this) {
7558            // Make sure we have no pre-ready processes sitting around.
7559
7560            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7561                ResolveInfo ri = mContext.getPackageManager()
7562                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7563                                STOCK_PM_FLAGS);
7564                CharSequence errorMsg = null;
7565                if (ri != null) {
7566                    ActivityInfo ai = ri.activityInfo;
7567                    ApplicationInfo app = ai.applicationInfo;
7568                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7569                        mTopAction = Intent.ACTION_FACTORY_TEST;
7570                        mTopData = null;
7571                        mTopComponent = new ComponentName(app.packageName,
7572                                ai.name);
7573                    } else {
7574                        errorMsg = mContext.getResources().getText(
7575                                com.android.internal.R.string.factorytest_not_system);
7576                    }
7577                } else {
7578                    errorMsg = mContext.getResources().getText(
7579                            com.android.internal.R.string.factorytest_no_action);
7580                }
7581                if (errorMsg != null) {
7582                    mTopAction = null;
7583                    mTopData = null;
7584                    mTopComponent = null;
7585                    Message msg = Message.obtain();
7586                    msg.what = SHOW_FACTORY_ERROR_MSG;
7587                    msg.getData().putCharSequence("msg", errorMsg);
7588                    mHandler.sendMessage(msg);
7589                }
7590            }
7591        }
7592
7593        retrieveSettings();
7594
7595        if (goingCallback != null) goingCallback.run();
7596
7597        synchronized (this) {
7598            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7599                try {
7600                    List apps = AppGlobals.getPackageManager().
7601                        getPersistentApplications(STOCK_PM_FLAGS);
7602                    if (apps != null) {
7603                        int N = apps.size();
7604                        int i;
7605                        for (i=0; i<N; i++) {
7606                            ApplicationInfo info
7607                                = (ApplicationInfo)apps.get(i);
7608                            if (info != null &&
7609                                    !info.packageName.equals("android")) {
7610                                addAppLocked(info, false);
7611                            }
7612                        }
7613                    }
7614                } catch (RemoteException ex) {
7615                    // pm is in same process, this will never happen.
7616                }
7617            }
7618
7619            // Start up initial activity.
7620            mBooting = true;
7621
7622            try {
7623                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7624                    Message msg = Message.obtain();
7625                    msg.what = SHOW_UID_ERROR_MSG;
7626                    mHandler.sendMessage(msg);
7627                }
7628            } catch (RemoteException e) {
7629            }
7630
7631            mMainStack.resumeTopActivityLocked(null);
7632        }
7633    }
7634
7635    private boolean makeAppCrashingLocked(ProcessRecord app,
7636            String shortMsg, String longMsg, String stackTrace) {
7637        app.crashing = true;
7638        app.crashingReport = generateProcessError(app,
7639                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7640        startAppProblemLocked(app);
7641        app.stopFreezingAllLocked();
7642        return handleAppCrashLocked(app);
7643    }
7644
7645    private void makeAppNotRespondingLocked(ProcessRecord app,
7646            String activity, String shortMsg, String longMsg) {
7647        app.notResponding = true;
7648        app.notRespondingReport = generateProcessError(app,
7649                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7650                activity, shortMsg, longMsg, null);
7651        startAppProblemLocked(app);
7652        app.stopFreezingAllLocked();
7653    }
7654
7655    /**
7656     * Generate a process error record, suitable for attachment to a ProcessRecord.
7657     *
7658     * @param app The ProcessRecord in which the error occurred.
7659     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7660     *                      ActivityManager.AppErrorStateInfo
7661     * @param activity The activity associated with the crash, if known.
7662     * @param shortMsg Short message describing the crash.
7663     * @param longMsg Long message describing the crash.
7664     * @param stackTrace Full crash stack trace, may be null.
7665     *
7666     * @return Returns a fully-formed AppErrorStateInfo record.
7667     */
7668    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7669            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7670        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7671
7672        report.condition = condition;
7673        report.processName = app.processName;
7674        report.pid = app.pid;
7675        report.uid = app.info.uid;
7676        report.tag = activity;
7677        report.shortMsg = shortMsg;
7678        report.longMsg = longMsg;
7679        report.stackTrace = stackTrace;
7680
7681        return report;
7682    }
7683
7684    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7685        synchronized (this) {
7686            app.crashing = false;
7687            app.crashingReport = null;
7688            app.notResponding = false;
7689            app.notRespondingReport = null;
7690            if (app.anrDialog == fromDialog) {
7691                app.anrDialog = null;
7692            }
7693            if (app.waitDialog == fromDialog) {
7694                app.waitDialog = null;
7695            }
7696            if (app.pid > 0 && app.pid != MY_PID) {
7697                handleAppCrashLocked(app);
7698                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7699                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7700                        app.processName, app.setAdj, "user's request after error");
7701                Process.killProcessQuiet(app.pid);
7702            }
7703        }
7704    }
7705
7706    private boolean handleAppCrashLocked(ProcessRecord app) {
7707        if (mHeadless) {
7708            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7709            return false;
7710        }
7711        long now = SystemClock.uptimeMillis();
7712
7713        Long crashTime;
7714        if (!app.isolated) {
7715            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7716        } else {
7717            crashTime = null;
7718        }
7719        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7720            // This process loses!
7721            Slog.w(TAG, "Process " + app.info.processName
7722                    + " has crashed too many times: killing!");
7723            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7724                    app.info.processName, app.uid);
7725            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7726                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7727                if (r.app == app) {
7728                    Slog.w(TAG, "  Force finishing activity "
7729                        + r.intent.getComponent().flattenToShortString());
7730                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7731                }
7732            }
7733            if (!app.persistent) {
7734                // We don't want to start this process again until the user
7735                // explicitly does so...  but for persistent process, we really
7736                // need to keep it running.  If a persistent process is actually
7737                // repeatedly crashing, then badness for everyone.
7738                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7739                        app.info.processName);
7740                if (!app.isolated) {
7741                    // XXX We don't have a way to mark isolated processes
7742                    // as bad, since they don't have a peristent identity.
7743                    mBadProcesses.put(app.info.processName, app.uid, now);
7744                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7745                }
7746                app.bad = true;
7747                app.removed = true;
7748                // Don't let services in this process be restarted and potentially
7749                // annoy the user repeatedly.  Unless it is persistent, since those
7750                // processes run critical code.
7751                removeProcessLocked(app, false, false, "crash");
7752                mMainStack.resumeTopActivityLocked(null);
7753                return false;
7754            }
7755            mMainStack.resumeTopActivityLocked(null);
7756        } else {
7757            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7758            if (r != null && r.app == app) {
7759                // If the top running activity is from this crashing
7760                // process, then terminate it to avoid getting in a loop.
7761                Slog.w(TAG, "  Force finishing activity "
7762                        + r.intent.getComponent().flattenToShortString());
7763                int index = mMainStack.indexOfActivityLocked(r);
7764                r.stack.finishActivityLocked(r, index,
7765                        Activity.RESULT_CANCELED, null, "crashed");
7766                // Also terminate any activities below it that aren't yet
7767                // stopped, to avoid a situation where one will get
7768                // re-start our crashing activity once it gets resumed again.
7769                index--;
7770                if (index >= 0) {
7771                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7772                    if (r.state == ActivityState.RESUMED
7773                            || r.state == ActivityState.PAUSING
7774                            || r.state == ActivityState.PAUSED) {
7775                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7776                            Slog.w(TAG, "  Force finishing activity "
7777                                    + r.intent.getComponent().flattenToShortString());
7778                            r.stack.finishActivityLocked(r, index,
7779                                    Activity.RESULT_CANCELED, null, "crashed");
7780                        }
7781                    }
7782                }
7783            }
7784        }
7785
7786        // Bump up the crash count of any services currently running in the proc.
7787        if (app.services.size() != 0) {
7788            // Any services running in the application need to be placed
7789            // back in the pending list.
7790            Iterator<ServiceRecord> it = app.services.iterator();
7791            while (it.hasNext()) {
7792                ServiceRecord sr = it.next();
7793                sr.crashCount++;
7794            }
7795        }
7796
7797        // If the crashing process is what we consider to be the "home process" and it has been
7798        // replaced by a third-party app, clear the package preferred activities from packages
7799        // with a home activity running in the process to prevent a repeatedly crashing app
7800        // from blocking the user to manually clear the list.
7801        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7802                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7803            Iterator it = mHomeProcess.activities.iterator();
7804            while (it.hasNext()) {
7805                ActivityRecord r = (ActivityRecord)it.next();
7806                if (r.isHomeActivity) {
7807                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7808                    try {
7809                        ActivityThread.getPackageManager()
7810                                .clearPackagePreferredActivities(r.packageName);
7811                    } catch (RemoteException c) {
7812                        // pm is in same process, this will never happen.
7813                    }
7814                }
7815            }
7816        }
7817
7818        if (!app.isolated) {
7819            // XXX Can't keep track of crash times for isolated processes,
7820            // because they don't have a perisistent identity.
7821            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7822        }
7823
7824        return true;
7825    }
7826
7827    void startAppProblemLocked(ProcessRecord app) {
7828        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7829                mContext, app.info.packageName, app.info.flags);
7830        skipCurrentReceiverLocked(app);
7831    }
7832
7833    void skipCurrentReceiverLocked(ProcessRecord app) {
7834        for (BroadcastQueue queue : mBroadcastQueues) {
7835            queue.skipCurrentReceiverLocked(app);
7836        }
7837    }
7838
7839    /**
7840     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7841     * The application process will exit immediately after this call returns.
7842     * @param app object of the crashing app, null for the system server
7843     * @param crashInfo describing the exception
7844     */
7845    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7846        ProcessRecord r = findAppProcess(app, "Crash");
7847        final String processName = app == null ? "system_server"
7848                : (r == null ? "unknown" : r.processName);
7849
7850        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7851                processName,
7852                r == null ? -1 : r.info.flags,
7853                crashInfo.exceptionClassName,
7854                crashInfo.exceptionMessage,
7855                crashInfo.throwFileName,
7856                crashInfo.throwLineNumber);
7857
7858        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7859
7860        crashApplication(r, crashInfo);
7861    }
7862
7863    public void handleApplicationStrictModeViolation(
7864            IBinder app,
7865            int violationMask,
7866            StrictMode.ViolationInfo info) {
7867        ProcessRecord r = findAppProcess(app, "StrictMode");
7868        if (r == null) {
7869            return;
7870        }
7871
7872        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7873            Integer stackFingerprint = info.hashCode();
7874            boolean logIt = true;
7875            synchronized (mAlreadyLoggedViolatedStacks) {
7876                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7877                    logIt = false;
7878                    // TODO: sub-sample into EventLog for these, with
7879                    // the info.durationMillis?  Then we'd get
7880                    // the relative pain numbers, without logging all
7881                    // the stack traces repeatedly.  We'd want to do
7882                    // likewise in the client code, which also does
7883                    // dup suppression, before the Binder call.
7884                } else {
7885                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7886                        mAlreadyLoggedViolatedStacks.clear();
7887                    }
7888                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7889                }
7890            }
7891            if (logIt) {
7892                logStrictModeViolationToDropBox(r, info);
7893            }
7894        }
7895
7896        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7897            AppErrorResult result = new AppErrorResult();
7898            synchronized (this) {
7899                final long origId = Binder.clearCallingIdentity();
7900
7901                Message msg = Message.obtain();
7902                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7903                HashMap<String, Object> data = new HashMap<String, Object>();
7904                data.put("result", result);
7905                data.put("app", r);
7906                data.put("violationMask", violationMask);
7907                data.put("info", info);
7908                msg.obj = data;
7909                mHandler.sendMessage(msg);
7910
7911                Binder.restoreCallingIdentity(origId);
7912            }
7913            int res = result.get();
7914            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7915        }
7916    }
7917
7918    // Depending on the policy in effect, there could be a bunch of
7919    // these in quick succession so we try to batch these together to
7920    // minimize disk writes, number of dropbox entries, and maximize
7921    // compression, by having more fewer, larger records.
7922    private void logStrictModeViolationToDropBox(
7923            ProcessRecord process,
7924            StrictMode.ViolationInfo info) {
7925        if (info == null) {
7926            return;
7927        }
7928        final boolean isSystemApp = process == null ||
7929                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7930                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7931        final String processName = process == null ? "unknown" : process.processName;
7932        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7933        final DropBoxManager dbox = (DropBoxManager)
7934                mContext.getSystemService(Context.DROPBOX_SERVICE);
7935
7936        // Exit early if the dropbox isn't configured to accept this report type.
7937        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7938
7939        boolean bufferWasEmpty;
7940        boolean needsFlush;
7941        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7942        synchronized (sb) {
7943            bufferWasEmpty = sb.length() == 0;
7944            appendDropBoxProcessHeaders(process, processName, sb);
7945            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7946            sb.append("System-App: ").append(isSystemApp).append("\n");
7947            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7948            if (info.violationNumThisLoop != 0) {
7949                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7950            }
7951            if (info.numAnimationsRunning != 0) {
7952                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7953            }
7954            if (info.broadcastIntentAction != null) {
7955                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7956            }
7957            if (info.durationMillis != -1) {
7958                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7959            }
7960            if (info.numInstances != -1) {
7961                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7962            }
7963            if (info.tags != null) {
7964                for (String tag : info.tags) {
7965                    sb.append("Span-Tag: ").append(tag).append("\n");
7966                }
7967            }
7968            sb.append("\n");
7969            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7970                sb.append(info.crashInfo.stackTrace);
7971            }
7972            sb.append("\n");
7973
7974            // Only buffer up to ~64k.  Various logging bits truncate
7975            // things at 128k.
7976            needsFlush = (sb.length() > 64 * 1024);
7977        }
7978
7979        // Flush immediately if the buffer's grown too large, or this
7980        // is a non-system app.  Non-system apps are isolated with a
7981        // different tag & policy and not batched.
7982        //
7983        // Batching is useful during internal testing with
7984        // StrictMode settings turned up high.  Without batching,
7985        // thousands of separate files could be created on boot.
7986        if (!isSystemApp || needsFlush) {
7987            new Thread("Error dump: " + dropboxTag) {
7988                @Override
7989                public void run() {
7990                    String report;
7991                    synchronized (sb) {
7992                        report = sb.toString();
7993                        sb.delete(0, sb.length());
7994                        sb.trimToSize();
7995                    }
7996                    if (report.length() != 0) {
7997                        dbox.addText(dropboxTag, report);
7998                    }
7999                }
8000            }.start();
8001            return;
8002        }
8003
8004        // System app batching:
8005        if (!bufferWasEmpty) {
8006            // An existing dropbox-writing thread is outstanding, so
8007            // we don't need to start it up.  The existing thread will
8008            // catch the buffer appends we just did.
8009            return;
8010        }
8011
8012        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8013        // (After this point, we shouldn't access AMS internal data structures.)
8014        new Thread("Error dump: " + dropboxTag) {
8015            @Override
8016            public void run() {
8017                // 5 second sleep to let stacks arrive and be batched together
8018                try {
8019                    Thread.sleep(5000);  // 5 seconds
8020                } catch (InterruptedException e) {}
8021
8022                String errorReport;
8023                synchronized (mStrictModeBuffer) {
8024                    errorReport = mStrictModeBuffer.toString();
8025                    if (errorReport.length() == 0) {
8026                        return;
8027                    }
8028                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8029                    mStrictModeBuffer.trimToSize();
8030                }
8031                dbox.addText(dropboxTag, errorReport);
8032            }
8033        }.start();
8034    }
8035
8036    /**
8037     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8038     * @param app object of the crashing app, null for the system server
8039     * @param tag reported by the caller
8040     * @param crashInfo describing the context of the error
8041     * @return true if the process should exit immediately (WTF is fatal)
8042     */
8043    public boolean handleApplicationWtf(IBinder app, String tag,
8044            ApplicationErrorReport.CrashInfo crashInfo) {
8045        ProcessRecord r = findAppProcess(app, "WTF");
8046        final String processName = app == null ? "system_server"
8047                : (r == null ? "unknown" : r.processName);
8048
8049        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8050                processName,
8051                r == null ? -1 : r.info.flags,
8052                tag, crashInfo.exceptionMessage);
8053
8054        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8055
8056        if (r != null && r.pid != Process.myPid() &&
8057                Settings.Secure.getInt(mContext.getContentResolver(),
8058                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8059            crashApplication(r, crashInfo);
8060            return true;
8061        } else {
8062            return false;
8063        }
8064    }
8065
8066    /**
8067     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8068     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8069     */
8070    private ProcessRecord findAppProcess(IBinder app, String reason) {
8071        if (app == null) {
8072            return null;
8073        }
8074
8075        synchronized (this) {
8076            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8077                final int NA = apps.size();
8078                for (int ia=0; ia<NA; ia++) {
8079                    ProcessRecord p = apps.valueAt(ia);
8080                    if (p.thread != null && p.thread.asBinder() == app) {
8081                        return p;
8082                    }
8083                }
8084            }
8085
8086            Slog.w(TAG, "Can't find mystery application for " + reason
8087                    + " from pid=" + Binder.getCallingPid()
8088                    + " uid=" + Binder.getCallingUid() + ": " + app);
8089            return null;
8090        }
8091    }
8092
8093    /**
8094     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8095     * to append various headers to the dropbox log text.
8096     */
8097    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8098            StringBuilder sb) {
8099        // Watchdog thread ends up invoking this function (with
8100        // a null ProcessRecord) to add the stack file to dropbox.
8101        // Do not acquire a lock on this (am) in such cases, as it
8102        // could cause a potential deadlock, if and when watchdog
8103        // is invoked due to unavailability of lock on am and it
8104        // would prevent watchdog from killing system_server.
8105        if (process == null) {
8106            sb.append("Process: ").append(processName).append("\n");
8107            return;
8108        }
8109        // Note: ProcessRecord 'process' is guarded by the service
8110        // instance.  (notably process.pkgList, which could otherwise change
8111        // concurrently during execution of this method)
8112        synchronized (this) {
8113            sb.append("Process: ").append(processName).append("\n");
8114            int flags = process.info.flags;
8115            IPackageManager pm = AppGlobals.getPackageManager();
8116            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8117            for (String pkg : process.pkgList) {
8118                sb.append("Package: ").append(pkg);
8119                try {
8120                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8121                    if (pi != null) {
8122                        sb.append(" v").append(pi.versionCode);
8123                        if (pi.versionName != null) {
8124                            sb.append(" (").append(pi.versionName).append(")");
8125                        }
8126                    }
8127                } catch (RemoteException e) {
8128                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8129                }
8130                sb.append("\n");
8131            }
8132        }
8133    }
8134
8135    private static String processClass(ProcessRecord process) {
8136        if (process == null || process.pid == MY_PID) {
8137            return "system_server";
8138        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8139            return "system_app";
8140        } else {
8141            return "data_app";
8142        }
8143    }
8144
8145    /**
8146     * Write a description of an error (crash, WTF, ANR) to the drop box.
8147     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8148     * @param process which caused the error, null means the system server
8149     * @param activity which triggered the error, null if unknown
8150     * @param parent activity related to the error, null if unknown
8151     * @param subject line related to the error, null if absent
8152     * @param report in long form describing the error, null if absent
8153     * @param logFile to include in the report, null if none
8154     * @param crashInfo giving an application stack trace, null if absent
8155     */
8156    public void addErrorToDropBox(String eventType,
8157            ProcessRecord process, String processName, ActivityRecord activity,
8158            ActivityRecord parent, String subject,
8159            final String report, final File logFile,
8160            final ApplicationErrorReport.CrashInfo crashInfo) {
8161        // NOTE -- this must never acquire the ActivityManagerService lock,
8162        // otherwise the watchdog may be prevented from resetting the system.
8163
8164        final String dropboxTag = processClass(process) + "_" + eventType;
8165        final DropBoxManager dbox = (DropBoxManager)
8166                mContext.getSystemService(Context.DROPBOX_SERVICE);
8167
8168        // Exit early if the dropbox isn't configured to accept this report type.
8169        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8170
8171        final StringBuilder sb = new StringBuilder(1024);
8172        appendDropBoxProcessHeaders(process, processName, sb);
8173        if (activity != null) {
8174            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8175        }
8176        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8177            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8178        }
8179        if (parent != null && parent != activity) {
8180            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8181        }
8182        if (subject != null) {
8183            sb.append("Subject: ").append(subject).append("\n");
8184        }
8185        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8186        if (Debug.isDebuggerConnected()) {
8187            sb.append("Debugger: Connected\n");
8188        }
8189        sb.append("\n");
8190
8191        // Do the rest in a worker thread to avoid blocking the caller on I/O
8192        // (After this point, we shouldn't access AMS internal data structures.)
8193        Thread worker = new Thread("Error dump: " + dropboxTag) {
8194            @Override
8195            public void run() {
8196                if (report != null) {
8197                    sb.append(report);
8198                }
8199                if (logFile != null) {
8200                    try {
8201                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8202                    } catch (IOException e) {
8203                        Slog.e(TAG, "Error reading " + logFile, e);
8204                    }
8205                }
8206                if (crashInfo != null && crashInfo.stackTrace != null) {
8207                    sb.append(crashInfo.stackTrace);
8208                }
8209
8210                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8211                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8212                if (lines > 0) {
8213                    sb.append("\n");
8214
8215                    // Merge several logcat streams, and take the last N lines
8216                    InputStreamReader input = null;
8217                    try {
8218                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8219                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8220                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8221
8222                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8223                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8224                        input = new InputStreamReader(logcat.getInputStream());
8225
8226                        int num;
8227                        char[] buf = new char[8192];
8228                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8229                    } catch (IOException e) {
8230                        Slog.e(TAG, "Error running logcat", e);
8231                    } finally {
8232                        if (input != null) try { input.close(); } catch (IOException e) {}
8233                    }
8234                }
8235
8236                dbox.addText(dropboxTag, sb.toString());
8237            }
8238        };
8239
8240        if (process == null) {
8241            // If process is null, we are being called from some internal code
8242            // and may be about to die -- run this synchronously.
8243            worker.run();
8244        } else {
8245            worker.start();
8246        }
8247    }
8248
8249    /**
8250     * Bring up the "unexpected error" dialog box for a crashing app.
8251     * Deal with edge cases (intercepts from instrumented applications,
8252     * ActivityController, error intent receivers, that sort of thing).
8253     * @param r the application crashing
8254     * @param crashInfo describing the failure
8255     */
8256    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8257        long timeMillis = System.currentTimeMillis();
8258        String shortMsg = crashInfo.exceptionClassName;
8259        String longMsg = crashInfo.exceptionMessage;
8260        String stackTrace = crashInfo.stackTrace;
8261        if (shortMsg != null && longMsg != null) {
8262            longMsg = shortMsg + ": " + longMsg;
8263        } else if (shortMsg != null) {
8264            longMsg = shortMsg;
8265        }
8266
8267        AppErrorResult result = new AppErrorResult();
8268        synchronized (this) {
8269            if (mController != null) {
8270                try {
8271                    String name = r != null ? r.processName : null;
8272                    int pid = r != null ? r.pid : Binder.getCallingPid();
8273                    if (!mController.appCrashed(name, pid,
8274                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8275                        Slog.w(TAG, "Force-killing crashed app " + name
8276                                + " at watcher's request");
8277                        Process.killProcess(pid);
8278                        return;
8279                    }
8280                } catch (RemoteException e) {
8281                    mController = null;
8282                }
8283            }
8284
8285            final long origId = Binder.clearCallingIdentity();
8286
8287            // If this process is running instrumentation, finish it.
8288            if (r != null && r.instrumentationClass != null) {
8289                Slog.w(TAG, "Error in app " + r.processName
8290                      + " running instrumentation " + r.instrumentationClass + ":");
8291                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8292                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8293                Bundle info = new Bundle();
8294                info.putString("shortMsg", shortMsg);
8295                info.putString("longMsg", longMsg);
8296                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8297                Binder.restoreCallingIdentity(origId);
8298                return;
8299            }
8300
8301            // If we can't identify the process or it's already exceeded its crash quota,
8302            // quit right away without showing a crash dialog.
8303            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8304                Binder.restoreCallingIdentity(origId);
8305                return;
8306            }
8307
8308            Message msg = Message.obtain();
8309            msg.what = SHOW_ERROR_MSG;
8310            HashMap data = new HashMap();
8311            data.put("result", result);
8312            data.put("app", r);
8313            msg.obj = data;
8314            mHandler.sendMessage(msg);
8315
8316            Binder.restoreCallingIdentity(origId);
8317        }
8318
8319        int res = result.get();
8320
8321        Intent appErrorIntent = null;
8322        synchronized (this) {
8323            if (r != null && !r.isolated) {
8324                // XXX Can't keep track of crash time for isolated processes,
8325                // since they don't have a persistent identity.
8326                mProcessCrashTimes.put(r.info.processName, r.uid,
8327                        SystemClock.uptimeMillis());
8328            }
8329            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8330                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8331            }
8332        }
8333
8334        if (appErrorIntent != null) {
8335            try {
8336                mContext.startActivity(appErrorIntent);
8337            } catch (ActivityNotFoundException e) {
8338                Slog.w(TAG, "bug report receiver dissappeared", e);
8339            }
8340        }
8341    }
8342
8343    Intent createAppErrorIntentLocked(ProcessRecord r,
8344            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8345        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8346        if (report == null) {
8347            return null;
8348        }
8349        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8350        result.setComponent(r.errorReportReceiver);
8351        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8352        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8353        return result;
8354    }
8355
8356    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8357            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8358        if (r.errorReportReceiver == null) {
8359            return null;
8360        }
8361
8362        if (!r.crashing && !r.notResponding) {
8363            return null;
8364        }
8365
8366        ApplicationErrorReport report = new ApplicationErrorReport();
8367        report.packageName = r.info.packageName;
8368        report.installerPackageName = r.errorReportReceiver.getPackageName();
8369        report.processName = r.processName;
8370        report.time = timeMillis;
8371        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8372
8373        if (r.crashing) {
8374            report.type = ApplicationErrorReport.TYPE_CRASH;
8375            report.crashInfo = crashInfo;
8376        } else if (r.notResponding) {
8377            report.type = ApplicationErrorReport.TYPE_ANR;
8378            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8379
8380            report.anrInfo.activity = r.notRespondingReport.tag;
8381            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8382            report.anrInfo.info = r.notRespondingReport.longMsg;
8383        }
8384
8385        return report;
8386    }
8387
8388    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8389        enforceNotIsolatedCaller("getProcessesInErrorState");
8390        // assume our apps are happy - lazy create the list
8391        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8392
8393        final boolean allUsers = ActivityManager.checkUidPermission(
8394                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8395                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8396        int userId = UserHandle.getUserId(Binder.getCallingUid());
8397
8398        synchronized (this) {
8399
8400            // iterate across all processes
8401            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8402                ProcessRecord app = mLruProcesses.get(i);
8403                if (!allUsers && app.userId != userId) {
8404                    continue;
8405                }
8406                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8407                    // This one's in trouble, so we'll generate a report for it
8408                    // crashes are higher priority (in case there's a crash *and* an anr)
8409                    ActivityManager.ProcessErrorStateInfo report = null;
8410                    if (app.crashing) {
8411                        report = app.crashingReport;
8412                    } else if (app.notResponding) {
8413                        report = app.notRespondingReport;
8414                    }
8415
8416                    if (report != null) {
8417                        if (errList == null) {
8418                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8419                        }
8420                        errList.add(report);
8421                    } else {
8422                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8423                                " crashing = " + app.crashing +
8424                                " notResponding = " + app.notResponding);
8425                    }
8426                }
8427            }
8428        }
8429
8430        return errList;
8431    }
8432
8433    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8434        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8435            if (currApp != null) {
8436                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8437            }
8438            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8439        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8440            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8441        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8442            if (currApp != null) {
8443                currApp.lru = 0;
8444            }
8445            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8446        } else if (adj >= ProcessList.SERVICE_ADJ) {
8447            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8448        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8449            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8450        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8451            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8452        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8453            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8454        } else {
8455            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8456        }
8457    }
8458
8459    private void fillInProcMemInfo(ProcessRecord app,
8460            ActivityManager.RunningAppProcessInfo outInfo) {
8461        outInfo.pid = app.pid;
8462        outInfo.uid = app.info.uid;
8463        if (mHeavyWeightProcess == app) {
8464            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8465        }
8466        if (app.persistent) {
8467            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8468        }
8469        if (app.hasActivities) {
8470            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8471        }
8472        outInfo.lastTrimLevel = app.trimMemoryLevel;
8473        int adj = app.curAdj;
8474        outInfo.importance = oomAdjToImportance(adj, outInfo);
8475        outInfo.importanceReasonCode = app.adjTypeCode;
8476    }
8477
8478    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8479        enforceNotIsolatedCaller("getRunningAppProcesses");
8480        // Lazy instantiation of list
8481        List<ActivityManager.RunningAppProcessInfo> runList = null;
8482        final boolean allUsers = ActivityManager.checkUidPermission(
8483                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8484                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8485        int userId = UserHandle.getUserId(Binder.getCallingUid());
8486        synchronized (this) {
8487            // Iterate across all processes
8488            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8489                ProcessRecord app = mLruProcesses.get(i);
8490                if (!allUsers && app.userId != userId) {
8491                    continue;
8492                }
8493                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8494                    // Generate process state info for running application
8495                    ActivityManager.RunningAppProcessInfo currApp =
8496                        new ActivityManager.RunningAppProcessInfo(app.processName,
8497                                app.pid, app.getPackageList());
8498                    fillInProcMemInfo(app, currApp);
8499                    if (app.adjSource instanceof ProcessRecord) {
8500                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8501                        currApp.importanceReasonImportance = oomAdjToImportance(
8502                                app.adjSourceOom, null);
8503                    } else if (app.adjSource instanceof ActivityRecord) {
8504                        ActivityRecord r = (ActivityRecord)app.adjSource;
8505                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8506                    }
8507                    if (app.adjTarget instanceof ComponentName) {
8508                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8509                    }
8510                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8511                    //        + " lru=" + currApp.lru);
8512                    if (runList == null) {
8513                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8514                    }
8515                    runList.add(currApp);
8516                }
8517            }
8518        }
8519        return runList;
8520    }
8521
8522    public List<ApplicationInfo> getRunningExternalApplications() {
8523        enforceNotIsolatedCaller("getRunningExternalApplications");
8524        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8525        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8526        if (runningApps != null && runningApps.size() > 0) {
8527            Set<String> extList = new HashSet<String>();
8528            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8529                if (app.pkgList != null) {
8530                    for (String pkg : app.pkgList) {
8531                        extList.add(pkg);
8532                    }
8533                }
8534            }
8535            IPackageManager pm = AppGlobals.getPackageManager();
8536            for (String pkg : extList) {
8537                try {
8538                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8539                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8540                        retList.add(info);
8541                    }
8542                } catch (RemoteException e) {
8543                }
8544            }
8545        }
8546        return retList;
8547    }
8548
8549    @Override
8550    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8551        enforceNotIsolatedCaller("getMyMemoryState");
8552        synchronized (this) {
8553            ProcessRecord proc;
8554            synchronized (mPidsSelfLocked) {
8555                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8556            }
8557            fillInProcMemInfo(proc, outInfo);
8558        }
8559    }
8560
8561    @Override
8562    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8563        if (checkCallingPermission(android.Manifest.permission.DUMP)
8564                != PackageManager.PERMISSION_GRANTED) {
8565            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8566                    + Binder.getCallingPid()
8567                    + ", uid=" + Binder.getCallingUid()
8568                    + " without permission "
8569                    + android.Manifest.permission.DUMP);
8570            return;
8571        }
8572
8573        boolean dumpAll = false;
8574        boolean dumpClient = false;
8575        String dumpPackage = null;
8576
8577        int opti = 0;
8578        while (opti < args.length) {
8579            String opt = args[opti];
8580            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8581                break;
8582            }
8583            opti++;
8584            if ("-a".equals(opt)) {
8585                dumpAll = true;
8586            } else if ("-c".equals(opt)) {
8587                dumpClient = true;
8588            } else if ("-h".equals(opt)) {
8589                pw.println("Activity manager dump options:");
8590                pw.println("  [-a] [-c] [-h] [cmd] ...");
8591                pw.println("  cmd may be one of:");
8592                pw.println("    a[ctivities]: activity stack state");
8593                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8594                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8595                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8596                pw.println("    o[om]: out of memory management");
8597                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8598                pw.println("    provider [COMP_SPEC]: provider client-side state");
8599                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8600                pw.println("    service [COMP_SPEC]: service client-side state");
8601                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8602                pw.println("    all: dump all activities");
8603                pw.println("    top: dump the top activity");
8604                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8605                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8606                pw.println("    a partial substring in a component name, a");
8607                pw.println("    hex object identifier.");
8608                pw.println("  -a: include all available server state.");
8609                pw.println("  -c: include client state.");
8610                return;
8611            } else {
8612                pw.println("Unknown argument: " + opt + "; use -h for help");
8613            }
8614        }
8615
8616        long origId = Binder.clearCallingIdentity();
8617        boolean more = false;
8618        // Is the caller requesting to dump a particular piece of data?
8619        if (opti < args.length) {
8620            String cmd = args[opti];
8621            opti++;
8622            if ("activities".equals(cmd) || "a".equals(cmd)) {
8623                synchronized (this) {
8624                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8625                }
8626            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8627                String[] newArgs;
8628                String name;
8629                if (opti >= args.length) {
8630                    name = null;
8631                    newArgs = EMPTY_STRING_ARRAY;
8632                } else {
8633                    name = args[opti];
8634                    opti++;
8635                    newArgs = new String[args.length - opti];
8636                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8637                            args.length - opti);
8638                }
8639                synchronized (this) {
8640                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8641                }
8642            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8643                String[] newArgs;
8644                String name;
8645                if (opti >= args.length) {
8646                    name = null;
8647                    newArgs = EMPTY_STRING_ARRAY;
8648                } else {
8649                    name = args[opti];
8650                    opti++;
8651                    newArgs = new String[args.length - opti];
8652                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8653                            args.length - opti);
8654                }
8655                synchronized (this) {
8656                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8657                }
8658            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8659                String[] newArgs;
8660                String name;
8661                if (opti >= args.length) {
8662                    name = null;
8663                    newArgs = EMPTY_STRING_ARRAY;
8664                } else {
8665                    name = args[opti];
8666                    opti++;
8667                    newArgs = new String[args.length - opti];
8668                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8669                            args.length - opti);
8670                }
8671                synchronized (this) {
8672                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8673                }
8674            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8675                synchronized (this) {
8676                    dumpOomLocked(fd, pw, args, opti, true);
8677                }
8678            } else if ("provider".equals(cmd)) {
8679                String[] newArgs;
8680                String name;
8681                if (opti >= args.length) {
8682                    name = null;
8683                    newArgs = EMPTY_STRING_ARRAY;
8684                } else {
8685                    name = args[opti];
8686                    opti++;
8687                    newArgs = new String[args.length - opti];
8688                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8689                }
8690                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8691                    pw.println("No providers match: " + name);
8692                    pw.println("Use -h for help.");
8693                }
8694            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8695                synchronized (this) {
8696                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8697                }
8698            } else if ("service".equals(cmd)) {
8699                String[] newArgs;
8700                String name;
8701                if (opti >= args.length) {
8702                    name = null;
8703                    newArgs = EMPTY_STRING_ARRAY;
8704                } else {
8705                    name = args[opti];
8706                    opti++;
8707                    newArgs = new String[args.length - opti];
8708                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8709                            args.length - opti);
8710                }
8711                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8712                    pw.println("No services match: " + name);
8713                    pw.println("Use -h for help.");
8714                }
8715            } else if ("package".equals(cmd)) {
8716                String[] newArgs;
8717                if (opti >= args.length) {
8718                    pw.println("package: no package name specified");
8719                    pw.println("Use -h for help.");
8720                } else {
8721                    dumpPackage = args[opti];
8722                    opti++;
8723                    newArgs = new String[args.length - opti];
8724                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8725                            args.length - opti);
8726                    args = newArgs;
8727                    opti = 0;
8728                    more = true;
8729                }
8730            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8731                synchronized (this) {
8732                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8733                }
8734            } else {
8735                // Dumping a single activity?
8736                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8737                    pw.println("Bad activity command, or no activities match: " + cmd);
8738                    pw.println("Use -h for help.");
8739                }
8740            }
8741            if (!more) {
8742                Binder.restoreCallingIdentity(origId);
8743                return;
8744            }
8745        }
8746
8747        // No piece of data specified, dump everything.
8748        synchronized (this) {
8749            boolean needSep;
8750            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8751            if (needSep) {
8752                pw.println(" ");
8753            }
8754            if (dumpAll) {
8755                pw.println("-------------------------------------------------------------------------------");
8756            }
8757            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8758            if (needSep) {
8759                pw.println(" ");
8760            }
8761            if (dumpAll) {
8762                pw.println("-------------------------------------------------------------------------------");
8763            }
8764            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8765            if (needSep) {
8766                pw.println(" ");
8767            }
8768            if (dumpAll) {
8769                pw.println("-------------------------------------------------------------------------------");
8770            }
8771            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8772            if (needSep) {
8773                pw.println(" ");
8774            }
8775            if (dumpAll) {
8776                pw.println("-------------------------------------------------------------------------------");
8777            }
8778            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8779            if (needSep) {
8780                pw.println(" ");
8781            }
8782            if (dumpAll) {
8783                pw.println("-------------------------------------------------------------------------------");
8784            }
8785            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8786        }
8787        Binder.restoreCallingIdentity(origId);
8788    }
8789
8790    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8791            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8792        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8793        pw.println("  Main stack:");
8794        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8795                dumpPackage);
8796        pw.println(" ");
8797        pw.println("  Running activities (most recent first):");
8798        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8799                dumpPackage);
8800        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8801            pw.println(" ");
8802            pw.println("  Activities waiting for another to become visible:");
8803            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8804                    !dumpAll, false, dumpPackage);
8805        }
8806        if (mMainStack.mStoppingActivities.size() > 0) {
8807            pw.println(" ");
8808            pw.println("  Activities waiting to stop:");
8809            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8810                    !dumpAll, false, dumpPackage);
8811        }
8812        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8813            pw.println(" ");
8814            pw.println("  Activities waiting to sleep:");
8815            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8816                    !dumpAll, false, dumpPackage);
8817        }
8818        if (mMainStack.mFinishingActivities.size() > 0) {
8819            pw.println(" ");
8820            pw.println("  Activities waiting to finish:");
8821            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8822                    !dumpAll, false, dumpPackage);
8823        }
8824
8825        pw.println(" ");
8826        if (mMainStack.mPausingActivity != null) {
8827            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8828        }
8829        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8830        pw.println("  mFocusedActivity: " + mFocusedActivity);
8831        if (dumpAll) {
8832            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8833            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8834            pw.println("  mDismissKeyguardOnNextActivity: "
8835                    + mMainStack.mDismissKeyguardOnNextActivity);
8836        }
8837
8838        if (mRecentTasks.size() > 0) {
8839            pw.println();
8840            pw.println("  Recent tasks:");
8841
8842            final int N = mRecentTasks.size();
8843            for (int i=0; i<N; i++) {
8844                TaskRecord tr = mRecentTasks.get(i);
8845                if (dumpPackage != null) {
8846                    if (tr.realActivity == null ||
8847                            !dumpPackage.equals(tr.realActivity)) {
8848                        continue;
8849                    }
8850                }
8851                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8852                        pw.println(tr);
8853                if (dumpAll) {
8854                    mRecentTasks.get(i).dump(pw, "    ");
8855                }
8856            }
8857        }
8858
8859        if (dumpAll) {
8860            pw.println(" ");
8861            pw.println("  mCurTask: " + mCurTask);
8862        }
8863
8864        return true;
8865    }
8866
8867    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8868            int opti, boolean dumpAll, String dumpPackage) {
8869        boolean needSep = false;
8870        int numPers = 0;
8871
8872        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8873
8874        if (dumpAll) {
8875            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8876                final int NA = procs.size();
8877                for (int ia=0; ia<NA; ia++) {
8878                    ProcessRecord r = procs.valueAt(ia);
8879                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8880                        continue;
8881                    }
8882                    if (!needSep) {
8883                        pw.println("  All known processes:");
8884                        needSep = true;
8885                    }
8886                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8887                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8888                        pw.print(" "); pw.println(r);
8889                    r.dump(pw, "    ");
8890                    if (r.persistent) {
8891                        numPers++;
8892                    }
8893                }
8894            }
8895        }
8896
8897        if (mIsolatedProcesses.size() > 0) {
8898            if (needSep) pw.println(" ");
8899            needSep = true;
8900            pw.println("  Isolated process list (sorted by uid):");
8901            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8902                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8903                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8904                    continue;
8905                }
8906                pw.println(String.format("%sIsolated #%2d: %s",
8907                        "    ", i, r.toString()));
8908            }
8909        }
8910
8911        if (mLruProcesses.size() > 0) {
8912            if (needSep) pw.println(" ");
8913            needSep = true;
8914            pw.println("  Process LRU list (sorted by oom_adj):");
8915            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8916                    "Proc", "PERS", false, dumpPackage);
8917            needSep = true;
8918        }
8919
8920        if (dumpAll) {
8921            synchronized (mPidsSelfLocked) {
8922                boolean printed = false;
8923                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8924                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8925                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8926                        continue;
8927                    }
8928                    if (!printed) {
8929                        if (needSep) pw.println(" ");
8930                        needSep = true;
8931                        pw.println("  PID mappings:");
8932                        printed = true;
8933                    }
8934                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8935                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8936                }
8937            }
8938        }
8939
8940        if (mForegroundProcesses.size() > 0) {
8941            synchronized (mPidsSelfLocked) {
8942                boolean printed = false;
8943                for (int i=0; i<mForegroundProcesses.size(); i++) {
8944                    ProcessRecord r = mPidsSelfLocked.get(
8945                            mForegroundProcesses.valueAt(i).pid);
8946                    if (dumpPackage != null && (r == null
8947                            || !dumpPackage.equals(r.info.packageName))) {
8948                        continue;
8949                    }
8950                    if (!printed) {
8951                        if (needSep) pw.println(" ");
8952                        needSep = true;
8953                        pw.println("  Foreground Processes:");
8954                        printed = true;
8955                    }
8956                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8957                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8958                }
8959            }
8960        }
8961
8962        if (mPersistentStartingProcesses.size() > 0) {
8963            if (needSep) pw.println(" ");
8964            needSep = true;
8965            pw.println("  Persisent processes that are starting:");
8966            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8967                    "Starting Norm", "Restarting PERS", dumpPackage);
8968        }
8969
8970        if (mRemovedProcesses.size() > 0) {
8971            if (needSep) pw.println(" ");
8972            needSep = true;
8973            pw.println("  Processes that are being removed:");
8974            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8975                    "Removed Norm", "Removed PERS", dumpPackage);
8976        }
8977
8978        if (mProcessesOnHold.size() > 0) {
8979            if (needSep) pw.println(" ");
8980            needSep = true;
8981            pw.println("  Processes that are on old until the system is ready:");
8982            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8983                    "OnHold Norm", "OnHold PERS", dumpPackage);
8984        }
8985
8986        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8987
8988        if (mProcessCrashTimes.getMap().size() > 0) {
8989            boolean printed = false;
8990            long now = SystemClock.uptimeMillis();
8991            for (Map.Entry<String, SparseArray<Long>> procs
8992                    : mProcessCrashTimes.getMap().entrySet()) {
8993                String pname = procs.getKey();
8994                SparseArray<Long> uids = procs.getValue();
8995                final int N = uids.size();
8996                for (int i=0; i<N; i++) {
8997                    int puid = uids.keyAt(i);
8998                    ProcessRecord r = mProcessNames.get(pname, puid);
8999                    if (dumpPackage != null && (r == null
9000                            || !dumpPackage.equals(r.info.packageName))) {
9001                        continue;
9002                    }
9003                    if (!printed) {
9004                        if (needSep) pw.println(" ");
9005                        needSep = true;
9006                        pw.println("  Time since processes crashed:");
9007                        printed = true;
9008                    }
9009                    pw.print("    Process "); pw.print(pname);
9010                            pw.print(" uid "); pw.print(puid);
9011                            pw.print(": last crashed ");
9012                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9013                            pw.println(" ago");
9014                }
9015            }
9016        }
9017
9018        if (mBadProcesses.getMap().size() > 0) {
9019            boolean printed = false;
9020            for (Map.Entry<String, SparseArray<Long>> procs
9021                    : mBadProcesses.getMap().entrySet()) {
9022                String pname = procs.getKey();
9023                SparseArray<Long> uids = procs.getValue();
9024                final int N = uids.size();
9025                for (int i=0; i<N; i++) {
9026                    int puid = uids.keyAt(i);
9027                    ProcessRecord r = mProcessNames.get(pname, puid);
9028                    if (dumpPackage != null && (r == null
9029                            || !dumpPackage.equals(r.info.packageName))) {
9030                        continue;
9031                    }
9032                    if (!printed) {
9033                        if (needSep) pw.println(" ");
9034                        needSep = true;
9035                        pw.println("  Bad processes:");
9036                    }
9037                    pw.print("    Bad process "); pw.print(pname);
9038                            pw.print(" uid "); pw.print(puid);
9039                            pw.print(": crashed at time ");
9040                            pw.println(uids.valueAt(i));
9041                }
9042            }
9043        }
9044
9045        pw.println();
9046        pw.println("  mHomeProcess: " + mHomeProcess);
9047        pw.println("  mPreviousProcess: " + mPreviousProcess);
9048        if (dumpAll) {
9049            StringBuilder sb = new StringBuilder(128);
9050            sb.append("  mPreviousProcessVisibleTime: ");
9051            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9052            pw.println(sb);
9053        }
9054        if (mHeavyWeightProcess != null) {
9055            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9056        }
9057        pw.println("  mConfiguration: " + mConfiguration);
9058        if (dumpAll) {
9059            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9060            if (mCompatModePackages.getPackages().size() > 0) {
9061                boolean printed = false;
9062                for (Map.Entry<String, Integer> entry
9063                        : mCompatModePackages.getPackages().entrySet()) {
9064                    String pkg = entry.getKey();
9065                    int mode = entry.getValue();
9066                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9067                        continue;
9068                    }
9069                    if (!printed) {
9070                        pw.println("  mScreenCompatPackages:");
9071                        printed = true;
9072                    }
9073                    pw.print("    "); pw.print(pkg); pw.print(": ");
9074                            pw.print(mode); pw.println();
9075                }
9076            }
9077        }
9078        if (mSleeping || mWentToSleep || mLockScreenShown) {
9079            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9080                    + " mLockScreenShown " + mLockScreenShown);
9081        }
9082        if (mShuttingDown) {
9083            pw.println("  mShuttingDown=" + mShuttingDown);
9084        }
9085        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9086                || mOrigWaitForDebugger) {
9087            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9088                    + " mDebugTransient=" + mDebugTransient
9089                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9090        }
9091        if (mOpenGlTraceApp != null) {
9092            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9093        }
9094        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9095                || mProfileFd != null) {
9096            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9097            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9098            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9099                    + mAutoStopProfiler);
9100        }
9101        if (mAlwaysFinishActivities || mController != null) {
9102            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9103                    + " mController=" + mController);
9104        }
9105        if (dumpAll) {
9106            pw.println("  Total persistent processes: " + numPers);
9107            pw.println("  mStartRunning=" + mStartRunning
9108                    + " mProcessesReady=" + mProcessesReady
9109                    + " mSystemReady=" + mSystemReady);
9110            pw.println("  mBooting=" + mBooting
9111                    + " mBooted=" + mBooted
9112                    + " mFactoryTest=" + mFactoryTest);
9113            pw.print("  mLastPowerCheckRealtime=");
9114                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9115                    pw.println("");
9116            pw.print("  mLastPowerCheckUptime=");
9117                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9118                    pw.println("");
9119            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9120            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9121            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9122            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9123                    + " mNumHiddenProcs=" + mNumHiddenProcs
9124                    + " mNumServiceProcs=" + mNumServiceProcs
9125                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9126        }
9127
9128        return true;
9129    }
9130
9131    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9132            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9133        if (mProcessesToGc.size() > 0) {
9134            boolean printed = false;
9135            long now = SystemClock.uptimeMillis();
9136            for (int i=0; i<mProcessesToGc.size(); i++) {
9137                ProcessRecord proc = mProcessesToGc.get(i);
9138                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9139                    continue;
9140                }
9141                if (!printed) {
9142                    if (needSep) pw.println(" ");
9143                    needSep = true;
9144                    pw.println("  Processes that are waiting to GC:");
9145                    printed = true;
9146                }
9147                pw.print("    Process "); pw.println(proc);
9148                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9149                        pw.print(", last gced=");
9150                        pw.print(now-proc.lastRequestedGc);
9151                        pw.print(" ms ago, last lowMem=");
9152                        pw.print(now-proc.lastLowMemory);
9153                        pw.println(" ms ago");
9154
9155            }
9156        }
9157        return needSep;
9158    }
9159
9160    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9161            int opti, boolean dumpAll) {
9162        boolean needSep = false;
9163
9164        if (mLruProcesses.size() > 0) {
9165            if (needSep) pw.println(" ");
9166            needSep = true;
9167            pw.println("  OOM levels:");
9168            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9169            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9170            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9171            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9172            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9173            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9174            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9175            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9176            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9177            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9178            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9179            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9180            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9181
9182            if (needSep) pw.println(" ");
9183            needSep = true;
9184            pw.println("  Process OOM control:");
9185            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9186                    "Proc", "PERS", true, null);
9187            needSep = true;
9188        }
9189
9190        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9191
9192        pw.println();
9193        pw.println("  mHomeProcess: " + mHomeProcess);
9194        pw.println("  mPreviousProcess: " + mPreviousProcess);
9195        if (mHeavyWeightProcess != null) {
9196            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9197        }
9198
9199        return true;
9200    }
9201
9202    /**
9203     * There are three ways to call this:
9204     *  - no provider specified: dump all the providers
9205     *  - a flattened component name that matched an existing provider was specified as the
9206     *    first arg: dump that one provider
9207     *  - the first arg isn't the flattened component name of an existing provider:
9208     *    dump all providers whose component contains the first arg as a substring
9209     */
9210    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9211            int opti, boolean dumpAll) {
9212        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9213    }
9214
9215    static class ItemMatcher {
9216        ArrayList<ComponentName> components;
9217        ArrayList<String> strings;
9218        ArrayList<Integer> objects;
9219        boolean all;
9220
9221        ItemMatcher() {
9222            all = true;
9223        }
9224
9225        void build(String name) {
9226            ComponentName componentName = ComponentName.unflattenFromString(name);
9227            if (componentName != null) {
9228                if (components == null) {
9229                    components = new ArrayList<ComponentName>();
9230                }
9231                components.add(componentName);
9232                all = false;
9233            } else {
9234                int objectId = 0;
9235                // Not a '/' separated full component name; maybe an object ID?
9236                try {
9237                    objectId = Integer.parseInt(name, 16);
9238                    if (objects == null) {
9239                        objects = new ArrayList<Integer>();
9240                    }
9241                    objects.add(objectId);
9242                    all = false;
9243                } catch (RuntimeException e) {
9244                    // Not an integer; just do string match.
9245                    if (strings == null) {
9246                        strings = new ArrayList<String>();
9247                    }
9248                    strings.add(name);
9249                    all = false;
9250                }
9251            }
9252        }
9253
9254        int build(String[] args, int opti) {
9255            for (; opti<args.length; opti++) {
9256                String name = args[opti];
9257                if ("--".equals(name)) {
9258                    return opti+1;
9259                }
9260                build(name);
9261            }
9262            return opti;
9263        }
9264
9265        boolean match(Object object, ComponentName comp) {
9266            if (all) {
9267                return true;
9268            }
9269            if (components != null) {
9270                for (int i=0; i<components.size(); i++) {
9271                    if (components.get(i).equals(comp)) {
9272                        return true;
9273                    }
9274                }
9275            }
9276            if (objects != null) {
9277                for (int i=0; i<objects.size(); i++) {
9278                    if (System.identityHashCode(object) == objects.get(i)) {
9279                        return true;
9280                    }
9281                }
9282            }
9283            if (strings != null) {
9284                String flat = comp.flattenToString();
9285                for (int i=0; i<strings.size(); i++) {
9286                    if (flat.contains(strings.get(i))) {
9287                        return true;
9288                    }
9289                }
9290            }
9291            return false;
9292        }
9293    }
9294
9295    /**
9296     * There are three things that cmd can be:
9297     *  - a flattened component name that matches an existing activity
9298     *  - the cmd arg isn't the flattened component name of an existing activity:
9299     *    dump all activity whose component contains the cmd as a substring
9300     *  - A hex number of the ActivityRecord object instance.
9301     */
9302    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9303            int opti, boolean dumpAll) {
9304        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9305
9306        if ("all".equals(name)) {
9307            synchronized (this) {
9308                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9309                    activities.add(r1);
9310                }
9311            }
9312        } else if ("top".equals(name)) {
9313            synchronized (this) {
9314                final int N = mMainStack.mHistory.size();
9315                if (N > 0) {
9316                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9317                }
9318            }
9319        } else {
9320            ItemMatcher matcher = new ItemMatcher();
9321            matcher.build(name);
9322
9323            synchronized (this) {
9324                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9325                    if (matcher.match(r1, r1.intent.getComponent())) {
9326                        activities.add(r1);
9327                    }
9328                }
9329            }
9330        }
9331
9332        if (activities.size() <= 0) {
9333            return false;
9334        }
9335
9336        String[] newArgs = new String[args.length - opti];
9337        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9338
9339        TaskRecord lastTask = null;
9340        boolean needSep = false;
9341        for (int i=activities.size()-1; i>=0; i--) {
9342            ActivityRecord r = (ActivityRecord)activities.get(i);
9343            if (needSep) {
9344                pw.println();
9345            }
9346            needSep = true;
9347            synchronized (this) {
9348                if (lastTask != r.task) {
9349                    lastTask = r.task;
9350                    pw.print("TASK "); pw.print(lastTask.affinity);
9351                            pw.print(" id="); pw.println(lastTask.taskId);
9352                    if (dumpAll) {
9353                        lastTask.dump(pw, "  ");
9354                    }
9355                }
9356            }
9357            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9358        }
9359        return true;
9360    }
9361
9362    /**
9363     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9364     * there is a thread associated with the activity.
9365     */
9366    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9367            final ActivityRecord r, String[] args, boolean dumpAll) {
9368        String innerPrefix = prefix + "  ";
9369        synchronized (this) {
9370            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9371                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9372                    pw.print(" pid=");
9373                    if (r.app != null) pw.println(r.app.pid);
9374                    else pw.println("(not running)");
9375            if (dumpAll) {
9376                r.dump(pw, innerPrefix);
9377            }
9378        }
9379        if (r.app != null && r.app.thread != null) {
9380            // flush anything that is already in the PrintWriter since the thread is going
9381            // to write to the file descriptor directly
9382            pw.flush();
9383            try {
9384                TransferPipe tp = new TransferPipe();
9385                try {
9386                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9387                            r.appToken, innerPrefix, args);
9388                    tp.go(fd);
9389                } finally {
9390                    tp.kill();
9391                }
9392            } catch (IOException e) {
9393                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9394            } catch (RemoteException e) {
9395                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9396            }
9397        }
9398    }
9399
9400    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9401            int opti, boolean dumpAll, String dumpPackage) {
9402        boolean needSep = false;
9403
9404        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9405        if (dumpAll) {
9406            if (mRegisteredReceivers.size() > 0) {
9407                boolean printed = false;
9408                Iterator it = mRegisteredReceivers.values().iterator();
9409                while (it.hasNext()) {
9410                    ReceiverList r = (ReceiverList)it.next();
9411                    if (dumpPackage != null && (r.app == null ||
9412                            !dumpPackage.equals(r.app.info.packageName))) {
9413                        continue;
9414                    }
9415                    if (!printed) {
9416                        pw.println("  Registered Receivers:");
9417                        needSep = true;
9418                        printed = true;
9419                    }
9420                    pw.print("  * "); pw.println(r);
9421                    r.dump(pw, "    ");
9422                }
9423            }
9424
9425            if (mReceiverResolver.dump(pw, needSep ?
9426                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9427                    "    ", dumpPackage, false)) {
9428                needSep = true;
9429            }
9430        }
9431
9432        for (BroadcastQueue q : mBroadcastQueues) {
9433            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9434        }
9435
9436        needSep = true;
9437
9438        if (mStickyBroadcasts != null && dumpPackage == null) {
9439            if (needSep) {
9440                pw.println();
9441            }
9442            needSep = true;
9443            pw.println("  Sticky broadcasts:");
9444            StringBuilder sb = new StringBuilder(128);
9445            for (Map.Entry<String, ArrayList<Intent>> ent
9446                    : mStickyBroadcasts.entrySet()) {
9447                pw.print("  * Sticky action "); pw.print(ent.getKey());
9448                if (dumpAll) {
9449                    pw.println(":");
9450                    ArrayList<Intent> intents = ent.getValue();
9451                    final int N = intents.size();
9452                    for (int i=0; i<N; i++) {
9453                        sb.setLength(0);
9454                        sb.append("    Intent: ");
9455                        intents.get(i).toShortString(sb, false, true, false, false);
9456                        pw.println(sb.toString());
9457                        Bundle bundle = intents.get(i).getExtras();
9458                        if (bundle != null) {
9459                            pw.print("      ");
9460                            pw.println(bundle.toString());
9461                        }
9462                    }
9463                } else {
9464                    pw.println("");
9465                }
9466            }
9467            needSep = true;
9468        }
9469
9470        if (dumpAll) {
9471            pw.println();
9472            for (BroadcastQueue queue : mBroadcastQueues) {
9473                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9474                        + queue.mBroadcastsScheduled);
9475            }
9476            pw.println("  mHandler:");
9477            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9478            needSep = true;
9479        }
9480
9481        return needSep;
9482    }
9483
9484    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9485            int opti, boolean dumpAll, String dumpPackage) {
9486        boolean needSep = true;
9487
9488        ItemMatcher matcher = new ItemMatcher();
9489        matcher.build(args, opti);
9490
9491        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9492
9493        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9494
9495        if (mLaunchingProviders.size() > 0) {
9496            boolean printed = false;
9497            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9498                ContentProviderRecord r = mLaunchingProviders.get(i);
9499                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9500                    continue;
9501                }
9502                if (!printed) {
9503                    if (needSep) pw.println(" ");
9504                    needSep = true;
9505                    pw.println("  Launching content providers:");
9506                    printed = true;
9507                }
9508                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9509                        pw.println(r);
9510            }
9511        }
9512
9513        if (mGrantedUriPermissions.size() > 0) {
9514            if (needSep) pw.println();
9515            needSep = true;
9516            pw.println("Granted Uri Permissions:");
9517            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9518                int uid = mGrantedUriPermissions.keyAt(i);
9519                HashMap<Uri, UriPermission> perms
9520                        = mGrantedUriPermissions.valueAt(i);
9521                pw.print("  * UID "); pw.print(uid);
9522                        pw.println(" holds:");
9523                for (UriPermission perm : perms.values()) {
9524                    pw.print("    "); pw.println(perm);
9525                    if (dumpAll) {
9526                        perm.dump(pw, "      ");
9527                    }
9528                }
9529            }
9530            needSep = true;
9531        }
9532
9533        return needSep;
9534    }
9535
9536    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9537            int opti, boolean dumpAll, String dumpPackage) {
9538        boolean needSep = false;
9539
9540        if (mIntentSenderRecords.size() > 0) {
9541            boolean printed = false;
9542            Iterator<WeakReference<PendingIntentRecord>> it
9543                    = mIntentSenderRecords.values().iterator();
9544            while (it.hasNext()) {
9545                WeakReference<PendingIntentRecord> ref = it.next();
9546                PendingIntentRecord rec = ref != null ? ref.get(): null;
9547                if (dumpPackage != null && (rec == null
9548                        || !dumpPackage.equals(rec.key.packageName))) {
9549                    continue;
9550                }
9551                if (!printed) {
9552                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9553                    printed = true;
9554                }
9555                needSep = true;
9556                if (rec != null) {
9557                    pw.print("  * "); pw.println(rec);
9558                    if (dumpAll) {
9559                        rec.dump(pw, "    ");
9560                    }
9561                } else {
9562                    pw.print("  * "); pw.println(ref);
9563                }
9564            }
9565        }
9566
9567        return needSep;
9568    }
9569
9570    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9571            String prefix, String label, boolean complete, boolean brief, boolean client,
9572            String dumpPackage) {
9573        TaskRecord lastTask = null;
9574        boolean needNL = false;
9575        final String innerPrefix = prefix + "      ";
9576        final String[] args = new String[0];
9577        for (int i=list.size()-1; i>=0; i--) {
9578            final ActivityRecord r = (ActivityRecord)list.get(i);
9579            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9580                continue;
9581            }
9582            final boolean full = !brief && (complete || !r.isInHistory());
9583            if (needNL) {
9584                pw.println(" ");
9585                needNL = false;
9586            }
9587            if (lastTask != r.task) {
9588                lastTask = r.task;
9589                pw.print(prefix);
9590                pw.print(full ? "* " : "  ");
9591                pw.println(lastTask);
9592                if (full) {
9593                    lastTask.dump(pw, prefix + "  ");
9594                } else if (complete) {
9595                    // Complete + brief == give a summary.  Isn't that obvious?!?
9596                    if (lastTask.intent != null) {
9597                        pw.print(prefix); pw.print("  ");
9598                                pw.println(lastTask.intent.toInsecureStringWithClip());
9599                    }
9600                }
9601            }
9602            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9603            pw.print(" #"); pw.print(i); pw.print(": ");
9604            pw.println(r);
9605            if (full) {
9606                r.dump(pw, innerPrefix);
9607            } else if (complete) {
9608                // Complete + brief == give a summary.  Isn't that obvious?!?
9609                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9610                if (r.app != null) {
9611                    pw.print(innerPrefix); pw.println(r.app);
9612                }
9613            }
9614            if (client && r.app != null && r.app.thread != null) {
9615                // flush anything that is already in the PrintWriter since the thread is going
9616                // to write to the file descriptor directly
9617                pw.flush();
9618                try {
9619                    TransferPipe tp = new TransferPipe();
9620                    try {
9621                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9622                                r.appToken, innerPrefix, args);
9623                        // Short timeout, since blocking here can
9624                        // deadlock with the application.
9625                        tp.go(fd, 2000);
9626                    } finally {
9627                        tp.kill();
9628                    }
9629                } catch (IOException e) {
9630                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9631                } catch (RemoteException e) {
9632                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9633                }
9634                needNL = true;
9635            }
9636        }
9637    }
9638
9639    private static String buildOomTag(String prefix, String space, int val, int base) {
9640        if (val == base) {
9641            if (space == null) return prefix;
9642            return prefix + "  ";
9643        }
9644        return prefix + "+" + Integer.toString(val-base);
9645    }
9646
9647    private static final int dumpProcessList(PrintWriter pw,
9648            ActivityManagerService service, List list,
9649            String prefix, String normalLabel, String persistentLabel,
9650            String dumpPackage) {
9651        int numPers = 0;
9652        final int N = list.size()-1;
9653        for (int i=N; i>=0; i--) {
9654            ProcessRecord r = (ProcessRecord)list.get(i);
9655            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9656                continue;
9657            }
9658            pw.println(String.format("%s%s #%2d: %s",
9659                    prefix, (r.persistent ? persistentLabel : normalLabel),
9660                    i, r.toString()));
9661            if (r.persistent) {
9662                numPers++;
9663            }
9664        }
9665        return numPers;
9666    }
9667
9668    private static final boolean dumpProcessOomList(PrintWriter pw,
9669            ActivityManagerService service, List<ProcessRecord> origList,
9670            String prefix, String normalLabel, String persistentLabel,
9671            boolean inclDetails, String dumpPackage) {
9672
9673        ArrayList<Pair<ProcessRecord, Integer>> list
9674                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9675        for (int i=0; i<origList.size(); i++) {
9676            ProcessRecord r = origList.get(i);
9677            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9678                continue;
9679            }
9680            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9681        }
9682
9683        if (list.size() <= 0) {
9684            return false;
9685        }
9686
9687        Comparator<Pair<ProcessRecord, Integer>> comparator
9688                = new Comparator<Pair<ProcessRecord, Integer>>() {
9689            @Override
9690            public int compare(Pair<ProcessRecord, Integer> object1,
9691                    Pair<ProcessRecord, Integer> object2) {
9692                if (object1.first.setAdj != object2.first.setAdj) {
9693                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9694                }
9695                if (object1.second.intValue() != object2.second.intValue()) {
9696                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9697                }
9698                return 0;
9699            }
9700        };
9701
9702        Collections.sort(list, comparator);
9703
9704        final long curRealtime = SystemClock.elapsedRealtime();
9705        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9706        final long curUptime = SystemClock.uptimeMillis();
9707        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9708
9709        for (int i=list.size()-1; i>=0; i--) {
9710            ProcessRecord r = list.get(i).first;
9711            String oomAdj;
9712            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9713                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9714            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9715                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9716            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9717                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9718            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9719                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9720            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9721                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9722            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9723                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9724            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9725                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9726            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9727                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9728            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9729                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9730            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9731                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9732            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9733                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9734            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9735                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9736            } else {
9737                oomAdj = Integer.toString(r.setAdj);
9738            }
9739            String schedGroup;
9740            switch (r.setSchedGroup) {
9741                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9742                    schedGroup = "B";
9743                    break;
9744                case Process.THREAD_GROUP_DEFAULT:
9745                    schedGroup = "F";
9746                    break;
9747                default:
9748                    schedGroup = Integer.toString(r.setSchedGroup);
9749                    break;
9750            }
9751            String foreground;
9752            if (r.foregroundActivities) {
9753                foreground = "A";
9754            } else if (r.foregroundServices) {
9755                foreground = "S";
9756            } else {
9757                foreground = " ";
9758            }
9759            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9760                    prefix, (r.persistent ? persistentLabel : normalLabel),
9761                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9762                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9763            if (r.adjSource != null || r.adjTarget != null) {
9764                pw.print(prefix);
9765                pw.print("    ");
9766                if (r.adjTarget instanceof ComponentName) {
9767                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9768                } else if (r.adjTarget != null) {
9769                    pw.print(r.adjTarget.toString());
9770                } else {
9771                    pw.print("{null}");
9772                }
9773                pw.print("<=");
9774                if (r.adjSource instanceof ProcessRecord) {
9775                    pw.print("Proc{");
9776                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9777                    pw.println("}");
9778                } else if (r.adjSource != null) {
9779                    pw.println(r.adjSource.toString());
9780                } else {
9781                    pw.println("{null}");
9782                }
9783            }
9784            if (inclDetails) {
9785                pw.print(prefix);
9786                pw.print("    ");
9787                pw.print("oom: max="); pw.print(r.maxAdj);
9788                pw.print(" hidden="); pw.print(r.hiddenAdj);
9789                pw.print(" empty="); pw.print(r.emptyAdj);
9790                pw.print(" curRaw="); pw.print(r.curRawAdj);
9791                pw.print(" setRaw="); pw.print(r.setRawAdj);
9792                pw.print(" cur="); pw.print(r.curAdj);
9793                pw.print(" set="); pw.println(r.setAdj);
9794                pw.print(prefix);
9795                pw.print("    ");
9796                pw.print("keeping="); pw.print(r.keeping);
9797                pw.print(" hidden="); pw.print(r.hidden);
9798                pw.print(" empty="); pw.print(r.empty);
9799                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9800
9801                if (!r.keeping) {
9802                    if (r.lastWakeTime != 0) {
9803                        long wtime;
9804                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9805                        synchronized (stats) {
9806                            wtime = stats.getProcessWakeTime(r.info.uid,
9807                                    r.pid, curRealtime);
9808                        }
9809                        long timeUsed = wtime - r.lastWakeTime;
9810                        pw.print(prefix);
9811                        pw.print("    ");
9812                        pw.print("keep awake over ");
9813                        TimeUtils.formatDuration(realtimeSince, pw);
9814                        pw.print(" used ");
9815                        TimeUtils.formatDuration(timeUsed, pw);
9816                        pw.print(" (");
9817                        pw.print((timeUsed*100)/realtimeSince);
9818                        pw.println("%)");
9819                    }
9820                    if (r.lastCpuTime != 0) {
9821                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9822                        pw.print(prefix);
9823                        pw.print("    ");
9824                        pw.print("run cpu over ");
9825                        TimeUtils.formatDuration(uptimeSince, pw);
9826                        pw.print(" used ");
9827                        TimeUtils.formatDuration(timeUsed, pw);
9828                        pw.print(" (");
9829                        pw.print((timeUsed*100)/uptimeSince);
9830                        pw.println("%)");
9831                    }
9832                }
9833            }
9834        }
9835        return true;
9836    }
9837
9838    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9839        ArrayList<ProcessRecord> procs;
9840        synchronized (this) {
9841            if (args != null && args.length > start
9842                    && args[start].charAt(0) != '-') {
9843                procs = new ArrayList<ProcessRecord>();
9844                int pid = -1;
9845                try {
9846                    pid = Integer.parseInt(args[start]);
9847                } catch (NumberFormatException e) {
9848
9849                }
9850                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9851                    ProcessRecord proc = mLruProcesses.get(i);
9852                    if (proc.pid == pid) {
9853                        procs.add(proc);
9854                    } else if (proc.processName.equals(args[start])) {
9855                        procs.add(proc);
9856                    }
9857                }
9858                if (procs.size() <= 0) {
9859                    pw.println("No process found for: " + args[start]);
9860                    return null;
9861                }
9862            } else {
9863                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9864            }
9865        }
9866        return procs;
9867    }
9868
9869    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9870            PrintWriter pw, String[] args) {
9871        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9872        if (procs == null) {
9873            return;
9874        }
9875
9876        long uptime = SystemClock.uptimeMillis();
9877        long realtime = SystemClock.elapsedRealtime();
9878        pw.println("Applications Graphics Acceleration Info:");
9879        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9880
9881        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9882            ProcessRecord r = procs.get(i);
9883            if (r.thread != null) {
9884                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9885                pw.flush();
9886                try {
9887                    TransferPipe tp = new TransferPipe();
9888                    try {
9889                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9890                        tp.go(fd);
9891                    } finally {
9892                        tp.kill();
9893                    }
9894                } catch (IOException e) {
9895                    pw.println("Failure while dumping the app: " + r);
9896                    pw.flush();
9897                } catch (RemoteException e) {
9898                    pw.println("Got a RemoteException while dumping the app " + r);
9899                    pw.flush();
9900                }
9901            }
9902        }
9903    }
9904
9905    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9906        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9907        if (procs == null) {
9908            return;
9909        }
9910
9911        pw.println("Applications Database Info:");
9912
9913        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9914            ProcessRecord r = procs.get(i);
9915            if (r.thread != null) {
9916                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9917                pw.flush();
9918                try {
9919                    TransferPipe tp = new TransferPipe();
9920                    try {
9921                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9922                        tp.go(fd);
9923                    } finally {
9924                        tp.kill();
9925                    }
9926                } catch (IOException e) {
9927                    pw.println("Failure while dumping the app: " + r);
9928                    pw.flush();
9929                } catch (RemoteException e) {
9930                    pw.println("Got a RemoteException while dumping the app " + r);
9931                    pw.flush();
9932                }
9933            }
9934        }
9935    }
9936
9937    final static class MemItem {
9938        final String label;
9939        final String shortLabel;
9940        final long pss;
9941        final int id;
9942        ArrayList<MemItem> subitems;
9943
9944        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9945            label = _label;
9946            shortLabel = _shortLabel;
9947            pss = _pss;
9948            id = _id;
9949        }
9950    }
9951
9952    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9953            boolean sort) {
9954        if (sort) {
9955            Collections.sort(items, new Comparator<MemItem>() {
9956                @Override
9957                public int compare(MemItem lhs, MemItem rhs) {
9958                    if (lhs.pss < rhs.pss) {
9959                        return 1;
9960                    } else if (lhs.pss > rhs.pss) {
9961                        return -1;
9962                    }
9963                    return 0;
9964                }
9965            });
9966        }
9967
9968        for (int i=0; i<items.size(); i++) {
9969            MemItem mi = items.get(i);
9970            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9971            if (mi.subitems != null) {
9972                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9973            }
9974        }
9975    }
9976
9977    // These are in KB.
9978    static final long[] DUMP_MEM_BUCKETS = new long[] {
9979        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9980        120*1024, 160*1024, 200*1024,
9981        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9982        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9983    };
9984
9985    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9986            boolean stackLike) {
9987        int start = label.lastIndexOf('.');
9988        if (start >= 0) start++;
9989        else start = 0;
9990        int end = label.length();
9991        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9992            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9993                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9994                out.append(bucket);
9995                out.append(stackLike ? "MB." : "MB ");
9996                out.append(label, start, end);
9997                return;
9998            }
9999        }
10000        out.append(memKB/1024);
10001        out.append(stackLike ? "MB." : "MB ");
10002        out.append(label, start, end);
10003    }
10004
10005    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10006            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10007            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10008            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10009            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10010    };
10011    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10012            "System", "Persistent", "Foreground",
10013            "Visible", "Perceptible", "Heavy Weight",
10014            "Backup", "A Services", "Home", "Previous",
10015            "B Services", "Background"
10016    };
10017
10018    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10019            PrintWriter pw, String prefix, String[] args, boolean brief,
10020            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10021        boolean dumpAll = false;
10022        boolean oomOnly = false;
10023
10024        int opti = 0;
10025        while (opti < args.length) {
10026            String opt = args[opti];
10027            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10028                break;
10029            }
10030            opti++;
10031            if ("-a".equals(opt)) {
10032                dumpAll = true;
10033            } else if ("--oom".equals(opt)) {
10034                oomOnly = true;
10035            } else if ("-h".equals(opt)) {
10036                pw.println("meminfo dump options: [-a] [--oom] [process]");
10037                pw.println("  -a: include all available information for each process.");
10038                pw.println("  --oom: only show processes organized by oom adj.");
10039                pw.println("If [process] is specified it can be the name or ");
10040                pw.println("pid of a specific process to dump.");
10041                return;
10042            } else {
10043                pw.println("Unknown argument: " + opt + "; use -h for help");
10044            }
10045        }
10046
10047        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10048        if (procs == null) {
10049            return;
10050        }
10051
10052        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10053        long uptime = SystemClock.uptimeMillis();
10054        long realtime = SystemClock.elapsedRealtime();
10055
10056        if (procs.size() == 1 || isCheckinRequest) {
10057            dumpAll = true;
10058        }
10059
10060        if (isCheckinRequest) {
10061            // short checkin version
10062            pw.println(uptime + "," + realtime);
10063            pw.flush();
10064        } else {
10065            pw.println("Applications Memory Usage (kB):");
10066            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10067        }
10068
10069        String[] innerArgs = new String[args.length-opti];
10070        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10071
10072        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10073        long nativePss=0, dalvikPss=0, otherPss=0;
10074        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10075
10076        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10077        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10078                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10079
10080        long totalPss = 0;
10081
10082        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10083            ProcessRecord r = procs.get(i);
10084            if (r.thread != null) {
10085                if (!isCheckinRequest && dumpAll) {
10086                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10087                    pw.flush();
10088                }
10089                Debug.MemoryInfo mi = null;
10090                if (dumpAll) {
10091                    try {
10092                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10093                    } catch (RemoteException e) {
10094                        if (!isCheckinRequest) {
10095                            pw.println("Got RemoteException!");
10096                            pw.flush();
10097                        }
10098                    }
10099                } else {
10100                    mi = new Debug.MemoryInfo();
10101                    Debug.getMemoryInfo(r.pid, mi);
10102                }
10103
10104                if (!isCheckinRequest && mi != null) {
10105                    long myTotalPss = mi.getTotalPss();
10106                    totalPss += myTotalPss;
10107                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10108                            r.processName, myTotalPss, 0);
10109                    procMems.add(pssItem);
10110
10111                    nativePss += mi.nativePss;
10112                    dalvikPss += mi.dalvikPss;
10113                    otherPss += mi.otherPss;
10114                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10115                        long mem = mi.getOtherPss(j);
10116                        miscPss[j] += mem;
10117                        otherPss -= mem;
10118                    }
10119
10120                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10121                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10122                                || oomIndex == (oomPss.length-1)) {
10123                            oomPss[oomIndex] += myTotalPss;
10124                            if (oomProcs[oomIndex] == null) {
10125                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10126                            }
10127                            oomProcs[oomIndex].add(pssItem);
10128                            break;
10129                        }
10130                    }
10131                }
10132            }
10133        }
10134
10135        if (!isCheckinRequest && procs.size() > 1) {
10136            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10137
10138            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10139            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10140            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10141            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10142                String label = Debug.MemoryInfo.getOtherLabel(j);
10143                catMems.add(new MemItem(label, label, miscPss[j], j));
10144            }
10145
10146            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10147            for (int j=0; j<oomPss.length; j++) {
10148                if (oomPss[j] != 0) {
10149                    String label = DUMP_MEM_OOM_LABEL[j];
10150                    MemItem item = new MemItem(label, label, oomPss[j],
10151                            DUMP_MEM_OOM_ADJ[j]);
10152                    item.subitems = oomProcs[j];
10153                    oomMems.add(item);
10154                }
10155            }
10156
10157            if (outTag != null || outStack != null) {
10158                if (outTag != null) {
10159                    appendMemBucket(outTag, totalPss, "total", false);
10160                }
10161                if (outStack != null) {
10162                    appendMemBucket(outStack, totalPss, "total", true);
10163                }
10164                boolean firstLine = true;
10165                for (int i=0; i<oomMems.size(); i++) {
10166                    MemItem miCat = oomMems.get(i);
10167                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10168                        continue;
10169                    }
10170                    if (miCat.id < ProcessList.SERVICE_ADJ
10171                            || miCat.id == ProcessList.HOME_APP_ADJ
10172                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10173                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10174                            outTag.append(" / ");
10175                        }
10176                        if (outStack != null) {
10177                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10178                                if (firstLine) {
10179                                    outStack.append(":");
10180                                    firstLine = false;
10181                                }
10182                                outStack.append("\n\t at ");
10183                            } else {
10184                                outStack.append("$");
10185                            }
10186                        }
10187                        for (int j=0; j<miCat.subitems.size(); j++) {
10188                            MemItem mi = miCat.subitems.get(j);
10189                            if (j > 0) {
10190                                if (outTag != null) {
10191                                    outTag.append(" ");
10192                                }
10193                                if (outStack != null) {
10194                                    outStack.append("$");
10195                                }
10196                            }
10197                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10198                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10199                            }
10200                            if (outStack != null) {
10201                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10202                            }
10203                        }
10204                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10205                            outStack.append("(");
10206                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10207                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10208                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10209                                    outStack.append(":");
10210                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10211                                }
10212                            }
10213                            outStack.append(")");
10214                        }
10215                    }
10216                }
10217            }
10218
10219            if (!brief && !oomOnly) {
10220                pw.println();
10221                pw.println("Total PSS by process:");
10222                dumpMemItems(pw, "  ", procMems, true);
10223                pw.println();
10224            }
10225            pw.println("Total PSS by OOM adjustment:");
10226            dumpMemItems(pw, "  ", oomMems, false);
10227            if (!oomOnly) {
10228                PrintWriter out = categoryPw != null ? categoryPw : pw;
10229                out.println();
10230                out.println("Total PSS by category:");
10231                dumpMemItems(out, "  ", catMems, true);
10232            }
10233            pw.println();
10234            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10235            final int[] SINGLE_LONG_FORMAT = new int[] {
10236                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10237            };
10238            long[] longOut = new long[1];
10239            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10240                    SINGLE_LONG_FORMAT, null, longOut, null);
10241            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10242            longOut[0] = 0;
10243            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10244                    SINGLE_LONG_FORMAT, null, longOut, null);
10245            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10246            longOut[0] = 0;
10247            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10248                    SINGLE_LONG_FORMAT, null, longOut, null);
10249            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10250            longOut[0] = 0;
10251            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10252                    SINGLE_LONG_FORMAT, null, longOut, null);
10253            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10254            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10255                    pw.print(shared); pw.println(" kB");
10256            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10257                    pw.print(voltile); pw.println(" kB volatile");
10258        }
10259    }
10260
10261    /**
10262     * Searches array of arguments for the specified string
10263     * @param args array of argument strings
10264     * @param value value to search for
10265     * @return true if the value is contained in the array
10266     */
10267    private static boolean scanArgs(String[] args, String value) {
10268        if (args != null) {
10269            for (String arg : args) {
10270                if (value.equals(arg)) {
10271                    return true;
10272                }
10273            }
10274        }
10275        return false;
10276    }
10277
10278    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10279            ContentProviderRecord cpr, boolean always) {
10280        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10281
10282        if (!inLaunching || always) {
10283            synchronized (cpr) {
10284                cpr.launchingApp = null;
10285                cpr.notifyAll();
10286            }
10287            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10288            String names[] = cpr.info.authority.split(";");
10289            for (int j = 0; j < names.length; j++) {
10290                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10291            }
10292        }
10293
10294        for (int i=0; i<cpr.connections.size(); i++) {
10295            ContentProviderConnection conn = cpr.connections.get(i);
10296            if (conn.waiting) {
10297                // If this connection is waiting for the provider, then we don't
10298                // need to mess with its process unless we are always removing
10299                // or for some reason the provider is not currently launching.
10300                if (inLaunching && !always) {
10301                    continue;
10302                }
10303            }
10304            ProcessRecord capp = conn.client;
10305            conn.dead = true;
10306            if (conn.stableCount > 0) {
10307                if (!capp.persistent && capp.thread != null
10308                        && capp.pid != 0
10309                        && capp.pid != MY_PID) {
10310                    Slog.i(TAG, "Kill " + capp.processName
10311                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10312                            + " in dying process " + (proc != null ? proc.processName : "??"));
10313                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10314                            capp.processName, capp.setAdj, "dying provider "
10315                                    + cpr.name.toShortString());
10316                    Process.killProcessQuiet(capp.pid);
10317                }
10318            } else if (capp.thread != null && conn.provider.provider != null) {
10319                try {
10320                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10321                } catch (RemoteException e) {
10322                }
10323                // In the protocol here, we don't expect the client to correctly
10324                // clean up this connection, we'll just remove it.
10325                cpr.connections.remove(i);
10326                conn.client.conProviders.remove(conn);
10327            }
10328        }
10329
10330        if (inLaunching && always) {
10331            mLaunchingProviders.remove(cpr);
10332        }
10333        return inLaunching;
10334    }
10335
10336    /**
10337     * Main code for cleaning up a process when it has gone away.  This is
10338     * called both as a result of the process dying, or directly when stopping
10339     * a process when running in single process mode.
10340     */
10341    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10342            boolean restarting, boolean allowRestart, int index) {
10343        if (index >= 0) {
10344            mLruProcesses.remove(index);
10345        }
10346
10347        mProcessesToGc.remove(app);
10348
10349        // Dismiss any open dialogs.
10350        if (app.crashDialog != null) {
10351            app.crashDialog.dismiss();
10352            app.crashDialog = null;
10353        }
10354        if (app.anrDialog != null) {
10355            app.anrDialog.dismiss();
10356            app.anrDialog = null;
10357        }
10358        if (app.waitDialog != null) {
10359            app.waitDialog.dismiss();
10360            app.waitDialog = null;
10361        }
10362
10363        app.crashing = false;
10364        app.notResponding = false;
10365
10366        app.resetPackageList();
10367        app.unlinkDeathRecipient();
10368        app.thread = null;
10369        app.forcingToForeground = null;
10370        app.foregroundServices = false;
10371        app.foregroundActivities = false;
10372        app.hasShownUi = false;
10373        app.hasAboveClient = false;
10374
10375        mServices.killServicesLocked(app, allowRestart);
10376
10377        boolean restart = false;
10378
10379        // Remove published content providers.
10380        if (!app.pubProviders.isEmpty()) {
10381            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10382            while (it.hasNext()) {
10383                ContentProviderRecord cpr = it.next();
10384
10385                final boolean always = app.bad || !allowRestart;
10386                if (removeDyingProviderLocked(app, cpr, always) || always) {
10387                    // We left the provider in the launching list, need to
10388                    // restart it.
10389                    restart = true;
10390                }
10391
10392                cpr.provider = null;
10393                cpr.proc = null;
10394            }
10395            app.pubProviders.clear();
10396        }
10397
10398        // Take care of any launching providers waiting for this process.
10399        if (checkAppInLaunchingProvidersLocked(app, false)) {
10400            restart = true;
10401        }
10402
10403        // Unregister from connected content providers.
10404        if (!app.conProviders.isEmpty()) {
10405            for (int i=0; i<app.conProviders.size(); i++) {
10406                ContentProviderConnection conn = app.conProviders.get(i);
10407                conn.provider.connections.remove(conn);
10408            }
10409            app.conProviders.clear();
10410        }
10411
10412        // At this point there may be remaining entries in mLaunchingProviders
10413        // where we were the only one waiting, so they are no longer of use.
10414        // Look for these and clean up if found.
10415        // XXX Commented out for now.  Trying to figure out a way to reproduce
10416        // the actual situation to identify what is actually going on.
10417        if (false) {
10418            for (int i=0; i<mLaunchingProviders.size(); i++) {
10419                ContentProviderRecord cpr = (ContentProviderRecord)
10420                        mLaunchingProviders.get(i);
10421                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10422                    synchronized (cpr) {
10423                        cpr.launchingApp = null;
10424                        cpr.notifyAll();
10425                    }
10426                }
10427            }
10428        }
10429
10430        skipCurrentReceiverLocked(app);
10431
10432        // Unregister any receivers.
10433        if (app.receivers.size() > 0) {
10434            Iterator<ReceiverList> it = app.receivers.iterator();
10435            while (it.hasNext()) {
10436                removeReceiverLocked(it.next());
10437            }
10438            app.receivers.clear();
10439        }
10440
10441        // If the app is undergoing backup, tell the backup manager about it
10442        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10443            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10444            try {
10445                IBackupManager bm = IBackupManager.Stub.asInterface(
10446                        ServiceManager.getService(Context.BACKUP_SERVICE));
10447                bm.agentDisconnected(app.info.packageName);
10448            } catch (RemoteException e) {
10449                // can't happen; backup manager is local
10450            }
10451        }
10452
10453        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10454            ProcessChangeItem item = mPendingProcessChanges.get(i);
10455            if (item.pid == app.pid) {
10456                mPendingProcessChanges.remove(i);
10457                mAvailProcessChanges.add(item);
10458            }
10459        }
10460        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10461
10462        // If the caller is restarting this app, then leave it in its
10463        // current lists and let the caller take care of it.
10464        if (restarting) {
10465            return;
10466        }
10467
10468        if (!app.persistent || app.isolated) {
10469            if (DEBUG_PROCESSES) Slog.v(TAG,
10470                    "Removing non-persistent process during cleanup: " + app);
10471            mProcessNames.remove(app.processName, app.uid);
10472            mIsolatedProcesses.remove(app.uid);
10473            if (mHeavyWeightProcess == app) {
10474                mHeavyWeightProcess = null;
10475                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10476            }
10477        } else if (!app.removed) {
10478            // This app is persistent, so we need to keep its record around.
10479            // If it is not already on the pending app list, add it there
10480            // and start a new process for it.
10481            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10482                mPersistentStartingProcesses.add(app);
10483                restart = true;
10484            }
10485        }
10486        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10487                "Clean-up removing on hold: " + app);
10488        mProcessesOnHold.remove(app);
10489
10490        if (app == mHomeProcess) {
10491            mHomeProcess = null;
10492        }
10493        if (app == mPreviousProcess) {
10494            mPreviousProcess = null;
10495        }
10496
10497        if (restart && !app.isolated) {
10498            // We have components that still need to be running in the
10499            // process, so re-launch it.
10500            mProcessNames.put(app.processName, app.uid, app);
10501            startProcessLocked(app, "restart", app.processName);
10502        } else if (app.pid > 0 && app.pid != MY_PID) {
10503            // Goodbye!
10504            synchronized (mPidsSelfLocked) {
10505                mPidsSelfLocked.remove(app.pid);
10506                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10507            }
10508            app.setPid(0);
10509        }
10510    }
10511
10512    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10513        // Look through the content providers we are waiting to have launched,
10514        // and if any run in this process then either schedule a restart of
10515        // the process or kill the client waiting for it if this process has
10516        // gone bad.
10517        int NL = mLaunchingProviders.size();
10518        boolean restart = false;
10519        for (int i=0; i<NL; i++) {
10520            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10521            if (cpr.launchingApp == app) {
10522                if (!alwaysBad && !app.bad) {
10523                    restart = true;
10524                } else {
10525                    removeDyingProviderLocked(app, cpr, true);
10526                    NL = mLaunchingProviders.size();
10527                }
10528            }
10529        }
10530        return restart;
10531    }
10532
10533    // =========================================================
10534    // SERVICES
10535    // =========================================================
10536
10537    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10538            int flags) {
10539        enforceNotIsolatedCaller("getServices");
10540        synchronized (this) {
10541            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10542        }
10543    }
10544
10545    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10546        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10547        synchronized (this) {
10548            return mServices.getRunningServiceControlPanelLocked(name);
10549        }
10550    }
10551
10552    public ComponentName startService(IApplicationThread caller, Intent service,
10553            String resolvedType) {
10554        enforceNotIsolatedCaller("startService");
10555        // Refuse possible leaked file descriptors
10556        if (service != null && service.hasFileDescriptors() == true) {
10557            throw new IllegalArgumentException("File descriptors passed in Intent");
10558        }
10559
10560        if (DEBUG_SERVICE)
10561            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10562        synchronized(this) {
10563            final int callingPid = Binder.getCallingPid();
10564            final int callingUid = Binder.getCallingUid();
10565            final long origId = Binder.clearCallingIdentity();
10566            ComponentName res = mServices.startServiceLocked(caller, service,
10567                    resolvedType, callingPid, callingUid);
10568            Binder.restoreCallingIdentity(origId);
10569            return res;
10570        }
10571    }
10572
10573    ComponentName startServiceInPackage(int uid,
10574            Intent service, String resolvedType) {
10575        synchronized(this) {
10576            if (DEBUG_SERVICE)
10577                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10578            final long origId = Binder.clearCallingIdentity();
10579            ComponentName res = mServices.startServiceLocked(null, service,
10580                    resolvedType, -1, uid);
10581            Binder.restoreCallingIdentity(origId);
10582            return res;
10583        }
10584    }
10585
10586    public int stopService(IApplicationThread caller, Intent service,
10587            String resolvedType) {
10588        enforceNotIsolatedCaller("stopService");
10589        // Refuse possible leaked file descriptors
10590        if (service != null && service.hasFileDescriptors() == true) {
10591            throw new IllegalArgumentException("File descriptors passed in Intent");
10592        }
10593
10594        synchronized(this) {
10595            return mServices.stopServiceLocked(caller, service, resolvedType);
10596        }
10597    }
10598
10599    public IBinder peekService(Intent service, String resolvedType) {
10600        enforceNotIsolatedCaller("peekService");
10601        // Refuse possible leaked file descriptors
10602        if (service != null && service.hasFileDescriptors() == true) {
10603            throw new IllegalArgumentException("File descriptors passed in Intent");
10604        }
10605        synchronized(this) {
10606            return mServices.peekServiceLocked(service, resolvedType);
10607        }
10608    }
10609
10610    public boolean stopServiceToken(ComponentName className, IBinder token,
10611            int startId) {
10612        synchronized(this) {
10613            return mServices.stopServiceTokenLocked(className, token, startId);
10614        }
10615    }
10616
10617    public void setServiceForeground(ComponentName className, IBinder token,
10618            int id, Notification notification, boolean removeNotification) {
10619        synchronized(this) {
10620            mServices.setServiceForegroundLocked(className, token, id, notification,
10621                    removeNotification);
10622        }
10623    }
10624
10625    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10626            String className, int flags) {
10627        boolean result = false;
10628        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10629            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10630                if (ActivityManager.checkUidPermission(
10631                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10632                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10633                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10634                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10635                            + " requests FLAG_SINGLE_USER, but app does not hold "
10636                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10637                    Slog.w(TAG, msg);
10638                    throw new SecurityException(msg);
10639                }
10640                result = true;
10641            }
10642        } else if (componentProcessName == aInfo.packageName) {
10643            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10644        } else if ("system".equals(componentProcessName)) {
10645            result = true;
10646        }
10647        if (DEBUG_MU) {
10648            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10649                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10650        }
10651        return result;
10652    }
10653
10654    public int bindService(IApplicationThread caller, IBinder token,
10655            Intent service, String resolvedType,
10656            IServiceConnection connection, int flags, int userId) {
10657        enforceNotIsolatedCaller("bindService");
10658        // Refuse possible leaked file descriptors
10659        if (service != null && service.hasFileDescriptors() == true) {
10660            throw new IllegalArgumentException("File descriptors passed in Intent");
10661        }
10662
10663        checkValidCaller(Binder.getCallingUid(), userId);
10664
10665        synchronized(this) {
10666            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10667                    connection, flags, userId);
10668        }
10669    }
10670
10671    public boolean unbindService(IServiceConnection connection) {
10672        synchronized (this) {
10673            return mServices.unbindServiceLocked(connection);
10674        }
10675    }
10676
10677    public void publishService(IBinder token, Intent intent, IBinder service) {
10678        // Refuse possible leaked file descriptors
10679        if (intent != null && intent.hasFileDescriptors() == true) {
10680            throw new IllegalArgumentException("File descriptors passed in Intent");
10681        }
10682
10683        synchronized(this) {
10684            if (!(token instanceof ServiceRecord)) {
10685                throw new IllegalArgumentException("Invalid service token");
10686            }
10687            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10688        }
10689    }
10690
10691    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10692        // Refuse possible leaked file descriptors
10693        if (intent != null && intent.hasFileDescriptors() == true) {
10694            throw new IllegalArgumentException("File descriptors passed in Intent");
10695        }
10696
10697        synchronized(this) {
10698            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10699        }
10700    }
10701
10702    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10703        synchronized(this) {
10704            if (!(token instanceof ServiceRecord)) {
10705                throw new IllegalArgumentException("Invalid service token");
10706            }
10707            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10708        }
10709    }
10710
10711    // =========================================================
10712    // BACKUP AND RESTORE
10713    // =========================================================
10714
10715    // Cause the target app to be launched if necessary and its backup agent
10716    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10717    // activity manager to announce its creation.
10718    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10719        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10720        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10721
10722        synchronized(this) {
10723            // !!! TODO: currently no check here that we're already bound
10724            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10725            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10726            synchronized (stats) {
10727                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10728            }
10729
10730            // Backup agent is now in use, its package can't be stopped.
10731            try {
10732                AppGlobals.getPackageManager().setPackageStoppedState(
10733                        app.packageName, false, UserHandle.getUserId(app.uid));
10734            } catch (RemoteException e) {
10735            } catch (IllegalArgumentException e) {
10736                Slog.w(TAG, "Failed trying to unstop package "
10737                        + app.packageName + ": " + e);
10738            }
10739
10740            BackupRecord r = new BackupRecord(ss, app, backupMode);
10741            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10742                    ? new ComponentName(app.packageName, app.backupAgentName)
10743                    : new ComponentName("android", "FullBackupAgent");
10744            // startProcessLocked() returns existing proc's record if it's already running
10745            ProcessRecord proc = startProcessLocked(app.processName, app,
10746                    false, 0, "backup", hostingName, false, false);
10747            if (proc == null) {
10748                Slog.e(TAG, "Unable to start backup agent process " + r);
10749                return false;
10750            }
10751
10752            r.app = proc;
10753            mBackupTarget = r;
10754            mBackupAppName = app.packageName;
10755
10756            // Try not to kill the process during backup
10757            updateOomAdjLocked(proc);
10758
10759            // If the process is already attached, schedule the creation of the backup agent now.
10760            // If it is not yet live, this will be done when it attaches to the framework.
10761            if (proc.thread != null) {
10762                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10763                try {
10764                    proc.thread.scheduleCreateBackupAgent(app,
10765                            compatibilityInfoForPackageLocked(app), backupMode);
10766                } catch (RemoteException e) {
10767                    // Will time out on the backup manager side
10768                }
10769            } else {
10770                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10771            }
10772            // Invariants: at this point, the target app process exists and the application
10773            // is either already running or in the process of coming up.  mBackupTarget and
10774            // mBackupAppName describe the app, so that when it binds back to the AM we
10775            // know that it's scheduled for a backup-agent operation.
10776        }
10777
10778        return true;
10779    }
10780
10781    // A backup agent has just come up
10782    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10783        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10784                + " = " + agent);
10785
10786        synchronized(this) {
10787            if (!agentPackageName.equals(mBackupAppName)) {
10788                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10789                return;
10790            }
10791        }
10792
10793        long oldIdent = Binder.clearCallingIdentity();
10794        try {
10795            IBackupManager bm = IBackupManager.Stub.asInterface(
10796                    ServiceManager.getService(Context.BACKUP_SERVICE));
10797            bm.agentConnected(agentPackageName, agent);
10798        } catch (RemoteException e) {
10799            // can't happen; the backup manager service is local
10800        } catch (Exception e) {
10801            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10802            e.printStackTrace();
10803        } finally {
10804            Binder.restoreCallingIdentity(oldIdent);
10805        }
10806    }
10807
10808    // done with this agent
10809    public void unbindBackupAgent(ApplicationInfo appInfo) {
10810        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10811        if (appInfo == null) {
10812            Slog.w(TAG, "unbind backup agent for null app");
10813            return;
10814        }
10815
10816        synchronized(this) {
10817            if (mBackupAppName == null) {
10818                Slog.w(TAG, "Unbinding backup agent with no active backup");
10819                return;
10820            }
10821
10822            if (!mBackupAppName.equals(appInfo.packageName)) {
10823                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10824                return;
10825            }
10826
10827            ProcessRecord proc = mBackupTarget.app;
10828            mBackupTarget = null;
10829            mBackupAppName = null;
10830
10831            // Not backing this app up any more; reset its OOM adjustment
10832            updateOomAdjLocked(proc);
10833
10834            // If the app crashed during backup, 'thread' will be null here
10835            if (proc.thread != null) {
10836                try {
10837                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10838                            compatibilityInfoForPackageLocked(appInfo));
10839                } catch (Exception e) {
10840                    Slog.e(TAG, "Exception when unbinding backup agent:");
10841                    e.printStackTrace();
10842                }
10843            }
10844        }
10845    }
10846    // =========================================================
10847    // BROADCASTS
10848    // =========================================================
10849
10850    private final List getStickiesLocked(String action, IntentFilter filter,
10851            List cur) {
10852        final ContentResolver resolver = mContext.getContentResolver();
10853        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10854        if (list == null) {
10855            return cur;
10856        }
10857        int N = list.size();
10858        for (int i=0; i<N; i++) {
10859            Intent intent = list.get(i);
10860            if (filter.match(resolver, intent, true, TAG) >= 0) {
10861                if (cur == null) {
10862                    cur = new ArrayList<Intent>();
10863                }
10864                cur.add(intent);
10865            }
10866        }
10867        return cur;
10868    }
10869
10870    boolean isPendingBroadcastProcessLocked(int pid) {
10871        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10872                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10873    }
10874
10875    void skipPendingBroadcastLocked(int pid) {
10876            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10877            for (BroadcastQueue queue : mBroadcastQueues) {
10878                queue.skipPendingBroadcastLocked(pid);
10879            }
10880    }
10881
10882    // The app just attached; send any pending broadcasts that it should receive
10883    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10884        boolean didSomething = false;
10885        for (BroadcastQueue queue : mBroadcastQueues) {
10886            didSomething |= queue.sendPendingBroadcastsLocked(app);
10887        }
10888        return didSomething;
10889    }
10890
10891    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10892            IIntentReceiver receiver, IntentFilter filter, String permission) {
10893        enforceNotIsolatedCaller("registerReceiver");
10894        int callingUid;
10895        synchronized(this) {
10896            ProcessRecord callerApp = null;
10897            if (caller != null) {
10898                callerApp = getRecordForAppLocked(caller);
10899                if (callerApp == null) {
10900                    throw new SecurityException(
10901                            "Unable to find app for caller " + caller
10902                            + " (pid=" + Binder.getCallingPid()
10903                            + ") when registering receiver " + receiver);
10904                }
10905                if (callerApp.info.uid != Process.SYSTEM_UID &&
10906                        !callerApp.pkgList.contains(callerPackage)) {
10907                    throw new SecurityException("Given caller package " + callerPackage
10908                            + " is not running in process " + callerApp);
10909                }
10910                callingUid = callerApp.info.uid;
10911            } else {
10912                callerPackage = null;
10913                callingUid = Binder.getCallingUid();
10914            }
10915
10916            List allSticky = null;
10917
10918            // Look for any matching sticky broadcasts...
10919            Iterator actions = filter.actionsIterator();
10920            if (actions != null) {
10921                while (actions.hasNext()) {
10922                    String action = (String)actions.next();
10923                    allSticky = getStickiesLocked(action, filter, allSticky);
10924                }
10925            } else {
10926                allSticky = getStickiesLocked(null, filter, allSticky);
10927            }
10928
10929            // The first sticky in the list is returned directly back to
10930            // the client.
10931            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10932
10933            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10934                    + ": " + sticky);
10935
10936            if (receiver == null) {
10937                return sticky;
10938            }
10939
10940            ReceiverList rl
10941                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10942            if (rl == null) {
10943                rl = new ReceiverList(this, callerApp,
10944                        Binder.getCallingPid(),
10945                        Binder.getCallingUid(), receiver);
10946                if (rl.app != null) {
10947                    rl.app.receivers.add(rl);
10948                } else {
10949                    try {
10950                        receiver.asBinder().linkToDeath(rl, 0);
10951                    } catch (RemoteException e) {
10952                        return sticky;
10953                    }
10954                    rl.linkedToDeath = true;
10955                }
10956                mRegisteredReceivers.put(receiver.asBinder(), rl);
10957            }
10958            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10959                    permission, callingUid);
10960            rl.add(bf);
10961            if (!bf.debugCheck()) {
10962                Slog.w(TAG, "==> For Dynamic broadast");
10963            }
10964            mReceiverResolver.addFilter(bf);
10965
10966            // Enqueue broadcasts for all existing stickies that match
10967            // this filter.
10968            if (allSticky != null) {
10969                ArrayList receivers = new ArrayList();
10970                receivers.add(bf);
10971
10972                int N = allSticky.size();
10973                for (int i=0; i<N; i++) {
10974                    Intent intent = (Intent)allSticky.get(i);
10975                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10976                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10977                            null, -1, -1, null, receivers, null, 0, null, null,
10978                            false, true, true, false);
10979                    queue.enqueueParallelBroadcastLocked(r);
10980                    queue.scheduleBroadcastsLocked();
10981                }
10982            }
10983
10984            return sticky;
10985        }
10986    }
10987
10988    public void unregisterReceiver(IIntentReceiver receiver) {
10989        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10990
10991        final long origId = Binder.clearCallingIdentity();
10992        try {
10993            boolean doTrim = false;
10994
10995            synchronized(this) {
10996                ReceiverList rl
10997                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10998                if (rl != null) {
10999                    if (rl.curBroadcast != null) {
11000                        BroadcastRecord r = rl.curBroadcast;
11001                        final boolean doNext = finishReceiverLocked(
11002                                receiver.asBinder(), r.resultCode, r.resultData,
11003                                r.resultExtras, r.resultAbort, true);
11004                        if (doNext) {
11005                            doTrim = true;
11006                            r.queue.processNextBroadcast(false);
11007                        }
11008                    }
11009
11010                    if (rl.app != null) {
11011                        rl.app.receivers.remove(rl);
11012                    }
11013                    removeReceiverLocked(rl);
11014                    if (rl.linkedToDeath) {
11015                        rl.linkedToDeath = false;
11016                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11017                    }
11018                }
11019            }
11020
11021            // If we actually concluded any broadcasts, we might now be able
11022            // to trim the recipients' apps from our working set
11023            if (doTrim) {
11024                trimApplications();
11025                return;
11026            }
11027
11028        } finally {
11029            Binder.restoreCallingIdentity(origId);
11030        }
11031    }
11032
11033    void removeReceiverLocked(ReceiverList rl) {
11034        mRegisteredReceivers.remove(rl.receiver.asBinder());
11035        int N = rl.size();
11036        for (int i=0; i<N; i++) {
11037            mReceiverResolver.removeFilter(rl.get(i));
11038        }
11039    }
11040
11041    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11042        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11043            ProcessRecord r = mLruProcesses.get(i);
11044            if (r.thread != null) {
11045                try {
11046                    r.thread.dispatchPackageBroadcast(cmd, packages);
11047                } catch (RemoteException ex) {
11048                }
11049            }
11050        }
11051    }
11052
11053    private final int broadcastIntentLocked(ProcessRecord callerApp,
11054            String callerPackage, Intent intent, String resolvedType,
11055            IIntentReceiver resultTo, int resultCode, String resultData,
11056            Bundle map, String requiredPermission,
11057            boolean ordered, boolean sticky, int callingPid, int callingUid,
11058            int userId) {
11059        intent = new Intent(intent);
11060
11061        // By default broadcasts do not go to stopped apps.
11062        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11063
11064        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11065            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11066            + " ordered=" + ordered + " userid=" + userId);
11067        if ((resultTo != null) && !ordered) {
11068            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11069        }
11070
11071        boolean onlySendToCaller = false;
11072
11073        // If the caller is trying to send this broadcast to a different
11074        // user, verify that is allowed.
11075        if (UserHandle.getUserId(callingUid) != userId) {
11076            if (checkComponentPermission(
11077                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11078                    callingPid, callingUid, -1, true)
11079                    != PackageManager.PERMISSION_GRANTED) {
11080                if (checkComponentPermission(
11081                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11082                        callingPid, callingUid, -1, true)
11083                        == PackageManager.PERMISSION_GRANTED) {
11084                    onlySendToCaller = true;
11085                } else {
11086                    String msg = "Permission Denial: " + intent.getAction()
11087                            + " broadcast from " + callerPackage
11088                            + " asks to send as user " + userId
11089                            + " but is calling from user " + UserHandle.getUserId(callingUid)
11090                            + "; this requires "
11091                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11092                    Slog.w(TAG, msg);
11093                    throw new SecurityException(msg);
11094                }
11095            }
11096        }
11097
11098        // Handle special intents: if this broadcast is from the package
11099        // manager about a package being removed, we need to remove all of
11100        // its activities from the history stack.
11101        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11102                intent.getAction());
11103        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11104                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11105                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11106                || uidRemoved) {
11107            if (checkComponentPermission(
11108                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11109                    callingPid, callingUid, -1, true)
11110                    == PackageManager.PERMISSION_GRANTED) {
11111                if (uidRemoved) {
11112                    final Bundle intentExtras = intent.getExtras();
11113                    final int uid = intentExtras != null
11114                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11115                    if (uid >= 0) {
11116                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11117                        synchronized (bs) {
11118                            bs.removeUidStatsLocked(uid);
11119                        }
11120                    }
11121                } else {
11122                    // If resources are unvailble just force stop all
11123                    // those packages and flush the attribute cache as well.
11124                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11125                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11126                        if (list != null && (list.length > 0)) {
11127                            for (String pkg : list) {
11128                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11129                            }
11130                            sendPackageBroadcastLocked(
11131                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11132                        }
11133                    } else {
11134                        Uri data = intent.getData();
11135                        String ssp;
11136                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11137                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11138                                forceStopPackageLocked(ssp,
11139                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11140                                        false, userId);
11141                            }
11142                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11143                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11144                                        new String[] {ssp});
11145                            }
11146                        }
11147                    }
11148                }
11149            } else {
11150                String msg = "Permission Denial: " + intent.getAction()
11151                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11152                        + ", uid=" + callingUid + ")"
11153                        + " requires "
11154                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11155                Slog.w(TAG, msg);
11156                throw new SecurityException(msg);
11157            }
11158
11159        // Special case for adding a package: by default turn on compatibility
11160        // mode.
11161        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11162            Uri data = intent.getData();
11163            String ssp;
11164            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11165                mCompatModePackages.handlePackageAddedLocked(ssp,
11166                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11167            }
11168        }
11169
11170        /*
11171         * If this is the time zone changed action, queue up a message that will reset the timezone
11172         * of all currently running processes. This message will get queued up before the broadcast
11173         * happens.
11174         */
11175        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11176            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11177        }
11178
11179        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11180            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11181        }
11182
11183        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11184            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11185            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11186        }
11187
11188        /*
11189         * Prevent non-system code (defined here to be non-persistent
11190         * processes) from sending protected broadcasts.
11191         */
11192        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11193            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11194            callingUid == 0) {
11195            // Always okay.
11196        } else if (callerApp == null || !callerApp.persistent) {
11197            try {
11198                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11199                        intent.getAction())) {
11200                    String msg = "Permission Denial: not allowed to send broadcast "
11201                            + intent.getAction() + " from pid="
11202                            + callingPid + ", uid=" + callingUid;
11203                    Slog.w(TAG, msg);
11204                    throw new SecurityException(msg);
11205                }
11206            } catch (RemoteException e) {
11207                Slog.w(TAG, "Remote exception", e);
11208                return ActivityManager.BROADCAST_SUCCESS;
11209            }
11210        }
11211
11212        // Add to the sticky list if requested.
11213        if (sticky) {
11214            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11215                    callingPid, callingUid)
11216                    != PackageManager.PERMISSION_GRANTED) {
11217                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11218                        + callingPid + ", uid=" + callingUid
11219                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11220                Slog.w(TAG, msg);
11221                throw new SecurityException(msg);
11222            }
11223            if (requiredPermission != null) {
11224                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11225                        + " and enforce permission " + requiredPermission);
11226                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11227            }
11228            if (intent.getComponent() != null) {
11229                throw new SecurityException(
11230                        "Sticky broadcasts can't target a specific component");
11231            }
11232            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11233            if (list == null) {
11234                list = new ArrayList<Intent>();
11235                mStickyBroadcasts.put(intent.getAction(), list);
11236            }
11237            int N = list.size();
11238            int i;
11239            for (i=0; i<N; i++) {
11240                if (intent.filterEquals(list.get(i))) {
11241                    // This sticky already exists, replace it.
11242                    list.set(i, new Intent(intent));
11243                    break;
11244                }
11245            }
11246            if (i >= N) {
11247                list.add(new Intent(intent));
11248            }
11249        }
11250
11251        // Figure out who all will receive this broadcast.
11252        List receivers = null;
11253        List<BroadcastFilter> registeredReceivers = null;
11254        try {
11255            // Need to resolve the intent to interested receivers...
11256            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11257                     == 0) {
11258                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11259                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11260            }
11261            if (intent.getComponent() == null) {
11262                registeredReceivers = mReceiverResolver.queryIntent(intent,
11263                        resolvedType, false, userId);
11264            }
11265        } catch (RemoteException ex) {
11266            // pm is in same process, this will never happen.
11267        }
11268
11269        final boolean replacePending =
11270                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11271
11272        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11273                + " replacePending=" + replacePending);
11274
11275        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11276        if (!ordered && NR > 0) {
11277            // If we are not serializing this broadcast, then send the
11278            // registered receivers separately so they don't wait for the
11279            // components to be launched.
11280            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11281            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11282                    callerPackage, callingPid, callingUid, requiredPermission,
11283                    registeredReceivers, resultTo, resultCode, resultData, map,
11284                    ordered, sticky, false, onlySendToCaller);
11285            if (DEBUG_BROADCAST) Slog.v(
11286                    TAG, "Enqueueing parallel broadcast " + r);
11287            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11288            if (!replaced) {
11289                queue.enqueueParallelBroadcastLocked(r);
11290                queue.scheduleBroadcastsLocked();
11291            }
11292            registeredReceivers = null;
11293            NR = 0;
11294        }
11295
11296        // Merge into one list.
11297        int ir = 0;
11298        if (receivers != null) {
11299            // A special case for PACKAGE_ADDED: do not allow the package
11300            // being added to see this broadcast.  This prevents them from
11301            // using this as a back door to get run as soon as they are
11302            // installed.  Maybe in the future we want to have a special install
11303            // broadcast or such for apps, but we'd like to deliberately make
11304            // this decision.
11305            String skipPackages[] = null;
11306            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11307                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11308                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11309                Uri data = intent.getData();
11310                if (data != null) {
11311                    String pkgName = data.getSchemeSpecificPart();
11312                    if (pkgName != null) {
11313                        skipPackages = new String[] { pkgName };
11314                    }
11315                }
11316            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11317                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11318            }
11319            if (skipPackages != null && (skipPackages.length > 0)) {
11320                for (String skipPackage : skipPackages) {
11321                    if (skipPackage != null) {
11322                        int NT = receivers.size();
11323                        for (int it=0; it<NT; it++) {
11324                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11325                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11326                                receivers.remove(it);
11327                                it--;
11328                                NT--;
11329                            }
11330                        }
11331                    }
11332                }
11333            }
11334
11335            int NT = receivers != null ? receivers.size() : 0;
11336            int it = 0;
11337            ResolveInfo curt = null;
11338            BroadcastFilter curr = null;
11339            while (it < NT && ir < NR) {
11340                if (curt == null) {
11341                    curt = (ResolveInfo)receivers.get(it);
11342                }
11343                if (curr == null) {
11344                    curr = registeredReceivers.get(ir);
11345                }
11346                if (curr.getPriority() >= curt.priority) {
11347                    // Insert this broadcast record into the final list.
11348                    receivers.add(it, curr);
11349                    ir++;
11350                    curr = null;
11351                    it++;
11352                    NT++;
11353                } else {
11354                    // Skip to the next ResolveInfo in the final list.
11355                    it++;
11356                    curt = null;
11357                }
11358            }
11359        }
11360        while (ir < NR) {
11361            if (receivers == null) {
11362                receivers = new ArrayList();
11363            }
11364            receivers.add(registeredReceivers.get(ir));
11365            ir++;
11366        }
11367
11368        if ((receivers != null && receivers.size() > 0)
11369                || resultTo != null) {
11370            BroadcastQueue queue = broadcastQueueForIntent(intent);
11371            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11372                    callerPackage, callingPid, callingUid, requiredPermission,
11373                    receivers, resultTo, resultCode, resultData, map, ordered,
11374                    sticky, false, onlySendToCaller);
11375            if (DEBUG_BROADCAST) Slog.v(
11376                    TAG, "Enqueueing ordered broadcast " + r
11377                    + ": prev had " + queue.mOrderedBroadcasts.size());
11378            if (DEBUG_BROADCAST) {
11379                int seq = r.intent.getIntExtra("seq", -1);
11380                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11381            }
11382            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11383            if (!replaced) {
11384                queue.enqueueOrderedBroadcastLocked(r);
11385                queue.scheduleBroadcastsLocked();
11386            }
11387        }
11388
11389        return ActivityManager.BROADCAST_SUCCESS;
11390    }
11391
11392    final Intent verifyBroadcastLocked(Intent intent) {
11393        // Refuse possible leaked file descriptors
11394        if (intent != null && intent.hasFileDescriptors() == true) {
11395            throw new IllegalArgumentException("File descriptors passed in Intent");
11396        }
11397
11398        int flags = intent.getFlags();
11399
11400        if (!mProcessesReady) {
11401            // if the caller really truly claims to know what they're doing, go
11402            // ahead and allow the broadcast without launching any receivers
11403            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11404                intent = new Intent(intent);
11405                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11406            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11407                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11408                        + " before boot completion");
11409                throw new IllegalStateException("Cannot broadcast before boot completed");
11410            }
11411        }
11412
11413        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11414            throw new IllegalArgumentException(
11415                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11416        }
11417
11418        return intent;
11419    }
11420
11421    public final int broadcastIntent(IApplicationThread caller,
11422            Intent intent, String resolvedType, IIntentReceiver resultTo,
11423            int resultCode, String resultData, Bundle map,
11424            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11425        enforceNotIsolatedCaller("broadcastIntent");
11426        synchronized(this) {
11427            intent = verifyBroadcastLocked(intent);
11428
11429            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11430            final int callingPid = Binder.getCallingPid();
11431            final int callingUid = Binder.getCallingUid();
11432            final long origId = Binder.clearCallingIdentity();
11433            int res = broadcastIntentLocked(callerApp,
11434                    callerApp != null ? callerApp.info.packageName : null,
11435                    intent, resolvedType, resultTo,
11436                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11437                    callingPid, callingUid, userId);
11438            Binder.restoreCallingIdentity(origId);
11439            return res;
11440        }
11441    }
11442
11443    int broadcastIntentInPackage(String packageName, int uid,
11444            Intent intent, String resolvedType, IIntentReceiver resultTo,
11445            int resultCode, String resultData, Bundle map,
11446            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11447        synchronized(this) {
11448            intent = verifyBroadcastLocked(intent);
11449
11450            final long origId = Binder.clearCallingIdentity();
11451            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11452                    resultTo, resultCode, resultData, map, requiredPermission,
11453                    serialized, sticky, -1, uid, userId);
11454            Binder.restoreCallingIdentity(origId);
11455            return res;
11456        }
11457    }
11458
11459    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11460    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11461        // Refuse possible leaked file descriptors
11462        if (intent != null && intent.hasFileDescriptors() == true) {
11463            throw new IllegalArgumentException("File descriptors passed in Intent");
11464        }
11465
11466        synchronized(this) {
11467            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11468                    != PackageManager.PERMISSION_GRANTED) {
11469                String msg = "Permission Denial: unbroadcastIntent() from pid="
11470                        + Binder.getCallingPid()
11471                        + ", uid=" + Binder.getCallingUid()
11472                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11473                Slog.w(TAG, msg);
11474                throw new SecurityException(msg);
11475            }
11476            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11477            if (list != null) {
11478                int N = list.size();
11479                int i;
11480                for (i=0; i<N; i++) {
11481                    if (intent.filterEquals(list.get(i))) {
11482                        list.remove(i);
11483                        break;
11484                    }
11485                }
11486            }
11487        }
11488    }
11489
11490    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11491            String resultData, Bundle resultExtras, boolean resultAbort,
11492            boolean explicit) {
11493        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11494        if (r == null) {
11495            Slog.w(TAG, "finishReceiver called but not found on queue");
11496            return false;
11497        }
11498
11499        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11500                explicit);
11501    }
11502
11503    public void finishReceiver(IBinder who, int resultCode, String resultData,
11504            Bundle resultExtras, boolean resultAbort) {
11505        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11506
11507        // Refuse possible leaked file descriptors
11508        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11509            throw new IllegalArgumentException("File descriptors passed in Bundle");
11510        }
11511
11512        final long origId = Binder.clearCallingIdentity();
11513        try {
11514            boolean doNext = false;
11515            BroadcastRecord r = null;
11516
11517            synchronized(this) {
11518                r = broadcastRecordForReceiverLocked(who);
11519                if (r != null) {
11520                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11521                        resultData, resultExtras, resultAbort, true);
11522                }
11523            }
11524
11525            if (doNext) {
11526                r.queue.processNextBroadcast(false);
11527            }
11528            trimApplications();
11529        } finally {
11530            Binder.restoreCallingIdentity(origId);
11531        }
11532    }
11533
11534    // =========================================================
11535    // INSTRUMENTATION
11536    // =========================================================
11537
11538    public boolean startInstrumentation(ComponentName className,
11539            String profileFile, int flags, Bundle arguments,
11540            IInstrumentationWatcher watcher) {
11541        enforceNotIsolatedCaller("startInstrumentation");
11542        // Refuse possible leaked file descriptors
11543        if (arguments != null && arguments.hasFileDescriptors()) {
11544            throw new IllegalArgumentException("File descriptors passed in Bundle");
11545        }
11546
11547        synchronized(this) {
11548            InstrumentationInfo ii = null;
11549            ApplicationInfo ai = null;
11550            try {
11551                ii = mContext.getPackageManager().getInstrumentationInfo(
11552                    className, STOCK_PM_FLAGS);
11553                ai = mContext.getPackageManager().getApplicationInfo(
11554                        ii.targetPackage, STOCK_PM_FLAGS);
11555            } catch (PackageManager.NameNotFoundException e) {
11556            }
11557            if (ii == null) {
11558                reportStartInstrumentationFailure(watcher, className,
11559                        "Unable to find instrumentation info for: " + className);
11560                return false;
11561            }
11562            if (ai == null) {
11563                reportStartInstrumentationFailure(watcher, className,
11564                        "Unable to find instrumentation target package: " + ii.targetPackage);
11565                return false;
11566            }
11567
11568            int match = mContext.getPackageManager().checkSignatures(
11569                    ii.targetPackage, ii.packageName);
11570            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11571                String msg = "Permission Denial: starting instrumentation "
11572                        + className + " from pid="
11573                        + Binder.getCallingPid()
11574                        + ", uid=" + Binder.getCallingPid()
11575                        + " not allowed because package " + ii.packageName
11576                        + " does not have a signature matching the target "
11577                        + ii.targetPackage;
11578                reportStartInstrumentationFailure(watcher, className, msg);
11579                throw new SecurityException(msg);
11580            }
11581
11582            int userId = UserHandle.getCallingUserId();
11583            final long origId = Binder.clearCallingIdentity();
11584            // Instrumentation can kill and relaunch even persistent processes
11585            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11586            ProcessRecord app = addAppLocked(ai, false);
11587            app.instrumentationClass = className;
11588            app.instrumentationInfo = ai;
11589            app.instrumentationProfileFile = profileFile;
11590            app.instrumentationArguments = arguments;
11591            app.instrumentationWatcher = watcher;
11592            app.instrumentationResultClass = className;
11593            Binder.restoreCallingIdentity(origId);
11594        }
11595
11596        return true;
11597    }
11598
11599    /**
11600     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11601     * error to the logs, but if somebody is watching, send the report there too.  This enables
11602     * the "am" command to report errors with more information.
11603     *
11604     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11605     * @param cn The component name of the instrumentation.
11606     * @param report The error report.
11607     */
11608    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11609            ComponentName cn, String report) {
11610        Slog.w(TAG, report);
11611        try {
11612            if (watcher != null) {
11613                Bundle results = new Bundle();
11614                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11615                results.putString("Error", report);
11616                watcher.instrumentationStatus(cn, -1, results);
11617            }
11618        } catch (RemoteException e) {
11619            Slog.w(TAG, e);
11620        }
11621    }
11622
11623    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11624        if (app.instrumentationWatcher != null) {
11625            try {
11626                // NOTE:  IInstrumentationWatcher *must* be oneway here
11627                app.instrumentationWatcher.instrumentationFinished(
11628                    app.instrumentationClass,
11629                    resultCode,
11630                    results);
11631            } catch (RemoteException e) {
11632            }
11633        }
11634        app.instrumentationWatcher = null;
11635        app.instrumentationClass = null;
11636        app.instrumentationInfo = null;
11637        app.instrumentationProfileFile = null;
11638        app.instrumentationArguments = null;
11639
11640        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11641    }
11642
11643    public void finishInstrumentation(IApplicationThread target,
11644            int resultCode, Bundle results) {
11645        int userId = UserHandle.getCallingUserId();
11646        // Refuse possible leaked file descriptors
11647        if (results != null && results.hasFileDescriptors()) {
11648            throw new IllegalArgumentException("File descriptors passed in Intent");
11649        }
11650
11651        synchronized(this) {
11652            ProcessRecord app = getRecordForAppLocked(target);
11653            if (app == null) {
11654                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11655                return;
11656            }
11657            final long origId = Binder.clearCallingIdentity();
11658            finishInstrumentationLocked(app, resultCode, results);
11659            Binder.restoreCallingIdentity(origId);
11660        }
11661    }
11662
11663    // =========================================================
11664    // CONFIGURATION
11665    // =========================================================
11666
11667    public ConfigurationInfo getDeviceConfigurationInfo() {
11668        ConfigurationInfo config = new ConfigurationInfo();
11669        synchronized (this) {
11670            config.reqTouchScreen = mConfiguration.touchscreen;
11671            config.reqKeyboardType = mConfiguration.keyboard;
11672            config.reqNavigation = mConfiguration.navigation;
11673            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11674                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11675                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11676            }
11677            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11678                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11679                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11680            }
11681            config.reqGlEsVersion = GL_ES_VERSION;
11682        }
11683        return config;
11684    }
11685
11686    public Configuration getConfiguration() {
11687        Configuration ci;
11688        synchronized(this) {
11689            ci = new Configuration(mConfiguration);
11690        }
11691        return ci;
11692    }
11693
11694    public void updatePersistentConfiguration(Configuration values) {
11695        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11696                "updateConfiguration()");
11697        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11698                "updateConfiguration()");
11699        if (values == null) {
11700            throw new NullPointerException("Configuration must not be null");
11701        }
11702
11703        synchronized(this) {
11704            final long origId = Binder.clearCallingIdentity();
11705            updateConfigurationLocked(values, null, true, false);
11706            Binder.restoreCallingIdentity(origId);
11707        }
11708    }
11709
11710    public void updateConfiguration(Configuration values) {
11711        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11712                "updateConfiguration()");
11713
11714        synchronized(this) {
11715            if (values == null && mWindowManager != null) {
11716                // sentinel: fetch the current configuration from the window manager
11717                values = mWindowManager.computeNewConfiguration();
11718            }
11719
11720            if (mWindowManager != null) {
11721                mProcessList.applyDisplaySize(mWindowManager);
11722            }
11723
11724            final long origId = Binder.clearCallingIdentity();
11725            if (values != null) {
11726                Settings.System.clearConfiguration(values);
11727            }
11728            updateConfigurationLocked(values, null, false, false);
11729            Binder.restoreCallingIdentity(origId);
11730        }
11731    }
11732
11733    /**
11734     * Do either or both things: (1) change the current configuration, and (2)
11735     * make sure the given activity is running with the (now) current
11736     * configuration.  Returns true if the activity has been left running, or
11737     * false if <var>starting</var> is being destroyed to match the new
11738     * configuration.
11739     * @param persistent TODO
11740     */
11741    boolean updateConfigurationLocked(Configuration values,
11742            ActivityRecord starting, boolean persistent, boolean initLocale) {
11743        // do nothing if we are headless
11744        if (mHeadless) return true;
11745
11746        int changes = 0;
11747
11748        boolean kept = true;
11749
11750        if (values != null) {
11751            Configuration newConfig = new Configuration(mConfiguration);
11752            changes = newConfig.updateFrom(values);
11753            if (changes != 0) {
11754                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11755                    Slog.i(TAG, "Updating configuration to: " + values);
11756                }
11757
11758                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11759
11760                if (values.locale != null && !initLocale) {
11761                    saveLocaleLocked(values.locale,
11762                                     !values.locale.equals(mConfiguration.locale),
11763                                     values.userSetLocale);
11764                }
11765
11766                mConfigurationSeq++;
11767                if (mConfigurationSeq <= 0) {
11768                    mConfigurationSeq = 1;
11769                }
11770                newConfig.seq = mConfigurationSeq;
11771                mConfiguration = newConfig;
11772                Slog.i(TAG, "Config changed: " + newConfig);
11773
11774                final Configuration configCopy = new Configuration(mConfiguration);
11775
11776                // TODO: If our config changes, should we auto dismiss any currently
11777                // showing dialogs?
11778                mShowDialogs = shouldShowDialogs(newConfig);
11779
11780                AttributeCache ac = AttributeCache.instance();
11781                if (ac != null) {
11782                    ac.updateConfiguration(configCopy);
11783                }
11784
11785                // Make sure all resources in our process are updated
11786                // right now, so that anyone who is going to retrieve
11787                // resource values after we return will be sure to get
11788                // the new ones.  This is especially important during
11789                // boot, where the first config change needs to guarantee
11790                // all resources have that config before following boot
11791                // code is executed.
11792                mSystemThread.applyConfigurationToResources(configCopy);
11793
11794                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11795                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11796                    msg.obj = new Configuration(configCopy);
11797                    mHandler.sendMessage(msg);
11798                }
11799
11800                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11801                    ProcessRecord app = mLruProcesses.get(i);
11802                    try {
11803                        if (app.thread != null) {
11804                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11805                                    + app.processName + " new config " + mConfiguration);
11806                            app.thread.scheduleConfigurationChanged(configCopy);
11807                        }
11808                    } catch (Exception e) {
11809                    }
11810                }
11811                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11812                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11813                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11814                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11815                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11816                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11817                    broadcastIntentLocked(null, null,
11818                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11819                            null, null, 0, null, null,
11820                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11821                }
11822            }
11823        }
11824
11825        if (changes != 0 && starting == null) {
11826            // If the configuration changed, and the caller is not already
11827            // in the process of starting an activity, then find the top
11828            // activity to check if its configuration needs to change.
11829            starting = mMainStack.topRunningActivityLocked(null);
11830        }
11831
11832        if (starting != null) {
11833            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11834            // And we need to make sure at this point that all other activities
11835            // are made visible with the correct configuration.
11836            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11837        }
11838
11839        if (values != null && mWindowManager != null) {
11840            mWindowManager.setNewConfiguration(mConfiguration);
11841        }
11842
11843        return kept;
11844    }
11845
11846    /**
11847     * Decide based on the configuration whether we should shouw the ANR,
11848     * crash, etc dialogs.  The idea is that if there is no affordnace to
11849     * press the on-screen buttons, we shouldn't show the dialog.
11850     *
11851     * A thought: SystemUI might also want to get told about this, the Power
11852     * dialog / global actions also might want different behaviors.
11853     */
11854    private static final boolean shouldShowDialogs(Configuration config) {
11855        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11856                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11857    }
11858
11859    /**
11860     * Save the locale.  You must be inside a synchronized (this) block.
11861     */
11862    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11863        if(isDiff) {
11864            SystemProperties.set("user.language", l.getLanguage());
11865            SystemProperties.set("user.region", l.getCountry());
11866        }
11867
11868        if(isPersist) {
11869            SystemProperties.set("persist.sys.language", l.getLanguage());
11870            SystemProperties.set("persist.sys.country", l.getCountry());
11871            SystemProperties.set("persist.sys.localevar", l.getVariant());
11872        }
11873    }
11874
11875    @Override
11876    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11877        ActivityRecord srec = ActivityRecord.forToken(token);
11878        return srec != null && srec.task.affinity != null &&
11879                srec.task.affinity.equals(destAffinity);
11880    }
11881
11882    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11883            Intent resultData) {
11884        ComponentName dest = destIntent.getComponent();
11885
11886        synchronized (this) {
11887            ActivityRecord srec = ActivityRecord.forToken(token);
11888            if (srec == null) {
11889                return false;
11890            }
11891            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11892            final int start = history.indexOf(srec);
11893            if (start < 0) {
11894                // Current activity is not in history stack; do nothing.
11895                return false;
11896            }
11897            int finishTo = start - 1;
11898            ActivityRecord parent = null;
11899            boolean foundParentInTask = false;
11900            if (dest != null) {
11901                TaskRecord tr = srec.task;
11902                for (int i = start - 1; i >= 0; i--) {
11903                    ActivityRecord r = history.get(i);
11904                    if (tr != r.task) {
11905                        // Couldn't find parent in the same task; stop at the one above this.
11906                        // (Root of current task; in-app "home" behavior)
11907                        // Always at least finish the current activity.
11908                        finishTo = Math.min(start - 1, i + 1);
11909                        parent = history.get(finishTo);
11910                        break;
11911                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11912                            r.info.name.equals(dest.getClassName())) {
11913                        finishTo = i;
11914                        parent = r;
11915                        foundParentInTask = true;
11916                        break;
11917                    }
11918                }
11919            }
11920
11921            if (mController != null) {
11922                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11923                if (next != null) {
11924                    // ask watcher if this is allowed
11925                    boolean resumeOK = true;
11926                    try {
11927                        resumeOK = mController.activityResuming(next.packageName);
11928                    } catch (RemoteException e) {
11929                        mController = null;
11930                    }
11931
11932                    if (!resumeOK) {
11933                        return false;
11934                    }
11935                }
11936            }
11937            final long origId = Binder.clearCallingIdentity();
11938            for (int i = start; i > finishTo; i--) {
11939                ActivityRecord r = history.get(i);
11940                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11941                        "navigate-up");
11942                // Only return the supplied result for the first activity finished
11943                resultCode = Activity.RESULT_CANCELED;
11944                resultData = null;
11945            }
11946
11947            if (parent != null && foundParentInTask) {
11948                final int parentLaunchMode = parent.info.launchMode;
11949                final int destIntentFlags = destIntent.getFlags();
11950                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11951                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11952                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11953                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11954                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11955                } else {
11956                    try {
11957                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11958                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
11959                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11960                                null, aInfo, parent.appToken, null,
11961                                0, -1, parent.launchedFromUid, 0, null, true, null);
11962                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11963                    } catch (RemoteException e) {
11964                        foundParentInTask = false;
11965                    }
11966                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11967                            resultData, "navigate-up");
11968                }
11969            }
11970            Binder.restoreCallingIdentity(origId);
11971            return foundParentInTask;
11972        }
11973    }
11974
11975    public int getLaunchedFromUid(IBinder activityToken) {
11976        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11977        if (srec == null) {
11978            return -1;
11979        }
11980        return srec.launchedFromUid;
11981    }
11982
11983    // =========================================================
11984    // LIFETIME MANAGEMENT
11985    // =========================================================
11986
11987    // Returns which broadcast queue the app is the current [or imminent] receiver
11988    // on, or 'null' if the app is not an active broadcast recipient.
11989    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11990        BroadcastRecord r = app.curReceiver;
11991        if (r != null) {
11992            return r.queue;
11993        }
11994
11995        // It's not the current receiver, but it might be starting up to become one
11996        synchronized (this) {
11997            for (BroadcastQueue queue : mBroadcastQueues) {
11998                r = queue.mPendingBroadcast;
11999                if (r != null && r.curApp == app) {
12000                    // found it; report which queue it's in
12001                    return queue;
12002                }
12003            }
12004        }
12005
12006        return null;
12007    }
12008
12009    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12010            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12011        if (mAdjSeq == app.adjSeq) {
12012            // This adjustment has already been computed.  If we are calling
12013            // from the top, we may have already computed our adjustment with
12014            // an earlier hidden adjustment that isn't really for us... if
12015            // so, use the new hidden adjustment.
12016            if (!recursed && app.hidden) {
12017                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12018                        app.hasActivities ? hiddenAdj : emptyAdj;
12019            }
12020            return app.curRawAdj;
12021        }
12022
12023        if (app.thread == null) {
12024            app.adjSeq = mAdjSeq;
12025            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12026            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12027        }
12028
12029        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12030        app.adjSource = null;
12031        app.adjTarget = null;
12032        app.empty = false;
12033        app.hidden = false;
12034
12035        final int activitiesSize = app.activities.size();
12036
12037        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12038            // The max adjustment doesn't allow this app to be anything
12039            // below foreground, so it is not worth doing work for it.
12040            app.adjType = "fixed";
12041            app.adjSeq = mAdjSeq;
12042            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12043            app.hasActivities = false;
12044            app.foregroundActivities = false;
12045            app.keeping = true;
12046            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12047            // System process can do UI, and when they do we want to have
12048            // them trim their memory after the user leaves the UI.  To
12049            // facilitate this, here we need to determine whether or not it
12050            // is currently showing UI.
12051            app.systemNoUi = true;
12052            if (app == TOP_APP) {
12053                app.systemNoUi = false;
12054                app.hasActivities = true;
12055            } else if (activitiesSize > 0) {
12056                for (int j = 0; j < activitiesSize; j++) {
12057                    final ActivityRecord r = app.activities.get(j);
12058                    if (r.visible) {
12059                        app.systemNoUi = false;
12060                    }
12061                    if (r.app == app) {
12062                        app.hasActivities = true;
12063                    }
12064                }
12065            }
12066            return (app.curAdj=app.maxAdj);
12067        }
12068
12069        app.keeping = false;
12070        app.systemNoUi = false;
12071        app.hasActivities = false;
12072
12073        // Determine the importance of the process, starting with most
12074        // important to least, and assign an appropriate OOM adjustment.
12075        int adj;
12076        int schedGroup;
12077        boolean foregroundActivities = false;
12078        boolean interesting = false;
12079        BroadcastQueue queue;
12080        if (app == TOP_APP) {
12081            // The last app on the list is the foreground app.
12082            adj = ProcessList.FOREGROUND_APP_ADJ;
12083            schedGroup = Process.THREAD_GROUP_DEFAULT;
12084            app.adjType = "top-activity";
12085            foregroundActivities = true;
12086            interesting = true;
12087            app.hasActivities = true;
12088        } else if (app.instrumentationClass != null) {
12089            // Don't want to kill running instrumentation.
12090            adj = ProcessList.FOREGROUND_APP_ADJ;
12091            schedGroup = Process.THREAD_GROUP_DEFAULT;
12092            app.adjType = "instrumentation";
12093            interesting = true;
12094        } else if ((queue = isReceivingBroadcast(app)) != null) {
12095            // An app that is currently receiving a broadcast also
12096            // counts as being in the foreground for OOM killer purposes.
12097            // It's placed in a sched group based on the nature of the
12098            // broadcast as reflected by which queue it's active in.
12099            adj = ProcessList.FOREGROUND_APP_ADJ;
12100            schedGroup = (queue == mFgBroadcastQueue)
12101                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12102            app.adjType = "broadcast";
12103        } else if (app.executingServices.size() > 0) {
12104            // An app that is currently executing a service callback also
12105            // counts as being in the foreground.
12106            adj = ProcessList.FOREGROUND_APP_ADJ;
12107            schedGroup = Process.THREAD_GROUP_DEFAULT;
12108            app.adjType = "exec-service";
12109        } else {
12110            // Assume process is hidden (has activities); we will correct
12111            // later if this is not the case.
12112            adj = hiddenAdj;
12113            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12114            app.hidden = true;
12115            app.adjType = "bg-activities";
12116        }
12117
12118        boolean hasStoppingActivities = false;
12119
12120        // Examine all activities if not already foreground.
12121        if (!foregroundActivities && activitiesSize > 0) {
12122            for (int j = 0; j < activitiesSize; j++) {
12123                final ActivityRecord r = app.activities.get(j);
12124                if (r.visible) {
12125                    // App has a visible activity; only upgrade adjustment.
12126                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12127                        adj = ProcessList.VISIBLE_APP_ADJ;
12128                        app.adjType = "visible";
12129                    }
12130                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12131                    app.hidden = false;
12132                    app.hasActivities = true;
12133                    foregroundActivities = true;
12134                    break;
12135                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12136                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12137                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12138                        app.adjType = "pausing";
12139                    }
12140                    app.hidden = false;
12141                    foregroundActivities = true;
12142                } else if (r.state == ActivityState.STOPPING) {
12143                    // We will apply the actual adjustment later, because
12144                    // we want to allow this process to immediately go through
12145                    // any memory trimming that is in effect.
12146                    app.hidden = false;
12147                    foregroundActivities = true;
12148                    hasStoppingActivities = true;
12149                }
12150                if (r.app == app) {
12151                    app.hasActivities = true;
12152                }
12153            }
12154        }
12155
12156        if (adj == hiddenAdj && !app.hasActivities) {
12157            // Whoops, this process is completely empty as far as we know
12158            // at this point.
12159            adj = emptyAdj;
12160            app.empty = true;
12161            app.adjType = "bg-empty";
12162        }
12163
12164        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12165            if (app.foregroundServices) {
12166                // The user is aware of this app, so make it visible.
12167                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12168                app.hidden = false;
12169                app.adjType = "foreground-service";
12170                schedGroup = Process.THREAD_GROUP_DEFAULT;
12171            } else if (app.forcingToForeground != null) {
12172                // The user is aware of this app, so make it visible.
12173                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12174                app.hidden = false;
12175                app.adjType = "force-foreground";
12176                app.adjSource = app.forcingToForeground;
12177                schedGroup = Process.THREAD_GROUP_DEFAULT;
12178            }
12179        }
12180
12181        if (app.foregroundServices) {
12182            interesting = true;
12183        }
12184
12185        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12186            // We don't want to kill the current heavy-weight process.
12187            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12188            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12189            app.hidden = false;
12190            app.adjType = "heavy";
12191        }
12192
12193        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12194            // This process is hosting what we currently consider to be the
12195            // home app, so we don't want to let it go into the background.
12196            adj = ProcessList.HOME_APP_ADJ;
12197            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12198            app.hidden = false;
12199            app.adjType = "home";
12200        }
12201
12202        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12203                && app.activities.size() > 0) {
12204            // This was the previous process that showed UI to the user.
12205            // We want to try to keep it around more aggressively, to give
12206            // a good experience around switching between two apps.
12207            adj = ProcessList.PREVIOUS_APP_ADJ;
12208            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12209            app.hidden = false;
12210            app.adjType = "previous";
12211        }
12212
12213        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12214                + " reason=" + app.adjType);
12215
12216        // By default, we use the computed adjustment.  It may be changed if
12217        // there are applications dependent on our services or providers, but
12218        // this gives us a baseline and makes sure we don't get into an
12219        // infinite recursion.
12220        app.adjSeq = mAdjSeq;
12221        app.curRawAdj = app.nonStoppingAdj = adj;
12222
12223        if (mBackupTarget != null && app == mBackupTarget.app) {
12224            // If possible we want to avoid killing apps while they're being backed up
12225            if (adj > ProcessList.BACKUP_APP_ADJ) {
12226                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12227                adj = ProcessList.BACKUP_APP_ADJ;
12228                app.adjType = "backup";
12229                app.hidden = false;
12230            }
12231        }
12232
12233        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12234                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12235            final long now = SystemClock.uptimeMillis();
12236            // This process is more important if the top activity is
12237            // bound to the service.
12238            Iterator<ServiceRecord> jt = app.services.iterator();
12239            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12240                ServiceRecord s = jt.next();
12241                if (s.startRequested) {
12242                    if (app.hasShownUi && app != mHomeProcess) {
12243                        // If this process has shown some UI, let it immediately
12244                        // go to the LRU list because it may be pretty heavy with
12245                        // UI stuff.  We'll tag it with a label just to help
12246                        // debug and understand what is going on.
12247                        if (adj > ProcessList.SERVICE_ADJ) {
12248                            app.adjType = "started-bg-ui-services";
12249                        }
12250                    } else {
12251                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12252                            // This service has seen some activity within
12253                            // recent memory, so we will keep its process ahead
12254                            // of the background processes.
12255                            if (adj > ProcessList.SERVICE_ADJ) {
12256                                adj = ProcessList.SERVICE_ADJ;
12257                                app.adjType = "started-services";
12258                                app.hidden = false;
12259                            }
12260                        }
12261                        // If we have let the service slide into the background
12262                        // state, still have some text describing what it is doing
12263                        // even though the service no longer has an impact.
12264                        if (adj > ProcessList.SERVICE_ADJ) {
12265                            app.adjType = "started-bg-services";
12266                        }
12267                    }
12268                    // Don't kill this process because it is doing work; it
12269                    // has said it is doing work.
12270                    app.keeping = true;
12271                }
12272                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12273                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12274                    Iterator<ArrayList<ConnectionRecord>> kt
12275                            = s.connections.values().iterator();
12276                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12277                        ArrayList<ConnectionRecord> clist = kt.next();
12278                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12279                            // XXX should compute this based on the max of
12280                            // all connected clients.
12281                            ConnectionRecord cr = clist.get(i);
12282                            if (cr.binding.client == app) {
12283                                // Binding to ourself is not interesting.
12284                                continue;
12285                            }
12286                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12287                                ProcessRecord client = cr.binding.client;
12288                                int clientAdj = adj;
12289                                int myHiddenAdj = hiddenAdj;
12290                                if (myHiddenAdj > client.hiddenAdj) {
12291                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12292                                        myHiddenAdj = client.hiddenAdj;
12293                                    } else {
12294                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12295                                    }
12296                                }
12297                                int myEmptyAdj = emptyAdj;
12298                                if (myEmptyAdj > client.emptyAdj) {
12299                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12300                                        myEmptyAdj = client.emptyAdj;
12301                                    } else {
12302                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12303                                    }
12304                                }
12305                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12306                                        myEmptyAdj, TOP_APP, true, doingAll);
12307                                String adjType = null;
12308                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12309                                    // Not doing bind OOM management, so treat
12310                                    // this guy more like a started service.
12311                                    if (app.hasShownUi && app != mHomeProcess) {
12312                                        // If this process has shown some UI, let it immediately
12313                                        // go to the LRU list because it may be pretty heavy with
12314                                        // UI stuff.  We'll tag it with a label just to help
12315                                        // debug and understand what is going on.
12316                                        if (adj > clientAdj) {
12317                                            adjType = "bound-bg-ui-services";
12318                                        }
12319                                        app.hidden = false;
12320                                        clientAdj = adj;
12321                                    } else {
12322                                        if (now >= (s.lastActivity
12323                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12324                                            // This service has not seen activity within
12325                                            // recent memory, so allow it to drop to the
12326                                            // LRU list if there is no other reason to keep
12327                                            // it around.  We'll also tag it with a label just
12328                                            // to help debug and undertand what is going on.
12329                                            if (adj > clientAdj) {
12330                                                adjType = "bound-bg-services";
12331                                            }
12332                                            clientAdj = adj;
12333                                        }
12334                                    }
12335                                }
12336                                if (adj > clientAdj) {
12337                                    // If this process has recently shown UI, and
12338                                    // the process that is binding to it is less
12339                                    // important than being visible, then we don't
12340                                    // care about the binding as much as we care
12341                                    // about letting this process get into the LRU
12342                                    // list to be killed and restarted if needed for
12343                                    // memory.
12344                                    if (app.hasShownUi && app != mHomeProcess
12345                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12346                                        adjType = "bound-bg-ui-services";
12347                                    } else {
12348                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12349                                                |Context.BIND_IMPORTANT)) != 0) {
12350                                            adj = clientAdj;
12351                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12352                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12353                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12354                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12355                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12356                                            adj = clientAdj;
12357                                        } else {
12358                                            app.pendingUiClean = true;
12359                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12360                                                adj = ProcessList.VISIBLE_APP_ADJ;
12361                                            }
12362                                        }
12363                                        if (!client.hidden) {
12364                                            app.hidden = false;
12365                                        }
12366                                        if (client.keeping) {
12367                                            app.keeping = true;
12368                                        }
12369                                        adjType = "service";
12370                                    }
12371                                }
12372                                if (adjType != null) {
12373                                    app.adjType = adjType;
12374                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12375                                            .REASON_SERVICE_IN_USE;
12376                                    app.adjSource = cr.binding.client;
12377                                    app.adjSourceOom = clientAdj;
12378                                    app.adjTarget = s.name;
12379                                }
12380                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12381                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12382                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12383                                    }
12384                                }
12385                            }
12386                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12387                                ActivityRecord a = cr.activity;
12388                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12389                                        (a.visible || a.state == ActivityState.RESUMED
12390                                         || a.state == ActivityState.PAUSING)) {
12391                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12392                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12393                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12394                                    }
12395                                    app.hidden = false;
12396                                    app.adjType = "service";
12397                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12398                                            .REASON_SERVICE_IN_USE;
12399                                    app.adjSource = a;
12400                                    app.adjSourceOom = adj;
12401                                    app.adjTarget = s.name;
12402                                }
12403                            }
12404                        }
12405                    }
12406                }
12407            }
12408
12409            // Finally, if this process has active services running in it, we
12410            // would like to avoid killing it unless it would prevent the current
12411            // application from running.  By default we put the process in
12412            // with the rest of the background processes; as we scan through
12413            // its services we may bump it up from there.
12414            if (adj > hiddenAdj) {
12415                adj = hiddenAdj;
12416                app.hidden = false;
12417                app.adjType = "bg-services";
12418            }
12419        }
12420
12421        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12422                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12423            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12424            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12425                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12426                ContentProviderRecord cpr = jt.next();
12427                for (int i = cpr.connections.size()-1;
12428                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12429                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12430                        i--) {
12431                    ContentProviderConnection conn = cpr.connections.get(i);
12432                    ProcessRecord client = conn.client;
12433                    if (client == app) {
12434                        // Being our own client is not interesting.
12435                        continue;
12436                    }
12437                    int myHiddenAdj = hiddenAdj;
12438                    if (myHiddenAdj > client.hiddenAdj) {
12439                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12440                            myHiddenAdj = client.hiddenAdj;
12441                        } else {
12442                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12443                        }
12444                    }
12445                    int myEmptyAdj = emptyAdj;
12446                    if (myEmptyAdj > client.emptyAdj) {
12447                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12448                            myEmptyAdj = client.emptyAdj;
12449                        } else {
12450                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12451                        }
12452                    }
12453                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12454                            myEmptyAdj, TOP_APP, true, doingAll);
12455                    if (adj > clientAdj) {
12456                        if (app.hasShownUi && app != mHomeProcess
12457                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12458                            app.adjType = "bg-ui-provider";
12459                        } else {
12460                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12461                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12462                            app.adjType = "provider";
12463                        }
12464                        if (!client.hidden) {
12465                            app.hidden = false;
12466                        }
12467                        if (client.keeping) {
12468                            app.keeping = true;
12469                        }
12470                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12471                                .REASON_PROVIDER_IN_USE;
12472                        app.adjSource = client;
12473                        app.adjSourceOom = clientAdj;
12474                        app.adjTarget = cpr.name;
12475                    }
12476                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12477                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12478                    }
12479                }
12480                // If the provider has external (non-framework) process
12481                // dependencies, ensure that its adjustment is at least
12482                // FOREGROUND_APP_ADJ.
12483                if (cpr.hasExternalProcessHandles()) {
12484                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12485                        adj = ProcessList.FOREGROUND_APP_ADJ;
12486                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12487                        app.hidden = false;
12488                        app.keeping = true;
12489                        app.adjType = "provider";
12490                        app.adjTarget = cpr.name;
12491                    }
12492                }
12493            }
12494        }
12495
12496        if (adj == ProcessList.SERVICE_ADJ) {
12497            if (doingAll) {
12498                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12499                mNewNumServiceProcs++;
12500            }
12501            if (app.serviceb) {
12502                adj = ProcessList.SERVICE_B_ADJ;
12503            }
12504        } else {
12505            app.serviceb = false;
12506        }
12507
12508        app.nonStoppingAdj = adj;
12509
12510        if (hasStoppingActivities) {
12511            // Only upgrade adjustment.
12512            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12513                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12514                app.adjType = "stopping";
12515            }
12516        }
12517
12518        app.curRawAdj = adj;
12519
12520        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12521        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12522        if (adj > app.maxAdj) {
12523            adj = app.maxAdj;
12524            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12525                schedGroup = Process.THREAD_GROUP_DEFAULT;
12526            }
12527        }
12528        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12529            app.keeping = true;
12530        }
12531
12532        if (app.hasAboveClient) {
12533            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12534            // then we need to drop its adjustment to be lower than the service's
12535            // in order to honor the request.  We want to drop it by one adjustment
12536            // level...  but there is special meaning applied to various levels so
12537            // we will skip some of them.
12538            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12539                // System process will not get dropped, ever
12540            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12541                adj = ProcessList.VISIBLE_APP_ADJ;
12542            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12543                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12544            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12545                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12546            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12547                adj++;
12548            }
12549        }
12550
12551        int importance = app.memImportance;
12552        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12553            app.curAdj = adj;
12554            app.curSchedGroup = schedGroup;
12555            if (!interesting) {
12556                // For this reporting, if there is not something explicitly
12557                // interesting in this process then we will push it to the
12558                // background importance.
12559                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12560            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12561                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12562            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12563                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12564            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12565                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12566            } else if (adj >= ProcessList.SERVICE_ADJ) {
12567                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12568            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12569                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12570            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12571                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12572            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12573                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12574            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12575                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12576            } else {
12577                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12578            }
12579        }
12580
12581        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12582        if (foregroundActivities != app.foregroundActivities) {
12583            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12584        }
12585        if (changes != 0) {
12586            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12587            app.memImportance = importance;
12588            app.foregroundActivities = foregroundActivities;
12589            int i = mPendingProcessChanges.size()-1;
12590            ProcessChangeItem item = null;
12591            while (i >= 0) {
12592                item = mPendingProcessChanges.get(i);
12593                if (item.pid == app.pid) {
12594                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12595                    break;
12596                }
12597                i--;
12598            }
12599            if (i < 0) {
12600                // No existing item in pending changes; need a new one.
12601                final int NA = mAvailProcessChanges.size();
12602                if (NA > 0) {
12603                    item = mAvailProcessChanges.remove(NA-1);
12604                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12605                } else {
12606                    item = new ProcessChangeItem();
12607                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12608                }
12609                item.changes = 0;
12610                item.pid = app.pid;
12611                item.uid = app.info.uid;
12612                if (mPendingProcessChanges.size() == 0) {
12613                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12614                            "*** Enqueueing dispatch processes changed!");
12615                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12616                }
12617                mPendingProcessChanges.add(item);
12618            }
12619            item.changes |= changes;
12620            item.importance = importance;
12621            item.foregroundActivities = foregroundActivities;
12622            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12623                    + Integer.toHexString(System.identityHashCode(item))
12624                    + " " + app.toShortString() + ": changes=" + item.changes
12625                    + " importance=" + item.importance
12626                    + " foreground=" + item.foregroundActivities
12627                    + " type=" + app.adjType + " source=" + app.adjSource
12628                    + " target=" + app.adjTarget);
12629        }
12630
12631        return app.curRawAdj;
12632    }
12633
12634    /**
12635     * Ask a given process to GC right now.
12636     */
12637    final void performAppGcLocked(ProcessRecord app) {
12638        try {
12639            app.lastRequestedGc = SystemClock.uptimeMillis();
12640            if (app.thread != null) {
12641                if (app.reportLowMemory) {
12642                    app.reportLowMemory = false;
12643                    app.thread.scheduleLowMemory();
12644                } else {
12645                    app.thread.processInBackground();
12646                }
12647            }
12648        } catch (Exception e) {
12649            // whatever.
12650        }
12651    }
12652
12653    /**
12654     * Returns true if things are idle enough to perform GCs.
12655     */
12656    private final boolean canGcNowLocked() {
12657        boolean processingBroadcasts = false;
12658        for (BroadcastQueue q : mBroadcastQueues) {
12659            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12660                processingBroadcasts = true;
12661            }
12662        }
12663        return !processingBroadcasts
12664                && (mSleeping || (mMainStack.mResumedActivity != null &&
12665                        mMainStack.mResumedActivity.idle));
12666    }
12667
12668    /**
12669     * Perform GCs on all processes that are waiting for it, but only
12670     * if things are idle.
12671     */
12672    final void performAppGcsLocked() {
12673        final int N = mProcessesToGc.size();
12674        if (N <= 0) {
12675            return;
12676        }
12677        if (canGcNowLocked()) {
12678            while (mProcessesToGc.size() > 0) {
12679                ProcessRecord proc = mProcessesToGc.remove(0);
12680                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12681                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12682                            <= SystemClock.uptimeMillis()) {
12683                        // To avoid spamming the system, we will GC processes one
12684                        // at a time, waiting a few seconds between each.
12685                        performAppGcLocked(proc);
12686                        scheduleAppGcsLocked();
12687                        return;
12688                    } else {
12689                        // It hasn't been long enough since we last GCed this
12690                        // process...  put it in the list to wait for its time.
12691                        addProcessToGcListLocked(proc);
12692                        break;
12693                    }
12694                }
12695            }
12696
12697            scheduleAppGcsLocked();
12698        }
12699    }
12700
12701    /**
12702     * If all looks good, perform GCs on all processes waiting for them.
12703     */
12704    final void performAppGcsIfAppropriateLocked() {
12705        if (canGcNowLocked()) {
12706            performAppGcsLocked();
12707            return;
12708        }
12709        // Still not idle, wait some more.
12710        scheduleAppGcsLocked();
12711    }
12712
12713    /**
12714     * Schedule the execution of all pending app GCs.
12715     */
12716    final void scheduleAppGcsLocked() {
12717        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12718
12719        if (mProcessesToGc.size() > 0) {
12720            // Schedule a GC for the time to the next process.
12721            ProcessRecord proc = mProcessesToGc.get(0);
12722            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12723
12724            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12725            long now = SystemClock.uptimeMillis();
12726            if (when < (now+GC_TIMEOUT)) {
12727                when = now + GC_TIMEOUT;
12728            }
12729            mHandler.sendMessageAtTime(msg, when);
12730        }
12731    }
12732
12733    /**
12734     * Add a process to the array of processes waiting to be GCed.  Keeps the
12735     * list in sorted order by the last GC time.  The process can't already be
12736     * on the list.
12737     */
12738    final void addProcessToGcListLocked(ProcessRecord proc) {
12739        boolean added = false;
12740        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12741            if (mProcessesToGc.get(i).lastRequestedGc <
12742                    proc.lastRequestedGc) {
12743                added = true;
12744                mProcessesToGc.add(i+1, proc);
12745                break;
12746            }
12747        }
12748        if (!added) {
12749            mProcessesToGc.add(0, proc);
12750        }
12751    }
12752
12753    /**
12754     * Set up to ask a process to GC itself.  This will either do it
12755     * immediately, or put it on the list of processes to gc the next
12756     * time things are idle.
12757     */
12758    final void scheduleAppGcLocked(ProcessRecord app) {
12759        long now = SystemClock.uptimeMillis();
12760        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12761            return;
12762        }
12763        if (!mProcessesToGc.contains(app)) {
12764            addProcessToGcListLocked(app);
12765            scheduleAppGcsLocked();
12766        }
12767    }
12768
12769    final void checkExcessivePowerUsageLocked(boolean doKills) {
12770        updateCpuStatsNow();
12771
12772        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12773        boolean doWakeKills = doKills;
12774        boolean doCpuKills = doKills;
12775        if (mLastPowerCheckRealtime == 0) {
12776            doWakeKills = false;
12777        }
12778        if (mLastPowerCheckUptime == 0) {
12779            doCpuKills = false;
12780        }
12781        if (stats.isScreenOn()) {
12782            doWakeKills = false;
12783        }
12784        final long curRealtime = SystemClock.elapsedRealtime();
12785        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12786        final long curUptime = SystemClock.uptimeMillis();
12787        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12788        mLastPowerCheckRealtime = curRealtime;
12789        mLastPowerCheckUptime = curUptime;
12790        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12791            doWakeKills = false;
12792        }
12793        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12794            doCpuKills = false;
12795        }
12796        int i = mLruProcesses.size();
12797        while (i > 0) {
12798            i--;
12799            ProcessRecord app = mLruProcesses.get(i);
12800            if (!app.keeping) {
12801                long wtime;
12802                synchronized (stats) {
12803                    wtime = stats.getProcessWakeTime(app.info.uid,
12804                            app.pid, curRealtime);
12805                }
12806                long wtimeUsed = wtime - app.lastWakeTime;
12807                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12808                if (DEBUG_POWER) {
12809                    StringBuilder sb = new StringBuilder(128);
12810                    sb.append("Wake for ");
12811                    app.toShortString(sb);
12812                    sb.append(": over ");
12813                    TimeUtils.formatDuration(realtimeSince, sb);
12814                    sb.append(" used ");
12815                    TimeUtils.formatDuration(wtimeUsed, sb);
12816                    sb.append(" (");
12817                    sb.append((wtimeUsed*100)/realtimeSince);
12818                    sb.append("%)");
12819                    Slog.i(TAG, sb.toString());
12820                    sb.setLength(0);
12821                    sb.append("CPU for ");
12822                    app.toShortString(sb);
12823                    sb.append(": over ");
12824                    TimeUtils.formatDuration(uptimeSince, sb);
12825                    sb.append(" used ");
12826                    TimeUtils.formatDuration(cputimeUsed, sb);
12827                    sb.append(" (");
12828                    sb.append((cputimeUsed*100)/uptimeSince);
12829                    sb.append("%)");
12830                    Slog.i(TAG, sb.toString());
12831                }
12832                // If a process has held a wake lock for more
12833                // than 50% of the time during this period,
12834                // that sounds bad.  Kill!
12835                if (doWakeKills && realtimeSince > 0
12836                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12837                    synchronized (stats) {
12838                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12839                                realtimeSince, wtimeUsed);
12840                    }
12841                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12842                            + " (pid " + app.pid + "): held " + wtimeUsed
12843                            + " during " + realtimeSince);
12844                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12845                            app.processName, app.setAdj, "excessive wake lock");
12846                    Process.killProcessQuiet(app.pid);
12847                } else if (doCpuKills && uptimeSince > 0
12848                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12849                    synchronized (stats) {
12850                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12851                                uptimeSince, cputimeUsed);
12852                    }
12853                    Slog.w(TAG, "Excessive CPU in " + app.processName
12854                            + " (pid " + app.pid + "): used " + cputimeUsed
12855                            + " during " + uptimeSince);
12856                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12857                            app.processName, app.setAdj, "excessive cpu");
12858                    Process.killProcessQuiet(app.pid);
12859                } else {
12860                    app.lastWakeTime = wtime;
12861                    app.lastCpuTime = app.curCpuTime;
12862                }
12863            }
12864        }
12865    }
12866
12867    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12868            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12869        app.hiddenAdj = hiddenAdj;
12870        app.emptyAdj = emptyAdj;
12871
12872        if (app.thread == null) {
12873            return false;
12874        }
12875
12876        final boolean wasKeeping = app.keeping;
12877
12878        boolean success = true;
12879
12880        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12881
12882        if (app.curRawAdj != app.setRawAdj) {
12883            if (wasKeeping && !app.keeping) {
12884                // This app is no longer something we want to keep.  Note
12885                // its current wake lock time to later know to kill it if
12886                // it is not behaving well.
12887                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12888                synchronized (stats) {
12889                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12890                            app.pid, SystemClock.elapsedRealtime());
12891                }
12892                app.lastCpuTime = app.curCpuTime;
12893            }
12894
12895            app.setRawAdj = app.curRawAdj;
12896        }
12897
12898        if (app.curAdj != app.setAdj) {
12899            if (Process.setOomAdj(app.pid, app.curAdj)) {
12900                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12901                    TAG, "Set " + app.pid + " " + app.processName +
12902                    " adj " + app.curAdj + ": " + app.adjType);
12903                app.setAdj = app.curAdj;
12904            } else {
12905                success = false;
12906                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12907            }
12908        }
12909        if (app.setSchedGroup != app.curSchedGroup) {
12910            app.setSchedGroup = app.curSchedGroup;
12911            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12912                    "Setting process group of " + app.processName
12913                    + " to " + app.curSchedGroup);
12914            if (app.waitingToKill != null &&
12915                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12916                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12917                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12918                        app.processName, app.setAdj, app.waitingToKill);
12919                app.killedBackground = true;
12920                Process.killProcessQuiet(app.pid);
12921                success = false;
12922            } else {
12923                if (true) {
12924                    long oldId = Binder.clearCallingIdentity();
12925                    try {
12926                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12927                    } catch (Exception e) {
12928                        Slog.w(TAG, "Failed setting process group of " + app.pid
12929                                + " to " + app.curSchedGroup);
12930                        e.printStackTrace();
12931                    } finally {
12932                        Binder.restoreCallingIdentity(oldId);
12933                    }
12934                } else {
12935                    if (app.thread != null) {
12936                        try {
12937                            app.thread.setSchedulingGroup(app.curSchedGroup);
12938                        } catch (RemoteException e) {
12939                        }
12940                    }
12941                }
12942            }
12943        }
12944        return success;
12945    }
12946
12947    private final ActivityRecord resumedAppLocked() {
12948        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12949        if (resumedActivity == null || resumedActivity.app == null) {
12950            resumedActivity = mMainStack.mPausingActivity;
12951            if (resumedActivity == null || resumedActivity.app == null) {
12952                resumedActivity = mMainStack.topRunningActivityLocked(null);
12953            }
12954        }
12955        return resumedActivity;
12956    }
12957
12958    final boolean updateOomAdjLocked(ProcessRecord app) {
12959        final ActivityRecord TOP_ACT = resumedAppLocked();
12960        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12961        int curAdj = app.curAdj;
12962        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12963            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12964
12965        mAdjSeq++;
12966
12967        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
12968                TOP_APP, false);
12969        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12970            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12971        if (nowHidden != wasHidden) {
12972            // Changed to/from hidden state, so apps after it in the LRU
12973            // list may also be changed.
12974            updateOomAdjLocked();
12975        }
12976        return success;
12977    }
12978
12979    final void updateOomAdjLocked() {
12980        final ActivityRecord TOP_ACT = resumedAppLocked();
12981        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12982
12983        if (false) {
12984            RuntimeException e = new RuntimeException();
12985            e.fillInStackTrace();
12986            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12987        }
12988
12989        mAdjSeq++;
12990        mNewNumServiceProcs = 0;
12991
12992        // Let's determine how many processes we have running vs.
12993        // how many slots we have for background processes; we may want
12994        // to put multiple processes in a slot of there are enough of
12995        // them.
12996        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
12997                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
12998        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
12999        if (emptyFactor < 1) emptyFactor = 1;
13000        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13001        if (hiddenFactor < 1) hiddenFactor = 1;
13002        int stepHidden = 0;
13003        int stepEmpty = 0;
13004        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13005        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13006        int numHidden = 0;
13007        int numEmpty = 0;
13008        int numTrimming = 0;
13009
13010        mNumNonHiddenProcs = 0;
13011        mNumHiddenProcs = 0;
13012
13013        // First update the OOM adjustment for each of the
13014        // application processes based on their current state.
13015        int i = mLruProcesses.size();
13016        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13017        int nextHiddenAdj = curHiddenAdj+1;
13018        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13019        int nextEmptyAdj = curEmptyAdj+2;
13020        while (i > 0) {
13021            i--;
13022            ProcessRecord app = mLruProcesses.get(i);
13023            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13024            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13025            if (!app.killedBackground) {
13026                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13027                    // This process was assigned as a hidden process...  step the
13028                    // hidden level.
13029                    mNumHiddenProcs++;
13030                    if (curHiddenAdj != nextHiddenAdj) {
13031                        stepHidden++;
13032                        if (stepHidden >= hiddenFactor) {
13033                            stepHidden = 0;
13034                            curHiddenAdj = nextHiddenAdj;
13035                            nextHiddenAdj += 2;
13036                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13037                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13038                            }
13039                        }
13040                    }
13041                    numHidden++;
13042                    if (numHidden > hiddenProcessLimit) {
13043                        Slog.i(TAG, "No longer want " + app.processName
13044                                + " (pid " + app.pid + "): hidden #" + numHidden);
13045                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13046                                app.processName, app.setAdj, "too many background");
13047                        app.killedBackground = true;
13048                        Process.killProcessQuiet(app.pid);
13049                    }
13050                } else {
13051                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13052                        // This process was assigned as an empty process...  step the
13053                        // empty level.
13054                        if (curEmptyAdj != nextEmptyAdj) {
13055                            stepEmpty++;
13056                            if (stepEmpty >= emptyFactor) {
13057                                stepEmpty = 0;
13058                                curEmptyAdj = nextEmptyAdj;
13059                                nextEmptyAdj += 2;
13060                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13061                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13062                                }
13063                            }
13064                        }
13065                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13066                        mNumNonHiddenProcs++;
13067                    }
13068                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13069                        numEmpty++;
13070                        if (numEmpty > emptyProcessLimit) {
13071                            Slog.i(TAG, "No longer want " + app.processName
13072                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13073                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13074                                    app.processName, app.setAdj, "too many background");
13075                            app.killedBackground = true;
13076                            Process.killProcessQuiet(app.pid);
13077                        }
13078                    }
13079                }
13080                if (app.isolated && app.services.size() <= 0) {
13081                    // If this is an isolated process, and there are no
13082                    // services running in it, then the process is no longer
13083                    // needed.  We agressively kill these because we can by
13084                    // definition not re-use the same process again, and it is
13085                    // good to avoid having whatever code was running in them
13086                    // left sitting around after no longer needed.
13087                    Slog.i(TAG, "Isolated process " + app.processName
13088                            + " (pid " + app.pid + ") no longer needed");
13089                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13090                            app.processName, app.setAdj, "isolated not needed");
13091                    app.killedBackground = true;
13092                    Process.killProcessQuiet(app.pid);
13093                }
13094                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13095                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13096                        && !app.killedBackground) {
13097                    numTrimming++;
13098                }
13099            }
13100        }
13101
13102        mNumServiceProcs = mNewNumServiceProcs;
13103
13104        // Now determine the memory trimming level of background processes.
13105        // Unfortunately we need to start at the back of the list to do this
13106        // properly.  We only do this if the number of background apps we
13107        // are managing to keep around is less than half the maximum we desire;
13108        // if we are keeping a good number around, we'll let them use whatever
13109        // memory they want.
13110        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13111                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13112            final int numHiddenAndEmpty = numHidden + numEmpty;
13113            final int N = mLruProcesses.size();
13114            int factor = numTrimming/3;
13115            int minFactor = 2;
13116            if (mHomeProcess != null) minFactor++;
13117            if (mPreviousProcess != null) minFactor++;
13118            if (factor < minFactor) factor = minFactor;
13119            int step = 0;
13120            int fgTrimLevel;
13121            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13122                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13123            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13124                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13125            } else {
13126                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13127            }
13128            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13129            for (i=0; i<N; i++) {
13130                ProcessRecord app = mLruProcesses.get(i);
13131                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13132                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13133                        && !app.killedBackground) {
13134                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13135                        try {
13136                            app.thread.scheduleTrimMemory(curLevel);
13137                        } catch (RemoteException e) {
13138                        }
13139                        if (false) {
13140                            // For now we won't do this; our memory trimming seems
13141                            // to be good enough at this point that destroying
13142                            // activities causes more harm than good.
13143                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13144                                    && app != mHomeProcess && app != mPreviousProcess) {
13145                                // Need to do this on its own message because the stack may not
13146                                // be in a consistent state at this point.
13147                                // For these apps we will also finish their activities
13148                                // to help them free memory.
13149                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13150                            }
13151                        }
13152                    }
13153                    app.trimMemoryLevel = curLevel;
13154                    step++;
13155                    if (step >= factor) {
13156                        step = 0;
13157                        switch (curLevel) {
13158                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13159                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13160                                break;
13161                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13162                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13163                                break;
13164                        }
13165                    }
13166                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13167                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13168                            && app.thread != null) {
13169                        try {
13170                            app.thread.scheduleTrimMemory(
13171                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13172                        } catch (RemoteException e) {
13173                        }
13174                    }
13175                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13176                } else {
13177                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13178                            && app.pendingUiClean) {
13179                        // If this application is now in the background and it
13180                        // had done UI, then give it the special trim level to
13181                        // have it free UI resources.
13182                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13183                        if (app.trimMemoryLevel < level && app.thread != null) {
13184                            try {
13185                                app.thread.scheduleTrimMemory(level);
13186                            } catch (RemoteException e) {
13187                            }
13188                        }
13189                        app.pendingUiClean = false;
13190                    }
13191                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13192                        try {
13193                            app.thread.scheduleTrimMemory(fgTrimLevel);
13194                        } catch (RemoteException e) {
13195                        }
13196                    }
13197                    app.trimMemoryLevel = fgTrimLevel;
13198                }
13199            }
13200        } else {
13201            final int N = mLruProcesses.size();
13202            for (i=0; i<N; i++) {
13203                ProcessRecord app = mLruProcesses.get(i);
13204                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13205                        && app.pendingUiClean) {
13206                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13207                            && app.thread != null) {
13208                        try {
13209                            app.thread.scheduleTrimMemory(
13210                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13211                        } catch (RemoteException e) {
13212                        }
13213                    }
13214                    app.pendingUiClean = false;
13215                }
13216                app.trimMemoryLevel = 0;
13217            }
13218        }
13219
13220        if (mAlwaysFinishActivities) {
13221            // Need to do this on its own message because the stack may not
13222            // be in a consistent state at this point.
13223            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13224        }
13225    }
13226
13227    final void trimApplications() {
13228        synchronized (this) {
13229            int i;
13230
13231            // First remove any unused application processes whose package
13232            // has been removed.
13233            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13234                final ProcessRecord app = mRemovedProcesses.get(i);
13235                if (app.activities.size() == 0
13236                        && app.curReceiver == null && app.services.size() == 0) {
13237                    Slog.i(
13238                        TAG, "Exiting empty application process "
13239                        + app.processName + " ("
13240                        + (app.thread != null ? app.thread.asBinder() : null)
13241                        + ")\n");
13242                    if (app.pid > 0 && app.pid != MY_PID) {
13243                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13244                                app.processName, app.setAdj, "empty");
13245                        Process.killProcessQuiet(app.pid);
13246                    } else {
13247                        try {
13248                            app.thread.scheduleExit();
13249                        } catch (Exception e) {
13250                            // Ignore exceptions.
13251                        }
13252                    }
13253                    cleanUpApplicationRecordLocked(app, false, true, -1);
13254                    mRemovedProcesses.remove(i);
13255
13256                    if (app.persistent) {
13257                        if (app.persistent) {
13258                            addAppLocked(app.info, false);
13259                        }
13260                    }
13261                }
13262            }
13263
13264            // Now update the oom adj for all processes.
13265            updateOomAdjLocked();
13266        }
13267    }
13268
13269    /** This method sends the specified signal to each of the persistent apps */
13270    public void signalPersistentProcesses(int sig) throws RemoteException {
13271        if (sig != Process.SIGNAL_USR1) {
13272            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13273        }
13274
13275        synchronized (this) {
13276            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13277                    != PackageManager.PERMISSION_GRANTED) {
13278                throw new SecurityException("Requires permission "
13279                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13280            }
13281
13282            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13283                ProcessRecord r = mLruProcesses.get(i);
13284                if (r.thread != null && r.persistent) {
13285                    Process.sendSignal(r.pid, sig);
13286                }
13287            }
13288        }
13289    }
13290
13291    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13292        if (proc == null || proc == mProfileProc) {
13293            proc = mProfileProc;
13294            path = mProfileFile;
13295            profileType = mProfileType;
13296            clearProfilerLocked();
13297        }
13298        if (proc == null) {
13299            return;
13300        }
13301        try {
13302            proc.thread.profilerControl(false, path, null, profileType);
13303        } catch (RemoteException e) {
13304            throw new IllegalStateException("Process disappeared");
13305        }
13306    }
13307
13308    private void clearProfilerLocked() {
13309        if (mProfileFd != null) {
13310            try {
13311                mProfileFd.close();
13312            } catch (IOException e) {
13313            }
13314        }
13315        mProfileApp = null;
13316        mProfileProc = null;
13317        mProfileFile = null;
13318        mProfileType = 0;
13319        mAutoStopProfiler = false;
13320    }
13321
13322    public boolean profileControl(String process, boolean start,
13323            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13324
13325        try {
13326            synchronized (this) {
13327                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13328                // its own permission.
13329                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13330                        != PackageManager.PERMISSION_GRANTED) {
13331                    throw new SecurityException("Requires permission "
13332                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13333                }
13334
13335                if (start && fd == null) {
13336                    throw new IllegalArgumentException("null fd");
13337                }
13338
13339                ProcessRecord proc = null;
13340                if (process != null) {
13341                    try {
13342                        int pid = Integer.parseInt(process);
13343                        synchronized (mPidsSelfLocked) {
13344                            proc = mPidsSelfLocked.get(pid);
13345                        }
13346                    } catch (NumberFormatException e) {
13347                    }
13348
13349                    if (proc == null) {
13350                        HashMap<String, SparseArray<ProcessRecord>> all
13351                                = mProcessNames.getMap();
13352                        SparseArray<ProcessRecord> procs = all.get(process);
13353                        if (procs != null && procs.size() > 0) {
13354                            proc = procs.valueAt(0);
13355                        }
13356                    }
13357                }
13358
13359                if (start && (proc == null || proc.thread == null)) {
13360                    throw new IllegalArgumentException("Unknown process: " + process);
13361                }
13362
13363                if (start) {
13364                    stopProfilerLocked(null, null, 0);
13365                    setProfileApp(proc.info, proc.processName, path, fd, false);
13366                    mProfileProc = proc;
13367                    mProfileType = profileType;
13368                    try {
13369                        fd = fd.dup();
13370                    } catch (IOException e) {
13371                        fd = null;
13372                    }
13373                    proc.thread.profilerControl(start, path, fd, profileType);
13374                    fd = null;
13375                    mProfileFd = null;
13376                } else {
13377                    stopProfilerLocked(proc, path, profileType);
13378                    if (fd != null) {
13379                        try {
13380                            fd.close();
13381                        } catch (IOException e) {
13382                        }
13383                    }
13384                }
13385
13386                return true;
13387            }
13388        } catch (RemoteException e) {
13389            throw new IllegalStateException("Process disappeared");
13390        } finally {
13391            if (fd != null) {
13392                try {
13393                    fd.close();
13394                } catch (IOException e) {
13395                }
13396            }
13397        }
13398    }
13399
13400    public boolean dumpHeap(String process, boolean managed,
13401            String path, ParcelFileDescriptor fd) throws RemoteException {
13402
13403        try {
13404            synchronized (this) {
13405                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13406                // its own permission (same as profileControl).
13407                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13408                        != PackageManager.PERMISSION_GRANTED) {
13409                    throw new SecurityException("Requires permission "
13410                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13411                }
13412
13413                if (fd == null) {
13414                    throw new IllegalArgumentException("null fd");
13415                }
13416
13417                ProcessRecord proc = null;
13418                try {
13419                    int pid = Integer.parseInt(process);
13420                    synchronized (mPidsSelfLocked) {
13421                        proc = mPidsSelfLocked.get(pid);
13422                    }
13423                } catch (NumberFormatException e) {
13424                }
13425
13426                if (proc == null) {
13427                    HashMap<String, SparseArray<ProcessRecord>> all
13428                            = mProcessNames.getMap();
13429                    SparseArray<ProcessRecord> procs = all.get(process);
13430                    if (procs != null && procs.size() > 0) {
13431                        proc = procs.valueAt(0);
13432                    }
13433                }
13434
13435                if (proc == null || proc.thread == null) {
13436                    throw new IllegalArgumentException("Unknown process: " + process);
13437                }
13438
13439                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13440                if (!isDebuggable) {
13441                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13442                        throw new SecurityException("Process not debuggable: " + proc);
13443                    }
13444                }
13445
13446                proc.thread.dumpHeap(managed, path, fd);
13447                fd = null;
13448                return true;
13449            }
13450        } catch (RemoteException e) {
13451            throw new IllegalStateException("Process disappeared");
13452        } finally {
13453            if (fd != null) {
13454                try {
13455                    fd.close();
13456                } catch (IOException e) {
13457                }
13458            }
13459        }
13460    }
13461
13462    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13463    public void monitor() {
13464        synchronized (this) { }
13465    }
13466
13467    void onCoreSettingsChange(Bundle settings) {
13468        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13469            ProcessRecord processRecord = mLruProcesses.get(i);
13470            try {
13471                if (processRecord.thread != null) {
13472                    processRecord.thread.setCoreSettings(settings);
13473                }
13474            } catch (RemoteException re) {
13475                /* ignore */
13476            }
13477        }
13478    }
13479
13480    // Multi-user methods
13481
13482    public boolean switchUser(int userId) {
13483        final int callingUid = Binder.getCallingUid();
13484        if (callingUid != 0 && callingUid != Process.myUid()) {
13485            Slog.e(TAG, "Trying to switch user from unauthorized app");
13486            return false;
13487        }
13488        if (mCurrentUserId == userId)
13489            return true;
13490
13491        synchronized (this) {
13492            // Check if user is already logged in, otherwise check if user exists first before
13493            // adding to the list of logged in users.
13494            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13495                if (!userExists(userId)) {
13496                    return false;
13497                }
13498                mLoggedInUsers.append(userId, userId);
13499            }
13500
13501            mCurrentUserId = userId;
13502            boolean haveActivities = mMainStack.switchUser(userId);
13503            if (!haveActivities) {
13504                startHomeActivityLocked(userId);
13505            }
13506
13507        }
13508
13509        // Inform of user switch
13510        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13511        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13512        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
13513
13514        return true;
13515    }
13516
13517    @Override
13518    public UserInfo getCurrentUser() throws RemoteException {
13519        final int callingUid = Binder.getCallingUid();
13520        if (callingUid != 0 && callingUid != Process.myUid()) {
13521            Slog.e(TAG, "Trying to get user from unauthorized app");
13522            return null;
13523        }
13524        return getUserManager().getUserInfo(mCurrentUserId);
13525    }
13526
13527    private void onUserRemoved(Intent intent) {
13528        int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
13529        if (extraUserId < 1) return;
13530
13531        // Kill all the processes for the user
13532        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13533        synchronized (this) {
13534            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13535            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13536                SparseArray<ProcessRecord> uids = uidMap.getValue();
13537                for (int i = 0; i < uids.size(); i++) {
13538                    if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
13539                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13540                    }
13541                }
13542            }
13543
13544            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13545                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13546                        false, false, true, true, extraUserId);
13547            }
13548        }
13549    }
13550
13551    private boolean userExists(int userId) {
13552        UserInfo user = getUserManager().getUserInfo(userId);
13553        return user != null;
13554    }
13555
13556    UserManager getUserManager() {
13557        if (mUserManager == null) {
13558            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13559        }
13560        return mUserManager;
13561    }
13562
13563    private void checkValidCaller(int uid, int userId) {
13564        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13565
13566        throw new SecurityException("Caller uid=" + uid
13567                + " is not privileged to communicate with user=" + userId);
13568    }
13569
13570    private int applyUserId(int uid, int userId) {
13571        return UserHandle.getUid(userId, uid);
13572    }
13573
13574    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13575        if (info == null) return null;
13576        ApplicationInfo newInfo = new ApplicationInfo(info);
13577        newInfo.uid = applyUserId(info.uid, userId);
13578        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13579                + info.packageName;
13580        return newInfo;
13581    }
13582
13583    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13584        if (aInfo == null
13585                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13586            return aInfo;
13587        }
13588
13589        ActivityInfo info = new ActivityInfo(aInfo);
13590        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13591        return info;
13592    }
13593}
13594