ActivityManagerService.java revision cc5a055613efb463275633d83a04674b0be6d770
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.pm.UserManagerService;
31import com.android.server.wm.WindowManagerService;
32
33import dalvik.system.Zygote;
34
35import android.app.Activity;
36import android.app.ActivityManager;
37import android.app.ActivityManagerNative;
38import android.app.ActivityOptions;
39import android.app.ActivityThread;
40import android.app.AlertDialog;
41import android.app.AppGlobals;
42import android.app.ApplicationErrorReport;
43import android.app.Dialog;
44import android.app.IActivityController;
45import android.app.IApplicationThread;
46import android.app.IInstrumentationWatcher;
47import android.app.INotificationManager;
48import android.app.IProcessObserver;
49import android.app.IServiceConnection;
50import android.app.IStopUserCallback;
51import android.app.IThumbnailReceiver;
52import android.app.IUserSwitchObserver;
53import android.app.Instrumentation;
54import android.app.Notification;
55import android.app.NotificationManager;
56import android.app.PendingIntent;
57import android.app.backup.IBackupManager;
58import android.content.ActivityNotFoundException;
59import android.content.BroadcastReceiver;
60import android.content.ClipData;
61import android.content.ComponentCallbacks2;
62import android.content.ComponentName;
63import android.content.ContentProvider;
64import android.content.ContentResolver;
65import android.content.Context;
66import android.content.DialogInterface;
67import android.content.IContentProvider;
68import android.content.IIntentReceiver;
69import android.content.IIntentSender;
70import android.content.Intent;
71import android.content.IntentFilter;
72import android.content.IntentSender;
73import android.content.pm.ActivityInfo;
74import android.content.pm.ApplicationInfo;
75import android.content.pm.ConfigurationInfo;
76import android.content.pm.IPackageDataObserver;
77import android.content.pm.IPackageManager;
78import android.content.pm.InstrumentationInfo;
79import android.content.pm.PackageInfo;
80import android.content.pm.PackageManager;
81import android.content.pm.UserInfo;
82import android.content.pm.PackageManager.NameNotFoundException;
83import android.content.pm.PathPermission;
84import android.content.pm.ProviderInfo;
85import android.content.pm.ResolveInfo;
86import android.content.pm.ServiceInfo;
87import android.content.res.CompatibilityInfo;
88import android.content.res.Configuration;
89import android.graphics.Bitmap;
90import android.net.Proxy;
91import android.net.ProxyProperties;
92import android.net.Uri;
93import android.os.Binder;
94import android.os.Build;
95import android.os.Bundle;
96import android.os.Debug;
97import android.os.DropBoxManager;
98import android.os.Environment;
99import android.os.FileObserver;
100import android.os.FileUtils;
101import android.os.Handler;
102import android.os.IBinder;
103import android.os.IPermissionController;
104import android.os.IRemoteCallback;
105import android.os.IUserManager;
106import android.os.Looper;
107import android.os.Message;
108import android.os.Parcel;
109import android.os.ParcelFileDescriptor;
110import android.os.Process;
111import android.os.RemoteCallbackList;
112import android.os.RemoteException;
113import android.os.SELinux;
114import android.os.ServiceManager;
115import android.os.StrictMode;
116import android.os.SystemClock;
117import android.os.SystemProperties;
118import android.os.UserHandle;
119import android.provider.Settings;
120import android.text.format.Time;
121import android.util.EventLog;
122import android.util.Log;
123import android.util.Pair;
124import android.util.PrintWriterPrinter;
125import android.util.Slog;
126import android.util.SparseArray;
127import android.util.TimeUtils;
128import android.view.Gravity;
129import android.view.LayoutInflater;
130import android.view.View;
131import android.view.WindowManager;
132import android.view.WindowManagerPolicy;
133
134import java.io.BufferedInputStream;
135import java.io.BufferedOutputStream;
136import java.io.BufferedReader;
137import java.io.DataInputStream;
138import java.io.DataOutputStream;
139import java.io.File;
140import java.io.FileDescriptor;
141import java.io.FileInputStream;
142import java.io.FileNotFoundException;
143import java.io.FileOutputStream;
144import java.io.IOException;
145import java.io.InputStreamReader;
146import java.io.PrintWriter;
147import java.io.StringWriter;
148import java.lang.ref.WeakReference;
149import java.util.ArrayList;
150import java.util.Arrays;
151import java.util.Collections;
152import java.util.Comparator;
153import java.util.HashMap;
154import java.util.HashSet;
155import java.util.Iterator;
156import java.util.List;
157import java.util.Locale;
158import java.util.Map;
159import java.util.Set;
160import java.util.concurrent.atomic.AtomicBoolean;
161import java.util.concurrent.atomic.AtomicLong;
162
163public final class ActivityManagerService extends ActivityManagerNative
164        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
165    private static final String USER_DATA_DIR = "/data/user/";
166    static final String TAG = "ActivityManager";
167    static final String TAG_MU = "ActivityManagerServiceMU";
168    static final boolean DEBUG = false;
169    static final boolean localLOGV = DEBUG;
170    static final boolean DEBUG_SWITCH = localLOGV || false;
171    static final boolean DEBUG_TASKS = localLOGV || false;
172    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
173    static final boolean DEBUG_PAUSE = localLOGV || false;
174    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
175    static final boolean DEBUG_TRANSITION = localLOGV || false;
176    static final boolean DEBUG_BROADCAST = localLOGV || false;
177    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
178    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
179    static final boolean DEBUG_SERVICE = localLOGV || false;
180    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
181    static final boolean DEBUG_VISBILITY = localLOGV || false;
182    static final boolean DEBUG_PROCESSES = localLOGV || false;
183    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
184    static final boolean DEBUG_CLEANUP = localLOGV || false;
185    static final boolean DEBUG_PROVIDER = localLOGV || false;
186    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
187    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
188    static final boolean DEBUG_RESULTS = localLOGV || false;
189    static final boolean DEBUG_BACKUP = localLOGV || false;
190    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
191    static final boolean DEBUG_POWER = localLOGV || false;
192    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
193    static final boolean DEBUG_MU = localLOGV || false;
194    static final boolean VALIDATE_TOKENS = false;
195    static final boolean SHOW_ACTIVITY_START_TIME = true;
196
197    // Control over CPU and battery monitoring.
198    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
199    static final boolean MONITOR_CPU_USAGE = true;
200    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
201    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
202    static final boolean MONITOR_THREAD_CPU_USAGE = false;
203
204    // The flags that are set for all calls we make to the package manager.
205    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
206
207    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
208
209    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
210
211    // Maximum number of recent tasks that we can remember.
212    static final int MAX_RECENT_TASKS = 20;
213
214    // Amount of time after a call to stopAppSwitches() during which we will
215    // prevent further untrusted switches from happening.
216    static final long APP_SWITCH_DELAY_TIME = 5*1000;
217
218    // How long we wait for a launched process to attach to the activity manager
219    // before we decide it's never going to come up for real.
220    static final int PROC_START_TIMEOUT = 10*1000;
221
222    // How long we wait for a launched process to attach to the activity manager
223    // before we decide it's never going to come up for real, when the process was
224    // started with a wrapper for instrumentation (such as Valgrind) because it
225    // could take much longer than usual.
226    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
227
228    // How long to wait after going idle before forcing apps to GC.
229    static final int GC_TIMEOUT = 5*1000;
230
231    // The minimum amount of time between successive GC requests for a process.
232    static final int GC_MIN_INTERVAL = 60*1000;
233
234    // The rate at which we check for apps using excessive power -- 15 mins.
235    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
236
237    // The minimum sample duration we will allow before deciding we have
238    // enough data on wake locks to start killing things.
239    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
240
241    // The minimum sample duration we will allow before deciding we have
242    // enough data on CPU usage to start killing things.
243    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
244
245    // How long we allow a receiver to run before giving up on it.
246    static final int BROADCAST_FG_TIMEOUT = 10*1000;
247    static final int BROADCAST_BG_TIMEOUT = 60*1000;
248
249    // How long we wait until we timeout on key dispatching.
250    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
251
252    // How long we wait until we timeout on key dispatching during instrumentation.
253    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
254
255    // Amount of time we wait for observers to handle a user switch before
256    // giving up on them and unfreezing the screen.
257    static final int USER_SWITCH_TIMEOUT = 2*1000;
258
259    // Maximum number of users we allow to be running at a time.
260    static final int MAX_RUNNING_USERS = 3;
261
262    static final int MY_PID = Process.myPid();
263
264    static final String[] EMPTY_STRING_ARRAY = new String[0];
265
266    public ActivityStack mMainStack;
267
268    private final boolean mHeadless;
269
270    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
271    // default actuion automatically.  Important for devices without direct input
272    // devices.
273    private boolean mShowDialogs = true;
274
275    /**
276     * Description of a request to start a new activity, which has been held
277     * due to app switches being disabled.
278     */
279    static class PendingActivityLaunch {
280        ActivityRecord r;
281        ActivityRecord sourceRecord;
282        int startFlags;
283    }
284
285    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
286            = new ArrayList<PendingActivityLaunch>();
287
288
289    BroadcastQueue mFgBroadcastQueue;
290    BroadcastQueue mBgBroadcastQueue;
291    // Convenient for easy iteration over the queues. Foreground is first
292    // so that dispatch of foreground broadcasts gets precedence.
293    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
294
295    BroadcastQueue broadcastQueueForIntent(Intent intent) {
296        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
297        if (DEBUG_BACKGROUND_BROADCAST) {
298            Slog.i(TAG, "Broadcast intent " + intent + " on "
299                    + (isFg ? "foreground" : "background")
300                    + " queue");
301        }
302        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
303    }
304
305    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
306        for (BroadcastQueue queue : mBroadcastQueues) {
307            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
308            if (r != null) {
309                return r;
310            }
311        }
312        return null;
313    }
314
315    /**
316     * Activity we have told the window manager to have key focus.
317     */
318    ActivityRecord mFocusedActivity = null;
319    /**
320     * List of intents that were used to start the most recent tasks.
321     */
322    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
323
324    /**
325     * Process management.
326     */
327    final ProcessList mProcessList = new ProcessList();
328
329    /**
330     * All of the applications we currently have running organized by name.
331     * The keys are strings of the application package name (as
332     * returned by the package manager), and the keys are ApplicationRecord
333     * objects.
334     */
335    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
336
337    /**
338     * The currently running isolated processes.
339     */
340    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
341
342    /**
343     * Counter for assigning isolated process uids, to avoid frequently reusing the
344     * same ones.
345     */
346    int mNextIsolatedProcessUid = 0;
347
348    /**
349     * The currently running heavy-weight process, if any.
350     */
351    ProcessRecord mHeavyWeightProcess = null;
352
353    /**
354     * The last time that various processes have crashed.
355     */
356    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
357
358    /**
359     * Set of applications that we consider to be bad, and will reject
360     * incoming broadcasts from (which the user has no control over).
361     * Processes are added to this set when they have crashed twice within
362     * a minimum amount of time; they are removed from it when they are
363     * later restarted (hopefully due to some user action).  The value is the
364     * time it was added to the list.
365     */
366    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
367
368    /**
369     * All of the processes we currently have running organized by pid.
370     * The keys are the pid running the application.
371     *
372     * <p>NOTE: This object is protected by its own lock, NOT the global
373     * activity manager lock!
374     */
375    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
376
377    /**
378     * All of the processes that have been forced to be foreground.  The key
379     * is the pid of the caller who requested it (we hold a death
380     * link on it).
381     */
382    abstract class ForegroundToken implements IBinder.DeathRecipient {
383        int pid;
384        IBinder token;
385    }
386    final SparseArray<ForegroundToken> mForegroundProcesses
387            = new SparseArray<ForegroundToken>();
388
389    /**
390     * List of records for processes that someone had tried to start before the
391     * system was ready.  We don't start them at that point, but ensure they
392     * are started by the time booting is complete.
393     */
394    final ArrayList<ProcessRecord> mProcessesOnHold
395            = new ArrayList<ProcessRecord>();
396
397    /**
398     * List of persistent applications that are in the process
399     * of being started.
400     */
401    final ArrayList<ProcessRecord> mPersistentStartingProcesses
402            = new ArrayList<ProcessRecord>();
403
404    /**
405     * Processes that are being forcibly torn down.
406     */
407    final ArrayList<ProcessRecord> mRemovedProcesses
408            = new ArrayList<ProcessRecord>();
409
410    /**
411     * List of running applications, sorted by recent usage.
412     * The first entry in the list is the least recently used.
413     * It contains ApplicationRecord objects.  This list does NOT include
414     * any persistent application records (since we never want to exit them).
415     */
416    final ArrayList<ProcessRecord> mLruProcesses
417            = new ArrayList<ProcessRecord>();
418
419    /**
420     * List of processes that should gc as soon as things are idle.
421     */
422    final ArrayList<ProcessRecord> mProcessesToGc
423            = new ArrayList<ProcessRecord>();
424
425    /**
426     * This is the process holding what we currently consider to be
427     * the "home" activity.
428     */
429    ProcessRecord mHomeProcess;
430
431    /**
432     * This is the process holding the activity the user last visited that
433     * is in a different process from the one they are currently in.
434     */
435    ProcessRecord mPreviousProcess;
436
437    /**
438     * The time at which the previous process was last visible.
439     */
440    long mPreviousProcessVisibleTime;
441
442    /**
443     * Which uses have been started, so are allowed to run code.
444     */
445    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
446
447    /**
448     * LRU list of history of current users.  Most recently current is at the end.
449     */
450    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
451
452    /**
453     * Constant array of the users that are currently started.
454     */
455    int[] mStartedUserArray = new int[] { 0 };
456
457    /**
458     * Registered observers of the user switching mechanics.
459     */
460    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
461            = new RemoteCallbackList<IUserSwitchObserver>();
462
463    /**
464     * Currently active user switch.
465     */
466    Object mCurUserSwitchCallback;
467
468    /**
469     * Packages that the user has asked to have run in screen size
470     * compatibility mode instead of filling the screen.
471     */
472    final CompatModePackages mCompatModePackages;
473
474    /**
475     * Set of PendingResultRecord objects that are currently active.
476     */
477    final HashSet mPendingResultRecords = new HashSet();
478
479    /**
480     * Set of IntentSenderRecord objects that are currently active.
481     */
482    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
483            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
484
485    /**
486     * Fingerprints (hashCode()) of stack traces that we've
487     * already logged DropBox entries for.  Guarded by itself.  If
488     * something (rogue user app) forces this over
489     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
490     */
491    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
492    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
493
494    /**
495     * Strict Mode background batched logging state.
496     *
497     * The string buffer is guarded by itself, and its lock is also
498     * used to determine if another batched write is already
499     * in-flight.
500     */
501    private final StringBuilder mStrictModeBuffer = new StringBuilder();
502
503    /**
504     * Keeps track of all IIntentReceivers that have been registered for
505     * broadcasts.  Hash keys are the receiver IBinder, hash value is
506     * a ReceiverList.
507     */
508    final HashMap mRegisteredReceivers = new HashMap();
509
510    /**
511     * Resolver for broadcast intents to registered receivers.
512     * Holds BroadcastFilter (subclass of IntentFilter).
513     */
514    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
515            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
516        @Override
517        protected boolean allowFilterResult(
518                BroadcastFilter filter, List<BroadcastFilter> dest) {
519            IBinder target = filter.receiverList.receiver.asBinder();
520            for (int i=dest.size()-1; i>=0; i--) {
521                if (dest.get(i).receiverList.receiver.asBinder() == target) {
522                    return false;
523                }
524            }
525            return true;
526        }
527
528        @Override
529        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
530            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
531                    || userId == filter.owningUserId) {
532                return super.newResult(filter, match, userId);
533            }
534            return null;
535        }
536
537        @Override
538        protected BroadcastFilter[] newArray(int size) {
539            return new BroadcastFilter[size];
540        }
541
542        @Override
543        protected String packageForFilter(BroadcastFilter filter) {
544            return filter.packageName;
545        }
546    };
547
548    /**
549     * State of all active sticky broadcasts per user.  Keys are the action of the
550     * sticky Intent, values are an ArrayList of all broadcasted intents with
551     * that action (which should usually be one).  The SparseArray is keyed
552     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
553     * for stickies that are sent to all users.
554     */
555    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
556            new SparseArray<HashMap<String, ArrayList<Intent>>>();
557
558    final ActiveServices mServices;
559
560    /**
561     * Backup/restore process management
562     */
563    String mBackupAppName = null;
564    BackupRecord mBackupTarget = null;
565
566    /**
567     * List of PendingThumbnailsRecord objects of clients who are still
568     * waiting to receive all of the thumbnails for a task.
569     */
570    final ArrayList mPendingThumbnails = new ArrayList();
571
572    /**
573     * List of HistoryRecord objects that have been finished and must
574     * still report back to a pending thumbnail receiver.
575     */
576    final ArrayList mCancelledThumbnails = new ArrayList();
577
578    final ProviderMap mProviderMap;
579
580    /**
581     * List of content providers who have clients waiting for them.  The
582     * application is currently being launched and the provider will be
583     * removed from this list once it is published.
584     */
585    final ArrayList<ContentProviderRecord> mLaunchingProviders
586            = new ArrayList<ContentProviderRecord>();
587
588    /**
589     * Global set of specific Uri permissions that have been granted.
590     */
591    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
592            = new SparseArray<HashMap<Uri, UriPermission>>();
593
594    CoreSettingsObserver mCoreSettingsObserver;
595
596    /**
597     * Thread-local storage used to carry caller permissions over through
598     * indirect content-provider access.
599     * @see #ActivityManagerService.openContentUri()
600     */
601    private class Identity {
602        public int pid;
603        public int uid;
604
605        Identity(int _pid, int _uid) {
606            pid = _pid;
607            uid = _uid;
608        }
609    }
610
611    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
612
613    /**
614     * All information we have collected about the runtime performance of
615     * any user id that can impact battery performance.
616     */
617    final BatteryStatsService mBatteryStatsService;
618
619    /**
620     * information about component usage
621     */
622    final UsageStatsService mUsageStatsService;
623
624    /**
625     * Current configuration information.  HistoryRecord objects are given
626     * a reference to this object to indicate which configuration they are
627     * currently running in, so this object must be kept immutable.
628     */
629    Configuration mConfiguration = new Configuration();
630
631    /**
632     * Current sequencing integer of the configuration, for skipping old
633     * configurations.
634     */
635    int mConfigurationSeq = 0;
636
637    /**
638     * Hardware-reported OpenGLES version.
639     */
640    final int GL_ES_VERSION;
641
642    /**
643     * List of initialization arguments to pass to all processes when binding applications to them.
644     * For example, references to the commonly used services.
645     */
646    HashMap<String, IBinder> mAppBindArgs;
647
648    /**
649     * Temporary to avoid allocations.  Protected by main lock.
650     */
651    final StringBuilder mStringBuilder = new StringBuilder(256);
652
653    /**
654     * Used to control how we initialize the service.
655     */
656    boolean mStartRunning = false;
657    ComponentName mTopComponent;
658    String mTopAction;
659    String mTopData;
660    boolean mProcessesReady = false;
661    boolean mSystemReady = false;
662    boolean mBooting = false;
663    boolean mWaitingUpdate = false;
664    boolean mDidUpdate = false;
665    boolean mOnBattery = false;
666    boolean mLaunchWarningShown = false;
667
668    Context mContext;
669
670    int mFactoryTest;
671
672    boolean mCheckedForSetup;
673
674    /**
675     * The time at which we will allow normal application switches again,
676     * after a call to {@link #stopAppSwitches()}.
677     */
678    long mAppSwitchesAllowedTime;
679
680    /**
681     * This is set to true after the first switch after mAppSwitchesAllowedTime
682     * is set; any switches after that will clear the time.
683     */
684    boolean mDidAppSwitch;
685
686    /**
687     * Last time (in realtime) at which we checked for power usage.
688     */
689    long mLastPowerCheckRealtime;
690
691    /**
692     * Last time (in uptime) at which we checked for power usage.
693     */
694    long mLastPowerCheckUptime;
695
696    /**
697     * Set while we are wanting to sleep, to prevent any
698     * activities from being started/resumed.
699     */
700    boolean mSleeping = false;
701
702    /**
703     * State of external calls telling us if the device is asleep.
704     */
705    boolean mWentToSleep = false;
706
707    /**
708     * State of external call telling us if the lock screen is shown.
709     */
710    boolean mLockScreenShown = false;
711
712    /**
713     * Set if we are shutting down the system, similar to sleeping.
714     */
715    boolean mShuttingDown = false;
716
717    /**
718     * Task identifier that activities are currently being started
719     * in.  Incremented each time a new task is created.
720     * todo: Replace this with a TokenSpace class that generates non-repeating
721     * integers that won't wrap.
722     */
723    int mCurTask = 1;
724
725    /**
726     * Current sequence id for oom_adj computation traversal.
727     */
728    int mAdjSeq = 0;
729
730    /**
731     * Current sequence id for process LRU updating.
732     */
733    int mLruSeq = 0;
734
735    /**
736     * Keep track of the non-hidden/empty process we last found, to help
737     * determine how to distribute hidden/empty processes next time.
738     */
739    int mNumNonHiddenProcs = 0;
740
741    /**
742     * Keep track of the number of hidden procs, to balance oom adj
743     * distribution between those and empty procs.
744     */
745    int mNumHiddenProcs = 0;
746
747    /**
748     * Keep track of the number of service processes we last found, to
749     * determine on the next iteration which should be B services.
750     */
751    int mNumServiceProcs = 0;
752    int mNewNumServiceProcs = 0;
753
754    /**
755     * System monitoring: number of processes that died since the last
756     * N procs were started.
757     */
758    int[] mProcDeaths = new int[20];
759
760    /**
761     * This is set if we had to do a delayed dexopt of an app before launching
762     * it, to increasing the ANR timeouts in that case.
763     */
764    boolean mDidDexOpt;
765
766    String mDebugApp = null;
767    boolean mWaitForDebugger = false;
768    boolean mDebugTransient = false;
769    String mOrigDebugApp = null;
770    boolean mOrigWaitForDebugger = false;
771    boolean mAlwaysFinishActivities = false;
772    IActivityController mController = null;
773    String mProfileApp = null;
774    ProcessRecord mProfileProc = null;
775    String mProfileFile;
776    ParcelFileDescriptor mProfileFd;
777    int mProfileType = 0;
778    boolean mAutoStopProfiler = false;
779    String mOpenGlTraceApp = null;
780
781    static class ProcessChangeItem {
782        static final int CHANGE_ACTIVITIES = 1<<0;
783        static final int CHANGE_IMPORTANCE= 1<<1;
784        int changes;
785        int uid;
786        int pid;
787        int importance;
788        boolean foregroundActivities;
789    }
790
791    final RemoteCallbackList<IProcessObserver> mProcessObservers
792            = new RemoteCallbackList<IProcessObserver>();
793    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
794
795    final ArrayList<ProcessChangeItem> mPendingProcessChanges
796            = new ArrayList<ProcessChangeItem>();
797    final ArrayList<ProcessChangeItem> mAvailProcessChanges
798            = new ArrayList<ProcessChangeItem>();
799
800    /**
801     * Callback of last caller to {@link #requestPss}.
802     */
803    Runnable mRequestPssCallback;
804
805    /**
806     * Remaining processes for which we are waiting results from the last
807     * call to {@link #requestPss}.
808     */
809    final ArrayList<ProcessRecord> mRequestPssList
810            = new ArrayList<ProcessRecord>();
811
812    /**
813     * Runtime statistics collection thread.  This object's lock is used to
814     * protect all related state.
815     */
816    final Thread mProcessStatsThread;
817
818    /**
819     * Used to collect process stats when showing not responding dialog.
820     * Protected by mProcessStatsThread.
821     */
822    final ProcessStats mProcessStats = new ProcessStats(
823            MONITOR_THREAD_CPU_USAGE);
824    final AtomicLong mLastCpuTime = new AtomicLong(0);
825    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
826
827    long mLastWriteTime = 0;
828
829    /**
830     * Set to true after the system has finished booting.
831     */
832    boolean mBooted = false;
833
834    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
835    int mProcessLimitOverride = -1;
836
837    WindowManagerService mWindowManager;
838
839    static ActivityManagerService mSelf;
840    static ActivityThread mSystemThread;
841
842    private int mCurrentUserId = 0;
843    private int[] mCurrentUserArray = new int[] { 0 };
844    private UserManagerService mUserManager;
845
846    private final class AppDeathRecipient implements IBinder.DeathRecipient {
847        final ProcessRecord mApp;
848        final int mPid;
849        final IApplicationThread mAppThread;
850
851        AppDeathRecipient(ProcessRecord app, int pid,
852                IApplicationThread thread) {
853            if (localLOGV) Slog.v(
854                TAG, "New death recipient " + this
855                + " for thread " + thread.asBinder());
856            mApp = app;
857            mPid = pid;
858            mAppThread = thread;
859        }
860
861        public void binderDied() {
862            if (localLOGV) Slog.v(
863                TAG, "Death received in " + this
864                + " for thread " + mAppThread.asBinder());
865            synchronized(ActivityManagerService.this) {
866                appDiedLocked(mApp, mPid, mAppThread);
867            }
868        }
869    }
870
871    static final int SHOW_ERROR_MSG = 1;
872    static final int SHOW_NOT_RESPONDING_MSG = 2;
873    static final int SHOW_FACTORY_ERROR_MSG = 3;
874    static final int UPDATE_CONFIGURATION_MSG = 4;
875    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
876    static final int WAIT_FOR_DEBUGGER_MSG = 6;
877    static final int SERVICE_TIMEOUT_MSG = 12;
878    static final int UPDATE_TIME_ZONE = 13;
879    static final int SHOW_UID_ERROR_MSG = 14;
880    static final int IM_FEELING_LUCKY_MSG = 15;
881    static final int PROC_START_TIMEOUT_MSG = 20;
882    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
883    static final int KILL_APPLICATION_MSG = 22;
884    static final int FINALIZE_PENDING_INTENT_MSG = 23;
885    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
886    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
887    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
888    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
889    static final int CLEAR_DNS_CACHE = 28;
890    static final int UPDATE_HTTP_PROXY = 29;
891    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
892    static final int DISPATCH_PROCESSES_CHANGED = 31;
893    static final int DISPATCH_PROCESS_DIED = 32;
894    static final int REPORT_MEM_USAGE = 33;
895    static final int REPORT_USER_SWITCH_MSG = 34;
896    static final int CONTINUE_USER_SWITCH_MSG = 35;
897    static final int USER_SWITCH_TIMEOUT_MSG = 36;
898
899    static final int FIRST_ACTIVITY_STACK_MSG = 100;
900    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
901    static final int FIRST_COMPAT_MODE_MSG = 300;
902
903    AlertDialog mUidAlert;
904    CompatModeDialog mCompatModeDialog;
905    long mLastMemUsageReportTime = 0;
906
907    final Handler mHandler = new Handler() {
908        //public Handler() {
909        //    if (localLOGV) Slog.v(TAG, "Handler started!");
910        //}
911
912        public void handleMessage(Message msg) {
913            switch (msg.what) {
914            case SHOW_ERROR_MSG: {
915                HashMap data = (HashMap) msg.obj;
916                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
917                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
918                synchronized (ActivityManagerService.this) {
919                    ProcessRecord proc = (ProcessRecord)data.get("app");
920                    AppErrorResult res = (AppErrorResult) data.get("result");
921                    if (proc != null && proc.crashDialog != null) {
922                        Slog.e(TAG, "App already has crash dialog: " + proc);
923                        if (res != null) {
924                            res.set(0);
925                        }
926                        return;
927                    }
928                    if (!showBackground && UserHandle.getAppId(proc.uid)
929                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
930                            && proc.pid != MY_PID) {
931                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
932                        if (res != null) {
933                            res.set(0);
934                        }
935                        return;
936                    }
937                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
938                        Dialog d = new AppErrorDialog(mContext,
939                                ActivityManagerService.this, res, proc);
940                        d.show();
941                        proc.crashDialog = d;
942                    } else {
943                        // The device is asleep, so just pretend that the user
944                        // saw a crash dialog and hit "force quit".
945                        if (res != null) {
946                            res.set(0);
947                        }
948                    }
949                }
950
951                ensureBootCompleted();
952            } break;
953            case SHOW_NOT_RESPONDING_MSG: {
954                synchronized (ActivityManagerService.this) {
955                    HashMap data = (HashMap) msg.obj;
956                    ProcessRecord proc = (ProcessRecord)data.get("app");
957                    if (proc != null && proc.anrDialog != null) {
958                        Slog.e(TAG, "App already has anr dialog: " + proc);
959                        return;
960                    }
961
962                    Intent intent = new Intent("android.intent.action.ANR");
963                    if (!mProcessesReady) {
964                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
965                                | Intent.FLAG_RECEIVER_FOREGROUND);
966                    }
967                    broadcastIntentLocked(null, null, intent,
968                            null, null, 0, null, null, null,
969                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
970
971                    if (mShowDialogs) {
972                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
973                                mContext, proc, (ActivityRecord)data.get("activity"));
974                        d.show();
975                        proc.anrDialog = d;
976                    } else {
977                        // Just kill the app if there is no dialog to be shown.
978                        killAppAtUsersRequest(proc, null);
979                    }
980                }
981
982                ensureBootCompleted();
983            } break;
984            case SHOW_STRICT_MODE_VIOLATION_MSG: {
985                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
986                synchronized (ActivityManagerService.this) {
987                    ProcessRecord proc = (ProcessRecord) data.get("app");
988                    if (proc == null) {
989                        Slog.e(TAG, "App not found when showing strict mode dialog.");
990                        break;
991                    }
992                    if (proc.crashDialog != null) {
993                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
994                        return;
995                    }
996                    AppErrorResult res = (AppErrorResult) data.get("result");
997                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
998                        Dialog d = new StrictModeViolationDialog(mContext,
999                                ActivityManagerService.this, res, proc);
1000                        d.show();
1001                        proc.crashDialog = d;
1002                    } else {
1003                        // The device is asleep, so just pretend that the user
1004                        // saw a crash dialog and hit "force quit".
1005                        res.set(0);
1006                    }
1007                }
1008                ensureBootCompleted();
1009            } break;
1010            case SHOW_FACTORY_ERROR_MSG: {
1011                Dialog d = new FactoryErrorDialog(
1012                    mContext, msg.getData().getCharSequence("msg"));
1013                d.show();
1014                ensureBootCompleted();
1015            } break;
1016            case UPDATE_CONFIGURATION_MSG: {
1017                final ContentResolver resolver = mContext.getContentResolver();
1018                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1019            } break;
1020            case GC_BACKGROUND_PROCESSES_MSG: {
1021                synchronized (ActivityManagerService.this) {
1022                    performAppGcsIfAppropriateLocked();
1023                }
1024            } break;
1025            case WAIT_FOR_DEBUGGER_MSG: {
1026                synchronized (ActivityManagerService.this) {
1027                    ProcessRecord app = (ProcessRecord)msg.obj;
1028                    if (msg.arg1 != 0) {
1029                        if (!app.waitedForDebugger) {
1030                            Dialog d = new AppWaitingForDebuggerDialog(
1031                                    ActivityManagerService.this,
1032                                    mContext, app);
1033                            app.waitDialog = d;
1034                            app.waitedForDebugger = true;
1035                            d.show();
1036                        }
1037                    } else {
1038                        if (app.waitDialog != null) {
1039                            app.waitDialog.dismiss();
1040                            app.waitDialog = null;
1041                        }
1042                    }
1043                }
1044            } break;
1045            case SERVICE_TIMEOUT_MSG: {
1046                if (mDidDexOpt) {
1047                    mDidDexOpt = false;
1048                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1049                    nmsg.obj = msg.obj;
1050                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1051                    return;
1052                }
1053                mServices.serviceTimeout((ProcessRecord)msg.obj);
1054            } break;
1055            case UPDATE_TIME_ZONE: {
1056                synchronized (ActivityManagerService.this) {
1057                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1058                        ProcessRecord r = mLruProcesses.get(i);
1059                        if (r.thread != null) {
1060                            try {
1061                                r.thread.updateTimeZone();
1062                            } catch (RemoteException ex) {
1063                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1064                            }
1065                        }
1066                    }
1067                }
1068            } break;
1069            case CLEAR_DNS_CACHE: {
1070                synchronized (ActivityManagerService.this) {
1071                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1072                        ProcessRecord r = mLruProcesses.get(i);
1073                        if (r.thread != null) {
1074                            try {
1075                                r.thread.clearDnsCache();
1076                            } catch (RemoteException ex) {
1077                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1078                            }
1079                        }
1080                    }
1081                }
1082            } break;
1083            case UPDATE_HTTP_PROXY: {
1084                ProxyProperties proxy = (ProxyProperties)msg.obj;
1085                String host = "";
1086                String port = "";
1087                String exclList = "";
1088                if (proxy != null) {
1089                    host = proxy.getHost();
1090                    port = Integer.toString(proxy.getPort());
1091                    exclList = proxy.getExclusionList();
1092                }
1093                synchronized (ActivityManagerService.this) {
1094                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1095                        ProcessRecord r = mLruProcesses.get(i);
1096                        if (r.thread != null) {
1097                            try {
1098                                r.thread.setHttpProxy(host, port, exclList);
1099                            } catch (RemoteException ex) {
1100                                Slog.w(TAG, "Failed to update http proxy for: " +
1101                                        r.info.processName);
1102                            }
1103                        }
1104                    }
1105                }
1106            } break;
1107            case SHOW_UID_ERROR_MSG: {
1108                String title = "System UIDs Inconsistent";
1109                String text = "UIDs on the system are inconsistent, you need to wipe your"
1110                        + " data partition or your device will be unstable.";
1111                Log.e(TAG, title + ": " + text);
1112                if (mShowDialogs) {
1113                    // XXX This is a temporary dialog, no need to localize.
1114                    AlertDialog d = new BaseErrorDialog(mContext);
1115                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1116                    d.setCancelable(false);
1117                    d.setTitle(title);
1118                    d.setMessage(text);
1119                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1120                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1121                    mUidAlert = d;
1122                    d.show();
1123                }
1124            } break;
1125            case IM_FEELING_LUCKY_MSG: {
1126                if (mUidAlert != null) {
1127                    mUidAlert.dismiss();
1128                    mUidAlert = null;
1129                }
1130            } break;
1131            case PROC_START_TIMEOUT_MSG: {
1132                if (mDidDexOpt) {
1133                    mDidDexOpt = false;
1134                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1135                    nmsg.obj = msg.obj;
1136                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1137                    return;
1138                }
1139                ProcessRecord app = (ProcessRecord)msg.obj;
1140                synchronized (ActivityManagerService.this) {
1141                    processStartTimedOutLocked(app);
1142                }
1143            } break;
1144            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1145                synchronized (ActivityManagerService.this) {
1146                    doPendingActivityLaunchesLocked(true);
1147                }
1148            } break;
1149            case KILL_APPLICATION_MSG: {
1150                synchronized (ActivityManagerService.this) {
1151                    int appid = msg.arg1;
1152                    boolean restart = (msg.arg2 == 1);
1153                    String pkg = (String) msg.obj;
1154                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1155                            UserHandle.USER_ALL);
1156                }
1157            } break;
1158            case FINALIZE_PENDING_INTENT_MSG: {
1159                ((PendingIntentRecord)msg.obj).completeFinalize();
1160            } break;
1161            case POST_HEAVY_NOTIFICATION_MSG: {
1162                INotificationManager inm = NotificationManager.getService();
1163                if (inm == null) {
1164                    return;
1165                }
1166
1167                ActivityRecord root = (ActivityRecord)msg.obj;
1168                ProcessRecord process = root.app;
1169                if (process == null) {
1170                    return;
1171                }
1172
1173                try {
1174                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1175                    String text = mContext.getString(R.string.heavy_weight_notification,
1176                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1177                    Notification notification = new Notification();
1178                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1179                    notification.when = 0;
1180                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1181                    notification.tickerText = text;
1182                    notification.defaults = 0; // please be quiet
1183                    notification.sound = null;
1184                    notification.vibrate = null;
1185                    notification.setLatestEventInfo(context, text,
1186                            mContext.getText(R.string.heavy_weight_notification_detail),
1187                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1188                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1189                                    new UserHandle(root.userId)));
1190
1191                    try {
1192                        int[] outId = new int[1];
1193                        inm.enqueueNotificationWithTag("android", null,
1194                                R.string.heavy_weight_notification,
1195                                notification, outId, root.userId);
1196                    } catch (RuntimeException e) {
1197                        Slog.w(ActivityManagerService.TAG,
1198                                "Error showing notification for heavy-weight app", e);
1199                    } catch (RemoteException e) {
1200                    }
1201                } catch (NameNotFoundException e) {
1202                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1203                }
1204            } break;
1205            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1206                INotificationManager inm = NotificationManager.getService();
1207                if (inm == null) {
1208                    return;
1209                }
1210                try {
1211                    inm.cancelNotificationWithTag("android", null,
1212                            R.string.heavy_weight_notification,  msg.arg1);
1213                } catch (RuntimeException e) {
1214                    Slog.w(ActivityManagerService.TAG,
1215                            "Error canceling notification for service", e);
1216                } catch (RemoteException e) {
1217                }
1218            } break;
1219            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1220                synchronized (ActivityManagerService.this) {
1221                    checkExcessivePowerUsageLocked(true);
1222                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1223                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1224                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1225                }
1226            } break;
1227            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1228                synchronized (ActivityManagerService.this) {
1229                    ActivityRecord ar = (ActivityRecord)msg.obj;
1230                    if (mCompatModeDialog != null) {
1231                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1232                                ar.info.applicationInfo.packageName)) {
1233                            return;
1234                        }
1235                        mCompatModeDialog.dismiss();
1236                        mCompatModeDialog = null;
1237                    }
1238                    if (ar != null && false) {
1239                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1240                                ar.packageName)) {
1241                            int mode = mCompatModePackages.computeCompatModeLocked(
1242                                    ar.info.applicationInfo);
1243                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1244                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1245                                mCompatModeDialog = new CompatModeDialog(
1246                                        ActivityManagerService.this, mContext,
1247                                        ar.info.applicationInfo);
1248                                mCompatModeDialog.show();
1249                            }
1250                        }
1251                    }
1252                }
1253                break;
1254            }
1255            case DISPATCH_PROCESSES_CHANGED: {
1256                dispatchProcessesChanged();
1257                break;
1258            }
1259            case DISPATCH_PROCESS_DIED: {
1260                final int pid = msg.arg1;
1261                final int uid = msg.arg2;
1262                dispatchProcessDied(pid, uid);
1263                break;
1264            }
1265            case REPORT_MEM_USAGE: {
1266                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1267                if (!isDebuggable) {
1268                    return;
1269                }
1270                synchronized (ActivityManagerService.this) {
1271                    long now = SystemClock.uptimeMillis();
1272                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1273                        // Don't report more than every 5 minutes to somewhat
1274                        // avoid spamming.
1275                        return;
1276                    }
1277                    mLastMemUsageReportTime = now;
1278                }
1279                Thread thread = new Thread() {
1280                    @Override public void run() {
1281                        StringBuilder dropBuilder = new StringBuilder(1024);
1282                        StringBuilder logBuilder = new StringBuilder(1024);
1283                        StringWriter oomSw = new StringWriter();
1284                        PrintWriter oomPw = new PrintWriter(oomSw);
1285                        StringWriter catSw = new StringWriter();
1286                        PrintWriter catPw = new PrintWriter(catSw);
1287                        String[] emptyArgs = new String[] { };
1288                        StringBuilder tag = new StringBuilder(128);
1289                        StringBuilder stack = new StringBuilder(128);
1290                        tag.append("Low on memory -- ");
1291                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1292                                tag, stack);
1293                        dropBuilder.append(stack);
1294                        dropBuilder.append('\n');
1295                        dropBuilder.append('\n');
1296                        String oomString = oomSw.toString();
1297                        dropBuilder.append(oomString);
1298                        dropBuilder.append('\n');
1299                        logBuilder.append(oomString);
1300                        try {
1301                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1302                                    "procrank", });
1303                            final InputStreamReader converter = new InputStreamReader(
1304                                    proc.getInputStream());
1305                            BufferedReader in = new BufferedReader(converter);
1306                            String line;
1307                            while (true) {
1308                                line = in.readLine();
1309                                if (line == null) {
1310                                    break;
1311                                }
1312                                if (line.length() > 0) {
1313                                    logBuilder.append(line);
1314                                    logBuilder.append('\n');
1315                                }
1316                                dropBuilder.append(line);
1317                                dropBuilder.append('\n');
1318                            }
1319                            converter.close();
1320                        } catch (IOException e) {
1321                        }
1322                        synchronized (ActivityManagerService.this) {
1323                            catPw.println();
1324                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1325                            catPw.println();
1326                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1327                                    false, false, null);
1328                            catPw.println();
1329                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1330                        }
1331                        dropBuilder.append(catSw.toString());
1332                        addErrorToDropBox("lowmem", null, "system_server", null,
1333                                null, tag.toString(), dropBuilder.toString(), null, null);
1334                        Slog.i(TAG, logBuilder.toString());
1335                        synchronized (ActivityManagerService.this) {
1336                            long now = SystemClock.uptimeMillis();
1337                            if (mLastMemUsageReportTime < now) {
1338                                mLastMemUsageReportTime = now;
1339                            }
1340                        }
1341                    }
1342                };
1343                thread.start();
1344                break;
1345            }
1346            case REPORT_USER_SWITCH_MSG: {
1347                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1348                break;
1349            }
1350            case CONTINUE_USER_SWITCH_MSG: {
1351                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1352                break;
1353            }
1354            case USER_SWITCH_TIMEOUT_MSG: {
1355                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1356                break;
1357            }
1358            }
1359        }
1360    };
1361
1362    public static void setSystemProcess() {
1363        try {
1364            ActivityManagerService m = mSelf;
1365
1366            ServiceManager.addService("activity", m, true);
1367            ServiceManager.addService("meminfo", new MemBinder(m));
1368            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1369            ServiceManager.addService("dbinfo", new DbBinder(m));
1370            if (MONITOR_CPU_USAGE) {
1371                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1372            }
1373            ServiceManager.addService("permission", new PermissionController(m));
1374
1375            ApplicationInfo info =
1376                mSelf.mContext.getPackageManager().getApplicationInfo(
1377                            "android", STOCK_PM_FLAGS);
1378            mSystemThread.installSystemApplicationInfo(info);
1379
1380            synchronized (mSelf) {
1381                ProcessRecord app = mSelf.newProcessRecordLocked(
1382                        mSystemThread.getApplicationThread(), info,
1383                        info.processName, false);
1384                app.persistent = true;
1385                app.pid = MY_PID;
1386                app.maxAdj = ProcessList.SYSTEM_ADJ;
1387                mSelf.mProcessNames.put(app.processName, app.uid, app);
1388                synchronized (mSelf.mPidsSelfLocked) {
1389                    mSelf.mPidsSelfLocked.put(app.pid, app);
1390                }
1391                mSelf.updateLruProcessLocked(app, true);
1392            }
1393        } catch (PackageManager.NameNotFoundException e) {
1394            throw new RuntimeException(
1395                    "Unable to find android system package", e);
1396        }
1397    }
1398
1399    public void setWindowManager(WindowManagerService wm) {
1400        mWindowManager = wm;
1401    }
1402
1403    public static final Context main(int factoryTest) {
1404        AThread thr = new AThread();
1405        thr.start();
1406
1407        synchronized (thr) {
1408            while (thr.mService == null) {
1409                try {
1410                    thr.wait();
1411                } catch (InterruptedException e) {
1412                }
1413            }
1414        }
1415
1416        ActivityManagerService m = thr.mService;
1417        mSelf = m;
1418        ActivityThread at = ActivityThread.systemMain();
1419        mSystemThread = at;
1420        Context context = at.getSystemContext();
1421        context.setTheme(android.R.style.Theme_Holo);
1422        m.mContext = context;
1423        m.mFactoryTest = factoryTest;
1424        m.mMainStack = new ActivityStack(m, context, true);
1425
1426        m.mBatteryStatsService.publish(context);
1427        m.mUsageStatsService.publish(context);
1428
1429        synchronized (thr) {
1430            thr.mReady = true;
1431            thr.notifyAll();
1432        }
1433
1434        m.startRunning(null, null, null, null);
1435
1436        return context;
1437    }
1438
1439    public static ActivityManagerService self() {
1440        return mSelf;
1441    }
1442
1443    static class AThread extends Thread {
1444        ActivityManagerService mService;
1445        boolean mReady = false;
1446
1447        public AThread() {
1448            super("ActivityManager");
1449        }
1450
1451        public void run() {
1452            Looper.prepare();
1453
1454            android.os.Process.setThreadPriority(
1455                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1456            android.os.Process.setCanSelfBackground(false);
1457
1458            ActivityManagerService m = new ActivityManagerService();
1459
1460            synchronized (this) {
1461                mService = m;
1462                notifyAll();
1463            }
1464
1465            synchronized (this) {
1466                while (!mReady) {
1467                    try {
1468                        wait();
1469                    } catch (InterruptedException e) {
1470                    }
1471                }
1472            }
1473
1474            // For debug builds, log event loop stalls to dropbox for analysis.
1475            if (StrictMode.conditionallyEnableDebugLogging()) {
1476                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1477            }
1478
1479            Looper.loop();
1480        }
1481    }
1482
1483    static class MemBinder extends Binder {
1484        ActivityManagerService mActivityManagerService;
1485        MemBinder(ActivityManagerService activityManagerService) {
1486            mActivityManagerService = activityManagerService;
1487        }
1488
1489        @Override
1490        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1491            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1492                    != PackageManager.PERMISSION_GRANTED) {
1493                pw.println("Permission Denial: can't dump meminfo from from pid="
1494                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1495                        + " without permission " + android.Manifest.permission.DUMP);
1496                return;
1497            }
1498
1499            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1500                    false, null, null, null);
1501        }
1502    }
1503
1504    static class GraphicsBinder extends Binder {
1505        ActivityManagerService mActivityManagerService;
1506        GraphicsBinder(ActivityManagerService activityManagerService) {
1507            mActivityManagerService = activityManagerService;
1508        }
1509
1510        @Override
1511        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1512            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1513                    != PackageManager.PERMISSION_GRANTED) {
1514                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1515                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1516                        + " without permission " + android.Manifest.permission.DUMP);
1517                return;
1518            }
1519
1520            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1521        }
1522    }
1523
1524    static class DbBinder extends Binder {
1525        ActivityManagerService mActivityManagerService;
1526        DbBinder(ActivityManagerService activityManagerService) {
1527            mActivityManagerService = activityManagerService;
1528        }
1529
1530        @Override
1531        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1532            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1533                    != PackageManager.PERMISSION_GRANTED) {
1534                pw.println("Permission Denial: can't dump dbinfo from from pid="
1535                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1536                        + " without permission " + android.Manifest.permission.DUMP);
1537                return;
1538            }
1539
1540            mActivityManagerService.dumpDbInfo(fd, pw, args);
1541        }
1542    }
1543
1544    static class CpuBinder extends Binder {
1545        ActivityManagerService mActivityManagerService;
1546        CpuBinder(ActivityManagerService activityManagerService) {
1547            mActivityManagerService = activityManagerService;
1548        }
1549
1550        @Override
1551        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1552            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1553                    != PackageManager.PERMISSION_GRANTED) {
1554                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1555                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1556                        + " without permission " + android.Manifest.permission.DUMP);
1557                return;
1558            }
1559
1560            synchronized (mActivityManagerService.mProcessStatsThread) {
1561                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1562                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1563                        SystemClock.uptimeMillis()));
1564            }
1565        }
1566    }
1567
1568    private ActivityManagerService() {
1569        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1570
1571        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1572        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1573        mBroadcastQueues[0] = mFgBroadcastQueue;
1574        mBroadcastQueues[1] = mBgBroadcastQueue;
1575
1576        mServices = new ActiveServices(this);
1577        mProviderMap = new ProviderMap(this);
1578
1579        File dataDir = Environment.getDataDirectory();
1580        File systemDir = new File(dataDir, "system");
1581        systemDir.mkdirs();
1582        mBatteryStatsService = new BatteryStatsService(new File(
1583                systemDir, "batterystats.bin").toString());
1584        mBatteryStatsService.getActiveStatistics().readLocked();
1585        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1586        mOnBattery = DEBUG_POWER ? true
1587                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1588        mBatteryStatsService.getActiveStatistics().setCallback(this);
1589
1590        mUsageStatsService = new UsageStatsService(new File(
1591                systemDir, "usagestats").toString());
1592        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1593
1594        // User 0 is the first and only user that runs at boot.
1595        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1596        mUserLru.add(Integer.valueOf(0));
1597        updateStartedUserArrayLocked();
1598
1599        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1600            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1601
1602        mConfiguration.setToDefaults();
1603        mConfiguration.setLocale(Locale.getDefault());
1604
1605        mConfigurationSeq = mConfiguration.seq = 1;
1606        mProcessStats.init();
1607
1608        mCompatModePackages = new CompatModePackages(this, systemDir);
1609
1610        // Add ourself to the Watchdog monitors.
1611        Watchdog.getInstance().addMonitor(this);
1612
1613        mProcessStatsThread = new Thread("ProcessStats") {
1614            public void run() {
1615                while (true) {
1616                    try {
1617                        try {
1618                            synchronized(this) {
1619                                final long now = SystemClock.uptimeMillis();
1620                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1621                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1622                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1623                                //        + ", write delay=" + nextWriteDelay);
1624                                if (nextWriteDelay < nextCpuDelay) {
1625                                    nextCpuDelay = nextWriteDelay;
1626                                }
1627                                if (nextCpuDelay > 0) {
1628                                    mProcessStatsMutexFree.set(true);
1629                                    this.wait(nextCpuDelay);
1630                                }
1631                            }
1632                        } catch (InterruptedException e) {
1633                        }
1634                        updateCpuStatsNow();
1635                    } catch (Exception e) {
1636                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1637                    }
1638                }
1639            }
1640        };
1641        mProcessStatsThread.start();
1642    }
1643
1644    @Override
1645    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1646            throws RemoteException {
1647        if (code == SYSPROPS_TRANSACTION) {
1648            // We need to tell all apps about the system property change.
1649            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1650            synchronized(this) {
1651                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1652                    final int NA = apps.size();
1653                    for (int ia=0; ia<NA; ia++) {
1654                        ProcessRecord app = apps.valueAt(ia);
1655                        if (app.thread != null) {
1656                            procs.add(app.thread.asBinder());
1657                        }
1658                    }
1659                }
1660            }
1661
1662            int N = procs.size();
1663            for (int i=0; i<N; i++) {
1664                Parcel data2 = Parcel.obtain();
1665                try {
1666                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1667                } catch (RemoteException e) {
1668                }
1669                data2.recycle();
1670            }
1671        }
1672        try {
1673            return super.onTransact(code, data, reply, flags);
1674        } catch (RuntimeException e) {
1675            // The activity manager only throws security exceptions, so let's
1676            // log all others.
1677            if (!(e instanceof SecurityException)) {
1678                Slog.e(TAG, "Activity Manager Crash", e);
1679            }
1680            throw e;
1681        }
1682    }
1683
1684    void updateCpuStats() {
1685        final long now = SystemClock.uptimeMillis();
1686        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1687            return;
1688        }
1689        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1690            synchronized (mProcessStatsThread) {
1691                mProcessStatsThread.notify();
1692            }
1693        }
1694    }
1695
1696    void updateCpuStatsNow() {
1697        synchronized (mProcessStatsThread) {
1698            mProcessStatsMutexFree.set(false);
1699            final long now = SystemClock.uptimeMillis();
1700            boolean haveNewCpuStats = false;
1701
1702            if (MONITOR_CPU_USAGE &&
1703                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1704                mLastCpuTime.set(now);
1705                haveNewCpuStats = true;
1706                mProcessStats.update();
1707                //Slog.i(TAG, mProcessStats.printCurrentState());
1708                //Slog.i(TAG, "Total CPU usage: "
1709                //        + mProcessStats.getTotalCpuPercent() + "%");
1710
1711                // Slog the cpu usage if the property is set.
1712                if ("true".equals(SystemProperties.get("events.cpu"))) {
1713                    int user = mProcessStats.getLastUserTime();
1714                    int system = mProcessStats.getLastSystemTime();
1715                    int iowait = mProcessStats.getLastIoWaitTime();
1716                    int irq = mProcessStats.getLastIrqTime();
1717                    int softIrq = mProcessStats.getLastSoftIrqTime();
1718                    int idle = mProcessStats.getLastIdleTime();
1719
1720                    int total = user + system + iowait + irq + softIrq + idle;
1721                    if (total == 0) total = 1;
1722
1723                    EventLog.writeEvent(EventLogTags.CPU,
1724                            ((user+system+iowait+irq+softIrq) * 100) / total,
1725                            (user * 100) / total,
1726                            (system * 100) / total,
1727                            (iowait * 100) / total,
1728                            (irq * 100) / total,
1729                            (softIrq * 100) / total);
1730                }
1731            }
1732
1733            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1734            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1735            synchronized(bstats) {
1736                synchronized(mPidsSelfLocked) {
1737                    if (haveNewCpuStats) {
1738                        if (mOnBattery) {
1739                            int perc = bstats.startAddingCpuLocked();
1740                            int totalUTime = 0;
1741                            int totalSTime = 0;
1742                            final int N = mProcessStats.countStats();
1743                            for (int i=0; i<N; i++) {
1744                                ProcessStats.Stats st = mProcessStats.getStats(i);
1745                                if (!st.working) {
1746                                    continue;
1747                                }
1748                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1749                                int otherUTime = (st.rel_utime*perc)/100;
1750                                int otherSTime = (st.rel_stime*perc)/100;
1751                                totalUTime += otherUTime;
1752                                totalSTime += otherSTime;
1753                                if (pr != null) {
1754                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1755                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1756                                            st.rel_stime-otherSTime);
1757                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1758                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1759                                } else {
1760                                    BatteryStatsImpl.Uid.Proc ps =
1761                                            bstats.getProcessStatsLocked(st.name, st.pid);
1762                                    if (ps != null) {
1763                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1764                                                st.rel_stime-otherSTime);
1765                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1766                                    }
1767                                }
1768                            }
1769                            bstats.finishAddingCpuLocked(perc, totalUTime,
1770                                    totalSTime, cpuSpeedTimes);
1771                        }
1772                    }
1773                }
1774
1775                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1776                    mLastWriteTime = now;
1777                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1778                }
1779            }
1780        }
1781    }
1782
1783    @Override
1784    public void batteryNeedsCpuUpdate() {
1785        updateCpuStatsNow();
1786    }
1787
1788    @Override
1789    public void batteryPowerChanged(boolean onBattery) {
1790        // When plugging in, update the CPU stats first before changing
1791        // the plug state.
1792        updateCpuStatsNow();
1793        synchronized (this) {
1794            synchronized(mPidsSelfLocked) {
1795                mOnBattery = DEBUG_POWER ? true : onBattery;
1796            }
1797        }
1798    }
1799
1800    /**
1801     * Initialize the application bind args. These are passed to each
1802     * process when the bindApplication() IPC is sent to the process. They're
1803     * lazily setup to make sure the services are running when they're asked for.
1804     */
1805    private HashMap<String, IBinder> getCommonServicesLocked() {
1806        if (mAppBindArgs == null) {
1807            mAppBindArgs = new HashMap<String, IBinder>();
1808
1809            // Setup the application init args
1810            mAppBindArgs.put("package", ServiceManager.getService("package"));
1811            mAppBindArgs.put("window", ServiceManager.getService("window"));
1812            mAppBindArgs.put(Context.ALARM_SERVICE,
1813                    ServiceManager.getService(Context.ALARM_SERVICE));
1814        }
1815        return mAppBindArgs;
1816    }
1817
1818    final void setFocusedActivityLocked(ActivityRecord r) {
1819        if (mFocusedActivity != r) {
1820            mFocusedActivity = r;
1821            if (r != null) {
1822                mWindowManager.setFocusedApp(r.appToken, true);
1823            }
1824        }
1825    }
1826
1827    private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1828        // put it on the LRU to keep track of when it should be exited.
1829        int lrui = mLruProcesses.indexOf(app);
1830        if (lrui >= 0) mLruProcesses.remove(lrui);
1831
1832        int i = mLruProcesses.size()-1;
1833        int skipTop = 0;
1834
1835        app.lruSeq = mLruSeq;
1836
1837        // compute the new weight for this process.
1838        app.lastActivityTime = SystemClock.uptimeMillis();
1839        if (app.activities.size() > 0) {
1840            // If this process has activities, we more strongly want to keep
1841            // it around.
1842            app.lruWeight = app.lastActivityTime;
1843        } else if (app.pubProviders.size() > 0) {
1844            // If this process contains content providers, we want to keep
1845            // it a little more strongly.
1846            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1847            // Also don't let it kick out the first few "real" hidden processes.
1848            skipTop = ProcessList.MIN_HIDDEN_APPS;
1849        } else {
1850            // If this process doesn't have activities, we less strongly
1851            // want to keep it around, and generally want to avoid getting
1852            // in front of any very recently used activities.
1853            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1854            // Also don't let it kick out the first few "real" hidden processes.
1855            skipTop = ProcessList.MIN_HIDDEN_APPS;
1856        }
1857
1858        while (i >= 0) {
1859            ProcessRecord p = mLruProcesses.get(i);
1860            // If this app shouldn't be in front of the first N background
1861            // apps, then skip over that many that are currently hidden.
1862            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1863                skipTop--;
1864            }
1865            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1866                mLruProcesses.add(i+1, app);
1867                break;
1868            }
1869            i--;
1870        }
1871        if (i < 0) {
1872            mLruProcesses.add(0, app);
1873        }
1874
1875        // If the app is currently using a content provider or service,
1876        // bump those processes as well.
1877        if (app.connections.size() > 0) {
1878            for (ConnectionRecord cr : app.connections) {
1879                if (cr.binding != null && cr.binding.service != null
1880                        && cr.binding.service.app != null
1881                        && cr.binding.service.app.lruSeq != mLruSeq) {
1882                    updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1883                }
1884            }
1885        }
1886        for (int j=app.conProviders.size()-1; j>=0; j--) {
1887            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1888            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1889                updateLruProcessInternalLocked(cpr.proc, i+1);
1890            }
1891        }
1892    }
1893
1894    final void updateLruProcessLocked(ProcessRecord app,
1895            boolean oomAdj) {
1896        mLruSeq++;
1897        updateLruProcessInternalLocked(app, 0);
1898
1899        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1900        if (oomAdj) {
1901            updateOomAdjLocked();
1902        }
1903    }
1904
1905    final ProcessRecord getProcessRecordLocked(
1906            String processName, int uid) {
1907        if (uid == Process.SYSTEM_UID) {
1908            // The system gets to run in any process.  If there are multiple
1909            // processes with the same uid, just pick the first (this
1910            // should never happen).
1911            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1912                    processName);
1913            if (procs == null) return null;
1914            final int N = procs.size();
1915            for (int i = 0; i < N; i++) {
1916                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1917            }
1918        }
1919        ProcessRecord proc = mProcessNames.get(processName, uid);
1920        return proc;
1921    }
1922
1923    void ensurePackageDexOpt(String packageName) {
1924        IPackageManager pm = AppGlobals.getPackageManager();
1925        try {
1926            if (pm.performDexOpt(packageName)) {
1927                mDidDexOpt = true;
1928            }
1929        } catch (RemoteException e) {
1930        }
1931    }
1932
1933    boolean isNextTransitionForward() {
1934        int transit = mWindowManager.getPendingAppTransition();
1935        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1936                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1937                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1938    }
1939
1940    final ProcessRecord startProcessLocked(String processName,
1941            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1942            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1943            boolean isolated) {
1944        ProcessRecord app;
1945        if (!isolated) {
1946            app = getProcessRecordLocked(processName, info.uid);
1947        } else {
1948            // If this is an isolated process, it can't re-use an existing process.
1949            app = null;
1950        }
1951        // We don't have to do anything more if:
1952        // (1) There is an existing application record; and
1953        // (2) The caller doesn't think it is dead, OR there is no thread
1954        //     object attached to it so we know it couldn't have crashed; and
1955        // (3) There is a pid assigned to it, so it is either starting or
1956        //     already running.
1957        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1958                + " app=" + app + " knownToBeDead=" + knownToBeDead
1959                + " thread=" + (app != null ? app.thread : null)
1960                + " pid=" + (app != null ? app.pid : -1));
1961        if (app != null && app.pid > 0) {
1962            if (!knownToBeDead || app.thread == null) {
1963                // We already have the app running, or are waiting for it to
1964                // come up (we have a pid but not yet its thread), so keep it.
1965                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1966                // If this is a new package in the process, add the package to the list
1967                app.addPackage(info.packageName);
1968                return app;
1969            } else {
1970                // An application record is attached to a previous process,
1971                // clean it up now.
1972                if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
1973                handleAppDiedLocked(app, true, true);
1974            }
1975        }
1976
1977        String hostingNameStr = hostingName != null
1978                ? hostingName.flattenToShortString() : null;
1979
1980        if (!isolated) {
1981            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1982                // If we are in the background, then check to see if this process
1983                // is bad.  If so, we will just silently fail.
1984                if (mBadProcesses.get(info.processName, info.uid) != null) {
1985                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1986                            + "/" + info.processName);
1987                    return null;
1988                }
1989            } else {
1990                // When the user is explicitly starting a process, then clear its
1991                // crash count so that we won't make it bad until they see at
1992                // least one crash dialog again, and make the process good again
1993                // if it had been bad.
1994                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1995                        + "/" + info.processName);
1996                mProcessCrashTimes.remove(info.processName, info.uid);
1997                if (mBadProcesses.get(info.processName, info.uid) != null) {
1998                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
1999                            UserHandle.getUserId(info.uid), info.uid,
2000                            info.processName);
2001                    mBadProcesses.remove(info.processName, info.uid);
2002                    if (app != null) {
2003                        app.bad = false;
2004                    }
2005                }
2006            }
2007        }
2008
2009        if (app == null) {
2010            app = newProcessRecordLocked(null, info, processName, isolated);
2011            if (app == null) {
2012                Slog.w(TAG, "Failed making new process record for "
2013                        + processName + "/" + info.uid + " isolated=" + isolated);
2014                return null;
2015            }
2016            mProcessNames.put(processName, app.uid, app);
2017            if (isolated) {
2018                mIsolatedProcesses.put(app.uid, app);
2019            }
2020        } else {
2021            // If this is a new package in the process, add the package to the list
2022            app.addPackage(info.packageName);
2023        }
2024
2025        // If the system is not ready yet, then hold off on starting this
2026        // process until it is.
2027        if (!mProcessesReady
2028                && !isAllowedWhileBooting(info)
2029                && !allowWhileBooting) {
2030            if (!mProcessesOnHold.contains(app)) {
2031                mProcessesOnHold.add(app);
2032            }
2033            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2034            return app;
2035        }
2036
2037        startProcessLocked(app, hostingType, hostingNameStr);
2038        return (app.pid != 0) ? app : null;
2039    }
2040
2041    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2042        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2043    }
2044
2045    private final void startProcessLocked(ProcessRecord app,
2046            String hostingType, String hostingNameStr) {
2047        if (app.pid > 0 && app.pid != MY_PID) {
2048            synchronized (mPidsSelfLocked) {
2049                mPidsSelfLocked.remove(app.pid);
2050                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2051            }
2052            app.setPid(0);
2053        }
2054
2055        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2056                "startProcessLocked removing on hold: " + app);
2057        mProcessesOnHold.remove(app);
2058
2059        updateCpuStats();
2060
2061        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2062        mProcDeaths[0] = 0;
2063
2064        try {
2065            int uid = app.uid;
2066
2067            int[] gids = null;
2068            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2069            if (!app.isolated) {
2070                int[] permGids = null;
2071                try {
2072                    final PackageManager pm = mContext.getPackageManager();
2073                    permGids = pm.getPackageGids(app.info.packageName);
2074
2075                    if (Environment.isExternalStorageEmulated()) {
2076                        if (pm.checkPermission(
2077                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2078                                app.info.packageName) == PERMISSION_GRANTED) {
2079                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2080                        } else {
2081                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2082                        }
2083                    }
2084                } catch (PackageManager.NameNotFoundException e) {
2085                    Slog.w(TAG, "Unable to retrieve gids", e);
2086                }
2087
2088                /*
2089                 * Add shared application GID so applications can share some
2090                 * resources like shared libraries
2091                 */
2092                if (permGids == null) {
2093                    gids = new int[1];
2094                } else {
2095                    gids = new int[permGids.length + 1];
2096                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2097                }
2098                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2099            }
2100            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2101                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2102                        && mTopComponent != null
2103                        && app.processName.equals(mTopComponent.getPackageName())) {
2104                    uid = 0;
2105                }
2106                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2107                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2108                    uid = 0;
2109                }
2110            }
2111            int debugFlags = 0;
2112            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2113                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2114                // Also turn on CheckJNI for debuggable apps. It's quite
2115                // awkward to turn on otherwise.
2116                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2117            }
2118            // Run the app in safe mode if its manifest requests so or the
2119            // system is booted in safe mode.
2120            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2121                Zygote.systemInSafeMode == true) {
2122                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2123            }
2124            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2125                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2126            }
2127            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2128                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2129            }
2130            if ("1".equals(SystemProperties.get("debug.assert"))) {
2131                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2132            }
2133
2134            // Start the process.  It will either succeed and return a result containing
2135            // the PID of the new process, or else throw a RuntimeException.
2136            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2137                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2138                    app.info.targetSdkVersion, null, null);
2139
2140            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2141            synchronized (bs) {
2142                if (bs.isOnBattery()) {
2143                    app.batteryStats.incStartsLocked();
2144                }
2145            }
2146
2147            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2148                    UserHandle.getUserId(uid), startResult.pid, uid,
2149                    app.processName, hostingType,
2150                    hostingNameStr != null ? hostingNameStr : "");
2151
2152            if (app.persistent) {
2153                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2154            }
2155
2156            StringBuilder buf = mStringBuilder;
2157            buf.setLength(0);
2158            buf.append("Start proc ");
2159            buf.append(app.processName);
2160            buf.append(" for ");
2161            buf.append(hostingType);
2162            if (hostingNameStr != null) {
2163                buf.append(" ");
2164                buf.append(hostingNameStr);
2165            }
2166            buf.append(": pid=");
2167            buf.append(startResult.pid);
2168            buf.append(" uid=");
2169            buf.append(uid);
2170            buf.append(" gids={");
2171            if (gids != null) {
2172                for (int gi=0; gi<gids.length; gi++) {
2173                    if (gi != 0) buf.append(", ");
2174                    buf.append(gids[gi]);
2175
2176                }
2177            }
2178            buf.append("}");
2179            Slog.i(TAG, buf.toString());
2180            app.setPid(startResult.pid);
2181            app.usingWrapper = startResult.usingWrapper;
2182            app.removed = false;
2183            synchronized (mPidsSelfLocked) {
2184                this.mPidsSelfLocked.put(startResult.pid, app);
2185                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2186                msg.obj = app;
2187                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2188                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2189            }
2190        } catch (RuntimeException e) {
2191            // XXX do better error recovery.
2192            app.setPid(0);
2193            Slog.e(TAG, "Failure starting process " + app.processName, e);
2194        }
2195    }
2196
2197    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2198        if (resumed) {
2199            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2200        } else {
2201            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2202        }
2203    }
2204
2205    boolean startHomeActivityLocked(int userId) {
2206        if (mHeadless) {
2207            // Added because none of the other calls to ensureBootCompleted seem to fire
2208            // when running headless.
2209            ensureBootCompleted();
2210            return false;
2211        }
2212
2213        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2214                && mTopAction == null) {
2215            // We are running in factory test mode, but unable to find
2216            // the factory test app, so just sit around displaying the
2217            // error message and don't try to start anything.
2218            return false;
2219        }
2220        Intent intent = new Intent(
2221            mTopAction,
2222            mTopData != null ? Uri.parse(mTopData) : null);
2223        intent.setComponent(mTopComponent);
2224        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2225            intent.addCategory(Intent.CATEGORY_HOME);
2226        }
2227        ActivityInfo aInfo =
2228            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2229        if (aInfo != null) {
2230            intent.setComponent(new ComponentName(
2231                    aInfo.applicationInfo.packageName, aInfo.name));
2232            // Don't do this if the home app is currently being
2233            // instrumented.
2234            aInfo = new ActivityInfo(aInfo);
2235            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2236            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2237                    aInfo.applicationInfo.uid);
2238            if (app == null || app.instrumentationClass == null) {
2239                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2240                mMainStack.startActivityLocked(null, intent, null, aInfo,
2241                        null, null, 0, 0, 0, 0, null, false, null);
2242            }
2243        }
2244
2245        return true;
2246    }
2247
2248    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2249        ActivityInfo ai = null;
2250        ComponentName comp = intent.getComponent();
2251        try {
2252            if (comp != null) {
2253                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2254            } else {
2255                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2256                        intent,
2257                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2258                            flags, userId);
2259
2260                if (info != null) {
2261                    ai = info.activityInfo;
2262                }
2263            }
2264        } catch (RemoteException e) {
2265            // ignore
2266        }
2267
2268        return ai;
2269    }
2270
2271    /**
2272     * Starts the "new version setup screen" if appropriate.
2273     */
2274    void startSetupActivityLocked() {
2275        // Only do this once per boot.
2276        if (mCheckedForSetup) {
2277            return;
2278        }
2279
2280        // We will show this screen if the current one is a different
2281        // version than the last one shown, and we are not running in
2282        // low-level factory test mode.
2283        final ContentResolver resolver = mContext.getContentResolver();
2284        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2285                Settings.Global.getInt(resolver,
2286                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2287            mCheckedForSetup = true;
2288
2289            // See if we should be showing the platform update setup UI.
2290            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2291            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2292                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2293
2294            // We don't allow third party apps to replace this.
2295            ResolveInfo ri = null;
2296            for (int i=0; ris != null && i<ris.size(); i++) {
2297                if ((ris.get(i).activityInfo.applicationInfo.flags
2298                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2299                    ri = ris.get(i);
2300                    break;
2301                }
2302            }
2303
2304            if (ri != null) {
2305                String vers = ri.activityInfo.metaData != null
2306                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2307                        : null;
2308                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2309                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2310                            Intent.METADATA_SETUP_VERSION);
2311                }
2312                String lastVers = Settings.Secure.getString(
2313                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2314                if (vers != null && !vers.equals(lastVers)) {
2315                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2316                    intent.setComponent(new ComponentName(
2317                            ri.activityInfo.packageName, ri.activityInfo.name));
2318                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2319                            null, null, 0, 0, 0, 0, null, false, null);
2320                }
2321            }
2322        }
2323    }
2324
2325    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2326        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2327    }
2328
2329    void enforceNotIsolatedCaller(String caller) {
2330        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2331            throw new SecurityException("Isolated process not allowed to call " + caller);
2332        }
2333    }
2334
2335    public int getFrontActivityScreenCompatMode() {
2336        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2337        synchronized (this) {
2338            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2339        }
2340    }
2341
2342    public void setFrontActivityScreenCompatMode(int mode) {
2343        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2344                "setFrontActivityScreenCompatMode");
2345        synchronized (this) {
2346            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2347        }
2348    }
2349
2350    public int getPackageScreenCompatMode(String packageName) {
2351        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2352        synchronized (this) {
2353            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2354        }
2355    }
2356
2357    public void setPackageScreenCompatMode(String packageName, int mode) {
2358        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2359                "setPackageScreenCompatMode");
2360        synchronized (this) {
2361            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2362        }
2363    }
2364
2365    public boolean getPackageAskScreenCompat(String packageName) {
2366        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2367        synchronized (this) {
2368            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2369        }
2370    }
2371
2372    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2373        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2374                "setPackageAskScreenCompat");
2375        synchronized (this) {
2376            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2377        }
2378    }
2379
2380    void reportResumedActivityLocked(ActivityRecord r) {
2381        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2382        updateUsageStats(r, true);
2383    }
2384
2385    private void dispatchProcessesChanged() {
2386        int N;
2387        synchronized (this) {
2388            N = mPendingProcessChanges.size();
2389            if (mActiveProcessChanges.length < N) {
2390                mActiveProcessChanges = new ProcessChangeItem[N];
2391            }
2392            mPendingProcessChanges.toArray(mActiveProcessChanges);
2393            mAvailProcessChanges.addAll(mPendingProcessChanges);
2394            mPendingProcessChanges.clear();
2395            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2396        }
2397        int i = mProcessObservers.beginBroadcast();
2398        while (i > 0) {
2399            i--;
2400            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2401            if (observer != null) {
2402                try {
2403                    for (int j=0; j<N; j++) {
2404                        ProcessChangeItem item = mActiveProcessChanges[j];
2405                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2406                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2407                                    + item.pid + " uid=" + item.uid + ": "
2408                                    + item.foregroundActivities);
2409                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2410                                    item.foregroundActivities);
2411                        }
2412                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2413                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2414                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2415                            observer.onImportanceChanged(item.pid, item.uid,
2416                                    item.importance);
2417                        }
2418                    }
2419                } catch (RemoteException e) {
2420                }
2421            }
2422        }
2423        mProcessObservers.finishBroadcast();
2424    }
2425
2426    private void dispatchProcessDied(int pid, int uid) {
2427        int i = mProcessObservers.beginBroadcast();
2428        while (i > 0) {
2429            i--;
2430            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2431            if (observer != null) {
2432                try {
2433                    observer.onProcessDied(pid, uid);
2434                } catch (RemoteException e) {
2435                }
2436            }
2437        }
2438        mProcessObservers.finishBroadcast();
2439    }
2440
2441    final void doPendingActivityLaunchesLocked(boolean doResume) {
2442        final int N = mPendingActivityLaunches.size();
2443        if (N <= 0) {
2444            return;
2445        }
2446        for (int i=0; i<N; i++) {
2447            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2448            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2449                    pal.startFlags, doResume && i == (N-1), null);
2450        }
2451        mPendingActivityLaunches.clear();
2452    }
2453
2454    public final int startActivity(IApplicationThread caller,
2455            Intent intent, String resolvedType, IBinder resultTo,
2456            String resultWho, int requestCode, int startFlags,
2457            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2458        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2459                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2460    }
2461
2462    public final int startActivityAsUser(IApplicationThread caller,
2463            Intent intent, String resolvedType, IBinder resultTo,
2464            String resultWho, int requestCode, int startFlags,
2465            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2466        enforceNotIsolatedCaller("startActivity");
2467        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2468                false, true, "startActivity", null);
2469        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2470                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2471                null, null, options, userId);
2472    }
2473
2474    public final WaitResult startActivityAndWait(IApplicationThread caller,
2475            Intent intent, String resolvedType, IBinder resultTo,
2476            String resultWho, int requestCode, int startFlags, String profileFile,
2477            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2478        enforceNotIsolatedCaller("startActivityAndWait");
2479        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2480                false, true, "startActivityAndWait", null);
2481        WaitResult res = new WaitResult();
2482        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2483                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2484                res, null, options, UserHandle.getCallingUserId());
2485        return res;
2486    }
2487
2488    public final int startActivityWithConfig(IApplicationThread caller,
2489            Intent intent, String resolvedType, IBinder resultTo,
2490            String resultWho, int requestCode, int startFlags, Configuration config,
2491            Bundle options, int userId) {
2492        enforceNotIsolatedCaller("startActivityWithConfig");
2493        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2494                false, true, "startActivityWithConfig", null);
2495        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2496                resultTo, resultWho, requestCode, startFlags,
2497                null, null, null, config, options, userId);
2498        return ret;
2499    }
2500
2501    public int startActivityIntentSender(IApplicationThread caller,
2502            IntentSender intent, Intent fillInIntent, String resolvedType,
2503            IBinder resultTo, String resultWho, int requestCode,
2504            int flagsMask, int flagsValues, Bundle options) {
2505        enforceNotIsolatedCaller("startActivityIntentSender");
2506        // Refuse possible leaked file descriptors
2507        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2508            throw new IllegalArgumentException("File descriptors passed in Intent");
2509        }
2510
2511        IIntentSender sender = intent.getTarget();
2512        if (!(sender instanceof PendingIntentRecord)) {
2513            throw new IllegalArgumentException("Bad PendingIntent object");
2514        }
2515
2516        PendingIntentRecord pir = (PendingIntentRecord)sender;
2517
2518        synchronized (this) {
2519            // If this is coming from the currently resumed activity, it is
2520            // effectively saying that app switches are allowed at this point.
2521            if (mMainStack.mResumedActivity != null
2522                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2523                            Binder.getCallingUid()) {
2524                mAppSwitchesAllowedTime = 0;
2525            }
2526        }
2527        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2528                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2529        return ret;
2530    }
2531
2532    public boolean startNextMatchingActivity(IBinder callingActivity,
2533            Intent intent, Bundle options) {
2534        // Refuse possible leaked file descriptors
2535        if (intent != null && intent.hasFileDescriptors() == true) {
2536            throw new IllegalArgumentException("File descriptors passed in Intent");
2537        }
2538
2539        synchronized (this) {
2540            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2541            if (r == null) {
2542                ActivityOptions.abort(options);
2543                return false;
2544            }
2545            if (r.app == null || r.app.thread == null) {
2546                // The caller is not running...  d'oh!
2547                ActivityOptions.abort(options);
2548                return false;
2549            }
2550            intent = new Intent(intent);
2551            // The caller is not allowed to change the data.
2552            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2553            // And we are resetting to find the next component...
2554            intent.setComponent(null);
2555
2556            ActivityInfo aInfo = null;
2557            try {
2558                List<ResolveInfo> resolves =
2559                    AppGlobals.getPackageManager().queryIntentActivities(
2560                            intent, r.resolvedType,
2561                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2562                            UserHandle.getCallingUserId());
2563
2564                // Look for the original activity in the list...
2565                final int N = resolves != null ? resolves.size() : 0;
2566                for (int i=0; i<N; i++) {
2567                    ResolveInfo rInfo = resolves.get(i);
2568                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2569                            && rInfo.activityInfo.name.equals(r.info.name)) {
2570                        // We found the current one...  the next matching is
2571                        // after it.
2572                        i++;
2573                        if (i<N) {
2574                            aInfo = resolves.get(i).activityInfo;
2575                        }
2576                        break;
2577                    }
2578                }
2579            } catch (RemoteException e) {
2580            }
2581
2582            if (aInfo == null) {
2583                // Nobody who is next!
2584                ActivityOptions.abort(options);
2585                return false;
2586            }
2587
2588            intent.setComponent(new ComponentName(
2589                    aInfo.applicationInfo.packageName, aInfo.name));
2590            intent.setFlags(intent.getFlags()&~(
2591                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2592                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2593                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2594                    Intent.FLAG_ACTIVITY_NEW_TASK));
2595
2596            // Okay now we need to start the new activity, replacing the
2597            // currently running activity.  This is a little tricky because
2598            // we want to start the new one as if the current one is finished,
2599            // but not finish the current one first so that there is no flicker.
2600            // And thus...
2601            final boolean wasFinishing = r.finishing;
2602            r.finishing = true;
2603
2604            // Propagate reply information over to the new activity.
2605            final ActivityRecord resultTo = r.resultTo;
2606            final String resultWho = r.resultWho;
2607            final int requestCode = r.requestCode;
2608            r.resultTo = null;
2609            if (resultTo != null) {
2610                resultTo.removeResultsLocked(r, resultWho, requestCode);
2611            }
2612
2613            final long origId = Binder.clearCallingIdentity();
2614            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2615                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2616                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2617                    options, false, null);
2618            Binder.restoreCallingIdentity(origId);
2619
2620            r.finishing = wasFinishing;
2621            if (res != ActivityManager.START_SUCCESS) {
2622                return false;
2623            }
2624            return true;
2625        }
2626    }
2627
2628    final int startActivityInPackage(int uid,
2629            Intent intent, String resolvedType, IBinder resultTo,
2630            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2631
2632        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2633                false, true, "startActivityInPackage", null);
2634
2635        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2636                resultTo, resultWho, requestCode, startFlags,
2637                null, null, null, null, options, userId);
2638        return ret;
2639    }
2640
2641    public final int startActivities(IApplicationThread caller,
2642            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2643            int userId) {
2644        enforceNotIsolatedCaller("startActivities");
2645        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2646                false, true, "startActivity", null);
2647        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2648                options, userId);
2649        return ret;
2650    }
2651
2652    final int startActivitiesInPackage(int uid,
2653            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2654            Bundle options, int userId) {
2655
2656        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2657                false, true, "startActivityInPackage", null);
2658        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2659                options, userId);
2660        return ret;
2661    }
2662
2663    final void addRecentTaskLocked(TaskRecord task) {
2664        int N = mRecentTasks.size();
2665        // Quick case: check if the top-most recent task is the same.
2666        if (N > 0 && mRecentTasks.get(0) == task) {
2667            return;
2668        }
2669        // Remove any existing entries that are the same kind of task.
2670        for (int i=0; i<N; i++) {
2671            TaskRecord tr = mRecentTasks.get(i);
2672            if (task.userId == tr.userId
2673                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2674                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2675                mRecentTasks.remove(i);
2676                i--;
2677                N--;
2678                if (task.intent == null) {
2679                    // If the new recent task we are adding is not fully
2680                    // specified, then replace it with the existing recent task.
2681                    task = tr;
2682                }
2683            }
2684        }
2685        if (N >= MAX_RECENT_TASKS) {
2686            mRecentTasks.remove(N-1);
2687        }
2688        mRecentTasks.add(0, task);
2689    }
2690
2691    public void setRequestedOrientation(IBinder token,
2692            int requestedOrientation) {
2693        synchronized (this) {
2694            ActivityRecord r = mMainStack.isInStackLocked(token);
2695            if (r == null) {
2696                return;
2697            }
2698            final long origId = Binder.clearCallingIdentity();
2699            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2700            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2701                    mConfiguration,
2702                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2703            if (config != null) {
2704                r.frozenBeforeDestroy = true;
2705                if (!updateConfigurationLocked(config, r, false, false)) {
2706                    mMainStack.resumeTopActivityLocked(null);
2707                }
2708            }
2709            Binder.restoreCallingIdentity(origId);
2710        }
2711    }
2712
2713    public int getRequestedOrientation(IBinder token) {
2714        synchronized (this) {
2715            ActivityRecord r = mMainStack.isInStackLocked(token);
2716            if (r == null) {
2717                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2718            }
2719            return mWindowManager.getAppOrientation(r.appToken);
2720        }
2721    }
2722
2723    /**
2724     * This is the internal entry point for handling Activity.finish().
2725     *
2726     * @param token The Binder token referencing the Activity we want to finish.
2727     * @param resultCode Result code, if any, from this Activity.
2728     * @param resultData Result data (Intent), if any, from this Activity.
2729     *
2730     * @return Returns true if the activity successfully finished, or false if it is still running.
2731     */
2732    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2733        // Refuse possible leaked file descriptors
2734        if (resultData != null && resultData.hasFileDescriptors() == true) {
2735            throw new IllegalArgumentException("File descriptors passed in Intent");
2736        }
2737
2738        synchronized(this) {
2739            if (mController != null) {
2740                // Find the first activity that is not finishing.
2741                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2742                if (next != null) {
2743                    // ask watcher if this is allowed
2744                    boolean resumeOK = true;
2745                    try {
2746                        resumeOK = mController.activityResuming(next.packageName);
2747                    } catch (RemoteException e) {
2748                        mController = null;
2749                    }
2750
2751                    if (!resumeOK) {
2752                        return false;
2753                    }
2754                }
2755            }
2756            final long origId = Binder.clearCallingIdentity();
2757            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2758                    resultData, "app-request", true);
2759            Binder.restoreCallingIdentity(origId);
2760            return res;
2761        }
2762    }
2763
2764    public final void finishHeavyWeightApp() {
2765        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2766                != PackageManager.PERMISSION_GRANTED) {
2767            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2768                    + Binder.getCallingPid()
2769                    + ", uid=" + Binder.getCallingUid()
2770                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2771            Slog.w(TAG, msg);
2772            throw new SecurityException(msg);
2773        }
2774
2775        synchronized(this) {
2776            if (mHeavyWeightProcess == null) {
2777                return;
2778            }
2779
2780            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2781                    mHeavyWeightProcess.activities);
2782            for (int i=0; i<activities.size(); i++) {
2783                ActivityRecord r = activities.get(i);
2784                if (!r.finishing) {
2785                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2786                    if (index >= 0) {
2787                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2788                                null, "finish-heavy", true);
2789                    }
2790                }
2791            }
2792
2793            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2794                    mHeavyWeightProcess.userId, 0));
2795            mHeavyWeightProcess = null;
2796        }
2797    }
2798
2799    public void crashApplication(int uid, int initialPid, String packageName,
2800            String message) {
2801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2802                != PackageManager.PERMISSION_GRANTED) {
2803            String msg = "Permission Denial: crashApplication() from pid="
2804                    + Binder.getCallingPid()
2805                    + ", uid=" + Binder.getCallingUid()
2806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2807            Slog.w(TAG, msg);
2808            throw new SecurityException(msg);
2809        }
2810
2811        synchronized(this) {
2812            ProcessRecord proc = null;
2813
2814            // Figure out which process to kill.  We don't trust that initialPid
2815            // still has any relation to current pids, so must scan through the
2816            // list.
2817            synchronized (mPidsSelfLocked) {
2818                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2819                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2820                    if (p.uid != uid) {
2821                        continue;
2822                    }
2823                    if (p.pid == initialPid) {
2824                        proc = p;
2825                        break;
2826                    }
2827                    for (String str : p.pkgList) {
2828                        if (str.equals(packageName)) {
2829                            proc = p;
2830                        }
2831                    }
2832                }
2833            }
2834
2835            if (proc == null) {
2836                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2837                        + " initialPid=" + initialPid
2838                        + " packageName=" + packageName);
2839                return;
2840            }
2841
2842            if (proc.thread != null) {
2843                if (proc.pid == Process.myPid()) {
2844                    Log.w(TAG, "crashApplication: trying to crash self!");
2845                    return;
2846                }
2847                long ident = Binder.clearCallingIdentity();
2848                try {
2849                    proc.thread.scheduleCrash(message);
2850                } catch (RemoteException e) {
2851                }
2852                Binder.restoreCallingIdentity(ident);
2853            }
2854        }
2855    }
2856
2857    public final void finishSubActivity(IBinder token, String resultWho,
2858            int requestCode) {
2859        synchronized(this) {
2860            final long origId = Binder.clearCallingIdentity();
2861            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2862            Binder.restoreCallingIdentity(origId);
2863        }
2864    }
2865
2866    public boolean finishActivityAffinity(IBinder token) {
2867        synchronized(this) {
2868            final long origId = Binder.clearCallingIdentity();
2869            boolean res = mMainStack.finishActivityAffinityLocked(token);
2870            Binder.restoreCallingIdentity(origId);
2871            return res;
2872        }
2873    }
2874
2875    public boolean willActivityBeVisible(IBinder token) {
2876        synchronized(this) {
2877            int i;
2878            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2879                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2880                if (r.appToken == token) {
2881                    return true;
2882                }
2883                if (r.fullscreen && !r.finishing) {
2884                    return false;
2885                }
2886            }
2887            return true;
2888        }
2889    }
2890
2891    public void overridePendingTransition(IBinder token, String packageName,
2892            int enterAnim, int exitAnim) {
2893        synchronized(this) {
2894            ActivityRecord self = mMainStack.isInStackLocked(token);
2895            if (self == null) {
2896                return;
2897            }
2898
2899            final long origId = Binder.clearCallingIdentity();
2900
2901            if (self.state == ActivityState.RESUMED
2902                    || self.state == ActivityState.PAUSING) {
2903                mWindowManager.overridePendingAppTransition(packageName,
2904                        enterAnim, exitAnim, null);
2905            }
2906
2907            Binder.restoreCallingIdentity(origId);
2908        }
2909    }
2910
2911    /**
2912     * Main function for removing an existing process from the activity manager
2913     * as a result of that process going away.  Clears out all connections
2914     * to the process.
2915     */
2916    private final void handleAppDiedLocked(ProcessRecord app,
2917            boolean restarting, boolean allowRestart) {
2918        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2919        if (!restarting) {
2920            mLruProcesses.remove(app);
2921        }
2922
2923        if (mProfileProc == app) {
2924            clearProfilerLocked();
2925        }
2926
2927        // Just in case...
2928        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2929            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2930                    "App died while pausing: " + mMainStack.mPausingActivity);
2931            mMainStack.mPausingActivity = null;
2932        }
2933        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2934            mMainStack.mLastPausedActivity = null;
2935        }
2936
2937        // Remove this application's activities from active lists.
2938        boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
2939
2940        app.activities.clear();
2941
2942        if (app.instrumentationClass != null) {
2943            Slog.w(TAG, "Crash of app " + app.processName
2944                  + " running instrumentation " + app.instrumentationClass);
2945            Bundle info = new Bundle();
2946            info.putString("shortMsg", "Process crashed.");
2947            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2948        }
2949
2950        if (!restarting) {
2951            if (!mMainStack.resumeTopActivityLocked(null)) {
2952                // If there was nothing to resume, and we are not already
2953                // restarting this process, but there is a visible activity that
2954                // is hosted by the process...  then make sure all visible
2955                // activities are running, taking care of restarting this
2956                // process.
2957                if (hasVisibleActivities) {
2958                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2959                }
2960            }
2961        }
2962    }
2963
2964    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2965        IBinder threadBinder = thread.asBinder();
2966        // Find the application record.
2967        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2968            ProcessRecord rec = mLruProcesses.get(i);
2969            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2970                return i;
2971            }
2972        }
2973        return -1;
2974    }
2975
2976    final ProcessRecord getRecordForAppLocked(
2977            IApplicationThread thread) {
2978        if (thread == null) {
2979            return null;
2980        }
2981
2982        int appIndex = getLRURecordIndexForAppLocked(thread);
2983        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2984    }
2985
2986    final void appDiedLocked(ProcessRecord app, int pid,
2987            IApplicationThread thread) {
2988
2989        mProcDeaths[0]++;
2990
2991        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2992        synchronized (stats) {
2993            stats.noteProcessDiedLocked(app.info.uid, pid);
2994        }
2995
2996        // Clean up already done if the process has been re-started.
2997        if (app.pid == pid && app.thread != null &&
2998                app.thread.asBinder() == thread.asBinder()) {
2999            if (!app.killedBackground) {
3000                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3001                        + ") has died.");
3002            }
3003            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3004            if (DEBUG_CLEANUP) Slog.v(
3005                TAG, "Dying app: " + app + ", pid: " + pid
3006                + ", thread: " + thread.asBinder());
3007            boolean doLowMem = app.instrumentationClass == null;
3008            handleAppDiedLocked(app, false, true);
3009
3010            if (doLowMem) {
3011                // If there are no longer any background processes running,
3012                // and the app that died was not running instrumentation,
3013                // then tell everyone we are now low on memory.
3014                boolean haveBg = false;
3015                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3016                    ProcessRecord rec = mLruProcesses.get(i);
3017                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3018                        haveBg = true;
3019                        break;
3020                    }
3021                }
3022
3023                if (!haveBg) {
3024                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3025                    long now = SystemClock.uptimeMillis();
3026                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3027                        ProcessRecord rec = mLruProcesses.get(i);
3028                        if (rec != app && rec.thread != null &&
3029                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3030                            // The low memory report is overriding any current
3031                            // state for a GC request.  Make sure to do
3032                            // heavy/important/visible/foreground processes first.
3033                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3034                                rec.lastRequestedGc = 0;
3035                            } else {
3036                                rec.lastRequestedGc = rec.lastLowMemory;
3037                            }
3038                            rec.reportLowMemory = true;
3039                            rec.lastLowMemory = now;
3040                            mProcessesToGc.remove(rec);
3041                            addProcessToGcListLocked(rec);
3042                        }
3043                    }
3044                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3045                    scheduleAppGcsLocked();
3046                }
3047            }
3048        } else if (app.pid != pid) {
3049            // A new process has already been started.
3050            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3051                    + ") has died and restarted (pid " + app.pid + ").");
3052            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3053        } else if (DEBUG_PROCESSES) {
3054            Slog.d(TAG, "Received spurious death notification for thread "
3055                    + thread.asBinder());
3056        }
3057    }
3058
3059    /**
3060     * If a stack trace dump file is configured, dump process stack traces.
3061     * @param clearTraces causes the dump file to be erased prior to the new
3062     *    traces being written, if true; when false, the new traces will be
3063     *    appended to any existing file content.
3064     * @param firstPids of dalvik VM processes to dump stack traces for first
3065     * @param lastPids of dalvik VM processes to dump stack traces for last
3066     * @param nativeProcs optional list of native process names to dump stack crawls
3067     * @return file containing stack traces, or null if no dump file is configured
3068     */
3069    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3070            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3071        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3072        if (tracesPath == null || tracesPath.length() == 0) {
3073            return null;
3074        }
3075
3076        File tracesFile = new File(tracesPath);
3077        try {
3078            File tracesDir = tracesFile.getParentFile();
3079            if (!tracesDir.exists()) {
3080                tracesFile.mkdirs();
3081                if (!SELinux.restorecon(tracesDir)) {
3082                    return null;
3083                }
3084            }
3085            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3086
3087            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3088            tracesFile.createNewFile();
3089            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3090        } catch (IOException e) {
3091            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3092            return null;
3093        }
3094
3095        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3096        return tracesFile;
3097    }
3098
3099    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3100            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3101        // Use a FileObserver to detect when traces finish writing.
3102        // The order of traces is considered important to maintain for legibility.
3103        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3104            public synchronized void onEvent(int event, String path) { notify(); }
3105        };
3106
3107        try {
3108            observer.startWatching();
3109
3110            // First collect all of the stacks of the most important pids.
3111            if (firstPids != null) {
3112                try {
3113                    int num = firstPids.size();
3114                    for (int i = 0; i < num; i++) {
3115                        synchronized (observer) {
3116                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3117                            observer.wait(200);  // Wait for write-close, give up after 200msec
3118                        }
3119                    }
3120                } catch (InterruptedException e) {
3121                    Log.wtf(TAG, e);
3122                }
3123            }
3124
3125            // Next measure CPU usage.
3126            if (processStats != null) {
3127                processStats.init();
3128                System.gc();
3129                processStats.update();
3130                try {
3131                    synchronized (processStats) {
3132                        processStats.wait(500); // measure over 1/2 second.
3133                    }
3134                } catch (InterruptedException e) {
3135                }
3136                processStats.update();
3137
3138                // We'll take the stack crawls of just the top apps using CPU.
3139                final int N = processStats.countWorkingStats();
3140                int numProcs = 0;
3141                for (int i=0; i<N && numProcs<5; i++) {
3142                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3143                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3144                        numProcs++;
3145                        try {
3146                            synchronized (observer) {
3147                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3148                                observer.wait(200);  // Wait for write-close, give up after 200msec
3149                            }
3150                        } catch (InterruptedException e) {
3151                            Log.wtf(TAG, e);
3152                        }
3153
3154                    }
3155                }
3156            }
3157
3158        } finally {
3159            observer.stopWatching();
3160        }
3161
3162        if (nativeProcs != null) {
3163            int[] pids = Process.getPidsForCommands(nativeProcs);
3164            if (pids != null) {
3165                for (int pid : pids) {
3166                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3167                }
3168            }
3169        }
3170    }
3171
3172    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3173        if (true || IS_USER_BUILD) {
3174            return;
3175        }
3176        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3177        if (tracesPath == null || tracesPath.length() == 0) {
3178            return;
3179        }
3180
3181        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3182        StrictMode.allowThreadDiskWrites();
3183        try {
3184            final File tracesFile = new File(tracesPath);
3185            final File tracesDir = tracesFile.getParentFile();
3186            final File tracesTmp = new File(tracesDir, "__tmp__");
3187            try {
3188                if (!tracesDir.exists()) {
3189                    tracesFile.mkdirs();
3190                    if (!SELinux.restorecon(tracesDir.getPath())) {
3191                        return;
3192                    }
3193                }
3194                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3195
3196                if (tracesFile.exists()) {
3197                    tracesTmp.delete();
3198                    tracesFile.renameTo(tracesTmp);
3199                }
3200                StringBuilder sb = new StringBuilder();
3201                Time tobj = new Time();
3202                tobj.set(System.currentTimeMillis());
3203                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3204                sb.append(": ");
3205                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3206                sb.append(" since ");
3207                sb.append(msg);
3208                FileOutputStream fos = new FileOutputStream(tracesFile);
3209                fos.write(sb.toString().getBytes());
3210                if (app == null) {
3211                    fos.write("\n*** No application process!".getBytes());
3212                }
3213                fos.close();
3214                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3215            } catch (IOException e) {
3216                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3217                return;
3218            }
3219
3220            if (app != null) {
3221                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3222                firstPids.add(app.pid);
3223                dumpStackTraces(tracesPath, firstPids, null, null, null);
3224            }
3225
3226            File lastTracesFile = null;
3227            File curTracesFile = null;
3228            for (int i=9; i>=0; i--) {
3229                String name = String.format("slow%02d.txt", i);
3230                curTracesFile = new File(tracesDir, name);
3231                if (curTracesFile.exists()) {
3232                    if (lastTracesFile != null) {
3233                        curTracesFile.renameTo(lastTracesFile);
3234                    } else {
3235                        curTracesFile.delete();
3236                    }
3237                }
3238                lastTracesFile = curTracesFile;
3239            }
3240            tracesFile.renameTo(curTracesFile);
3241            if (tracesTmp.exists()) {
3242                tracesTmp.renameTo(tracesFile);
3243            }
3244        } finally {
3245            StrictMode.setThreadPolicy(oldPolicy);
3246        }
3247    }
3248
3249    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3250            ActivityRecord parent, final String annotation) {
3251        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3252        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3253
3254        if (mController != null) {
3255            try {
3256                // 0 == continue, -1 = kill process immediately
3257                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3258                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3259            } catch (RemoteException e) {
3260                mController = null;
3261            }
3262        }
3263
3264        long anrTime = SystemClock.uptimeMillis();
3265        if (MONITOR_CPU_USAGE) {
3266            updateCpuStatsNow();
3267        }
3268
3269        synchronized (this) {
3270            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3271            if (mShuttingDown) {
3272                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3273                return;
3274            } else if (app.notResponding) {
3275                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3276                return;
3277            } else if (app.crashing) {
3278                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3279                return;
3280            }
3281
3282            // In case we come through here for the same app before completing
3283            // this one, mark as anring now so we will bail out.
3284            app.notResponding = true;
3285
3286            // Log the ANR to the event log.
3287            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3288                    app.processName, app.info.flags, annotation);
3289
3290            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3291            firstPids.add(app.pid);
3292
3293            int parentPid = app.pid;
3294            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3295            if (parentPid != app.pid) firstPids.add(parentPid);
3296
3297            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3298
3299            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3300                ProcessRecord r = mLruProcesses.get(i);
3301                if (r != null && r.thread != null) {
3302                    int pid = r.pid;
3303                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3304                        if (r.persistent) {
3305                            firstPids.add(pid);
3306                        } else {
3307                            lastPids.put(pid, Boolean.TRUE);
3308                        }
3309                    }
3310                }
3311            }
3312        }
3313
3314        // Log the ANR to the main log.
3315        StringBuilder info = new StringBuilder();
3316        info.setLength(0);
3317        info.append("ANR in ").append(app.processName);
3318        if (activity != null && activity.shortComponentName != null) {
3319            info.append(" (").append(activity.shortComponentName).append(")");
3320        }
3321        info.append("\n");
3322        if (annotation != null) {
3323            info.append("Reason: ").append(annotation).append("\n");
3324        }
3325        if (parent != null && parent != activity) {
3326            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3327        }
3328
3329        final ProcessStats processStats = new ProcessStats(true);
3330
3331        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3332
3333        String cpuInfo = null;
3334        if (MONITOR_CPU_USAGE) {
3335            updateCpuStatsNow();
3336            synchronized (mProcessStatsThread) {
3337                cpuInfo = mProcessStats.printCurrentState(anrTime);
3338            }
3339            info.append(processStats.printCurrentLoad());
3340            info.append(cpuInfo);
3341        }
3342
3343        info.append(processStats.printCurrentState(anrTime));
3344
3345        Slog.e(TAG, info.toString());
3346        if (tracesFile == null) {
3347            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3348            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3349        }
3350
3351        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3352                cpuInfo, tracesFile, null);
3353
3354        if (mController != null) {
3355            try {
3356                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3357                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3358                if (res != 0) {
3359                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3360                    return;
3361                }
3362            } catch (RemoteException e) {
3363                mController = null;
3364            }
3365        }
3366
3367        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3368        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3369                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3370
3371        synchronized (this) {
3372            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3373                Slog.w(TAG, "Killing " + app + ": background ANR");
3374                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3375                        app.processName, app.setAdj, "background ANR");
3376                Process.killProcessQuiet(app.pid);
3377                return;
3378            }
3379
3380            // Set the app's notResponding state, and look up the errorReportReceiver
3381            makeAppNotRespondingLocked(app,
3382                    activity != null ? activity.shortComponentName : null,
3383                    annotation != null ? "ANR " + annotation : "ANR",
3384                    info.toString());
3385
3386            // Bring up the infamous App Not Responding dialog
3387            Message msg = Message.obtain();
3388            HashMap map = new HashMap();
3389            msg.what = SHOW_NOT_RESPONDING_MSG;
3390            msg.obj = map;
3391            map.put("app", app);
3392            if (activity != null) {
3393                map.put("activity", activity);
3394            }
3395
3396            mHandler.sendMessage(msg);
3397        }
3398    }
3399
3400    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3401        if (!mLaunchWarningShown) {
3402            mLaunchWarningShown = true;
3403            mHandler.post(new Runnable() {
3404                @Override
3405                public void run() {
3406                    synchronized (ActivityManagerService.this) {
3407                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3408                        d.show();
3409                        mHandler.postDelayed(new Runnable() {
3410                            @Override
3411                            public void run() {
3412                                synchronized (ActivityManagerService.this) {
3413                                    d.dismiss();
3414                                    mLaunchWarningShown = false;
3415                                }
3416                            }
3417                        }, 4000);
3418                    }
3419                }
3420            });
3421        }
3422    }
3423
3424    public boolean clearApplicationUserData(final String packageName,
3425            final IPackageDataObserver observer, int userId) {
3426        enforceNotIsolatedCaller("clearApplicationUserData");
3427        int uid = Binder.getCallingUid();
3428        int pid = Binder.getCallingPid();
3429        userId = handleIncomingUser(pid, uid,
3430                userId, false, true, "clearApplicationUserData", null);
3431        long callingId = Binder.clearCallingIdentity();
3432        try {
3433            IPackageManager pm = AppGlobals.getPackageManager();
3434            int pkgUid = -1;
3435            synchronized(this) {
3436                try {
3437                    pkgUid = pm.getPackageUid(packageName, userId);
3438                } catch (RemoteException e) {
3439                }
3440                if (pkgUid == -1) {
3441                    Slog.w(TAG, "Invalid packageName:" + packageName);
3442                    return false;
3443                }
3444                if (uid == pkgUid || checkComponentPermission(
3445                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3446                        pid, uid, -1, true)
3447                        == PackageManager.PERMISSION_GRANTED) {
3448                    forceStopPackageLocked(packageName, pkgUid);
3449                } else {
3450                    throw new SecurityException(pid+" does not have permission:"+
3451                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3452                                    "for process:"+packageName);
3453                }
3454            }
3455
3456            try {
3457                //clear application user data
3458                pm.clearApplicationUserData(packageName, observer, userId);
3459                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3460                        Uri.fromParts("package", packageName, null));
3461                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3462                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3463                        null, null, 0, null, null, null, false, false, userId);
3464            } catch (RemoteException e) {
3465            }
3466        } finally {
3467            Binder.restoreCallingIdentity(callingId);
3468        }
3469        return true;
3470    }
3471
3472    public void killBackgroundProcesses(final String packageName, int userId) {
3473        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3474                != PackageManager.PERMISSION_GRANTED &&
3475                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3476                        != PackageManager.PERMISSION_GRANTED) {
3477            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3478                    + Binder.getCallingPid()
3479                    + ", uid=" + Binder.getCallingUid()
3480                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3481            Slog.w(TAG, msg);
3482            throw new SecurityException(msg);
3483        }
3484
3485        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3486                userId, true, true, "killBackgroundProcesses", null);
3487        long callingId = Binder.clearCallingIdentity();
3488        try {
3489            IPackageManager pm = AppGlobals.getPackageManager();
3490            synchronized(this) {
3491                int appId = -1;
3492                try {
3493                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3494                } catch (RemoteException e) {
3495                }
3496                if (appId == -1) {
3497                    Slog.w(TAG, "Invalid packageName: " + packageName);
3498                    return;
3499                }
3500                killPackageProcessesLocked(packageName, appId, userId,
3501                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3502            }
3503        } finally {
3504            Binder.restoreCallingIdentity(callingId);
3505        }
3506    }
3507
3508    public void killAllBackgroundProcesses() {
3509        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3510                != PackageManager.PERMISSION_GRANTED) {
3511            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3512                    + Binder.getCallingPid()
3513                    + ", uid=" + Binder.getCallingUid()
3514                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3515            Slog.w(TAG, msg);
3516            throw new SecurityException(msg);
3517        }
3518
3519        long callingId = Binder.clearCallingIdentity();
3520        try {
3521            synchronized(this) {
3522                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3523                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3524                    final int NA = apps.size();
3525                    for (int ia=0; ia<NA; ia++) {
3526                        ProcessRecord app = apps.valueAt(ia);
3527                        if (app.persistent) {
3528                            // we don't kill persistent processes
3529                            continue;
3530                        }
3531                        if (app.removed) {
3532                            procs.add(app);
3533                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3534                            app.removed = true;
3535                            procs.add(app);
3536                        }
3537                    }
3538                }
3539
3540                int N = procs.size();
3541                for (int i=0; i<N; i++) {
3542                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3543                }
3544            }
3545        } finally {
3546            Binder.restoreCallingIdentity(callingId);
3547        }
3548    }
3549
3550    public void forceStopPackage(final String packageName, int userId) {
3551        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3552                != PackageManager.PERMISSION_GRANTED) {
3553            String msg = "Permission Denial: forceStopPackage() from pid="
3554                    + Binder.getCallingPid()
3555                    + ", uid=" + Binder.getCallingUid()
3556                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3557            Slog.w(TAG, msg);
3558            throw new SecurityException(msg);
3559        }
3560        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3561                userId, true, true, "forceStopPackage", null);
3562        long callingId = Binder.clearCallingIdentity();
3563        try {
3564            IPackageManager pm = AppGlobals.getPackageManager();
3565            synchronized(this) {
3566                int[] users = userId == UserHandle.USER_ALL
3567                        ? getUsersLocked() : new int[] { userId };
3568                for (int user : users) {
3569                    int pkgUid = -1;
3570                    try {
3571                        pkgUid = pm.getPackageUid(packageName, user);
3572                    } catch (RemoteException e) {
3573                    }
3574                    if (pkgUid == -1) {
3575                        Slog.w(TAG, "Invalid packageName: " + packageName);
3576                        continue;
3577                    }
3578                    try {
3579                        pm.setPackageStoppedState(packageName, true, user);
3580                    } catch (RemoteException e) {
3581                    } catch (IllegalArgumentException e) {
3582                        Slog.w(TAG, "Failed trying to unstop package "
3583                                + packageName + ": " + e);
3584                    }
3585                    if (isUserRunningLocked(user)) {
3586                        forceStopPackageLocked(packageName, pkgUid);
3587                    }
3588                }
3589            }
3590        } finally {
3591            Binder.restoreCallingIdentity(callingId);
3592        }
3593    }
3594
3595    /*
3596     * The pkg name and app id have to be specified.
3597     */
3598    public void killApplicationWithAppId(String pkg, int appid) {
3599        if (pkg == null) {
3600            return;
3601        }
3602        // Make sure the uid is valid.
3603        if (appid < 0) {
3604            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3605            return;
3606        }
3607        int callerUid = Binder.getCallingUid();
3608        // Only the system server can kill an application
3609        if (callerUid == Process.SYSTEM_UID) {
3610            // Post an aysnc message to kill the application
3611            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3612            msg.arg1 = appid;
3613            msg.arg2 = 0;
3614            msg.obj = pkg;
3615            mHandler.sendMessage(msg);
3616        } else {
3617            throw new SecurityException(callerUid + " cannot kill pkg: " +
3618                    pkg);
3619        }
3620    }
3621
3622    public void closeSystemDialogs(String reason) {
3623        enforceNotIsolatedCaller("closeSystemDialogs");
3624
3625        final int pid = Binder.getCallingPid();
3626        final int uid = Binder.getCallingUid();
3627        final long origId = Binder.clearCallingIdentity();
3628        try {
3629            synchronized (this) {
3630                // Only allow this from foreground processes, so that background
3631                // applications can't abuse it to prevent system UI from being shown.
3632                if (uid >= Process.FIRST_APPLICATION_UID) {
3633                    ProcessRecord proc;
3634                    synchronized (mPidsSelfLocked) {
3635                        proc = mPidsSelfLocked.get(pid);
3636                    }
3637                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3638                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3639                                + " from background process " + proc);
3640                        return;
3641                    }
3642                }
3643                closeSystemDialogsLocked(reason);
3644            }
3645        } finally {
3646            Binder.restoreCallingIdentity(origId);
3647        }
3648    }
3649
3650    void closeSystemDialogsLocked(String reason) {
3651        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3652        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3653                | Intent.FLAG_RECEIVER_FOREGROUND);
3654        if (reason != null) {
3655            intent.putExtra("reason", reason);
3656        }
3657        mWindowManager.closeSystemDialogs(reason);
3658
3659        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3660            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3661            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3662                r.stack.finishActivityLocked(r, i,
3663                        Activity.RESULT_CANCELED, null, "close-sys", true);
3664            }
3665        }
3666
3667        broadcastIntentLocked(null, null, intent, null,
3668                null, 0, null, null, null, false, false, -1,
3669                Process.SYSTEM_UID, UserHandle.USER_ALL);
3670    }
3671
3672    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3673            throws RemoteException {
3674        enforceNotIsolatedCaller("getProcessMemoryInfo");
3675        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3676        for (int i=pids.length-1; i>=0; i--) {
3677            infos[i] = new Debug.MemoryInfo();
3678            Debug.getMemoryInfo(pids[i], infos[i]);
3679        }
3680        return infos;
3681    }
3682
3683    public long[] getProcessPss(int[] pids) throws RemoteException {
3684        enforceNotIsolatedCaller("getProcessPss");
3685        long[] pss = new long[pids.length];
3686        for (int i=pids.length-1; i>=0; i--) {
3687            pss[i] = Debug.getPss(pids[i]);
3688        }
3689        return pss;
3690    }
3691
3692    public void killApplicationProcess(String processName, int uid) {
3693        if (processName == null) {
3694            return;
3695        }
3696
3697        int callerUid = Binder.getCallingUid();
3698        // Only the system server can kill an application
3699        if (callerUid == Process.SYSTEM_UID) {
3700            synchronized (this) {
3701                ProcessRecord app = getProcessRecordLocked(processName, uid);
3702                if (app != null && app.thread != null) {
3703                    try {
3704                        app.thread.scheduleSuicide();
3705                    } catch (RemoteException e) {
3706                        // If the other end already died, then our work here is done.
3707                    }
3708                } else {
3709                    Slog.w(TAG, "Process/uid not found attempting kill of "
3710                            + processName + " / " + uid);
3711                }
3712            }
3713        } else {
3714            throw new SecurityException(callerUid + " cannot kill app process: " +
3715                    processName);
3716        }
3717    }
3718
3719    private void forceStopPackageLocked(final String packageName, int uid) {
3720        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3721                false, true, false, UserHandle.getUserId(uid));
3722        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3723                Uri.fromParts("package", packageName, null));
3724        if (!mProcessesReady) {
3725            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3726                    | Intent.FLAG_RECEIVER_FOREGROUND);
3727        }
3728        intent.putExtra(Intent.EXTRA_UID, uid);
3729        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3730        broadcastIntentLocked(null, null, intent,
3731                null, null, 0, null, null, null,
3732                false, false,
3733                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3734    }
3735
3736    private void forceStopUserLocked(int userId) {
3737        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3738        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3739        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3740                | Intent.FLAG_RECEIVER_FOREGROUND);
3741        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3742        broadcastIntentLocked(null, null, intent,
3743                null, null, 0, null, null, null,
3744                false, false,
3745                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3746    }
3747
3748    private final boolean killPackageProcessesLocked(String packageName, int appId,
3749            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3750            boolean doit, boolean evenPersistent, String reason) {
3751        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3752
3753        // Remove all processes this package may have touched: all with the
3754        // same UID (except for the system or root user), and all whose name
3755        // matches the package name.
3756        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3757        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3758            final int NA = apps.size();
3759            for (int ia=0; ia<NA; ia++) {
3760                ProcessRecord app = apps.valueAt(ia);
3761                if (app.persistent && !evenPersistent) {
3762                    // we don't kill persistent processes
3763                    continue;
3764                }
3765                if (app.removed) {
3766                    if (doit) {
3767                        procs.add(app);
3768                    }
3769                    continue;
3770                }
3771
3772                // Skip process if it doesn't meet our oom adj requirement.
3773                if (app.setAdj < minOomAdj) {
3774                    continue;
3775                }
3776
3777                // If no package is specified, we call all processes under the
3778                // give user id.
3779                if (packageName == null) {
3780                    if (app.userId != userId) {
3781                        continue;
3782                    }
3783                // Package has been specified, we want to hit all processes
3784                // that match it.  We need to qualify this by the processes
3785                // that are running under the specified app and user ID.
3786                } else {
3787                    if (UserHandle.getAppId(app.uid) != appId) {
3788                        continue;
3789                    }
3790                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3791                        continue;
3792                    }
3793                    if (!app.pkgList.contains(packageName)) {
3794                        continue;
3795                    }
3796                }
3797
3798                // Process has passed all conditions, kill it!
3799                if (!doit) {
3800                    return true;
3801                }
3802                app.removed = true;
3803                procs.add(app);
3804            }
3805        }
3806
3807        int N = procs.size();
3808        for (int i=0; i<N; i++) {
3809            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3810        }
3811        return N > 0;
3812    }
3813
3814    private final boolean forceStopPackageLocked(String name, int appId,
3815            boolean callerWillRestart, boolean purgeCache, boolean doit,
3816            boolean evenPersistent, int userId) {
3817        int i;
3818        int N;
3819
3820        if (userId == UserHandle.USER_ALL && name == null) {
3821            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3822        }
3823
3824        if (appId < 0 && name != null) {
3825            try {
3826                appId = UserHandle.getAppId(
3827                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3828            } catch (RemoteException e) {
3829            }
3830        }
3831
3832        if (doit) {
3833            if (name != null) {
3834                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3835                        + " user=" + userId);
3836            } else {
3837                Slog.i(TAG, "Force stopping user " + userId);
3838            }
3839
3840            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3841            while (badApps.hasNext()) {
3842                SparseArray<Long> ba = badApps.next();
3843                for (i=ba.size()-1; i>=0; i--) {
3844                    boolean remove = false;
3845                    final int entUid = ba.keyAt(i);
3846                    if (name != null) {
3847                        if (userId == UserHandle.USER_ALL) {
3848                            if (UserHandle.getAppId(entUid) == appId) {
3849                                remove = true;
3850                            }
3851                        } else {
3852                            if (entUid == UserHandle.getUid(userId, appId)) {
3853                                remove = true;
3854                            }
3855                        }
3856                    } else if (UserHandle.getUserId(entUid) == userId) {
3857                        remove = true;
3858                    }
3859                    if (remove) {
3860                        ba.removeAt(i);
3861                    }
3862                }
3863                if (ba.size() == 0) {
3864                    badApps.remove();
3865                }
3866            }
3867        }
3868
3869        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3870                -100, callerWillRestart, false, doit, evenPersistent,
3871                name == null ? ("force stop user " + userId) : ("force stop " + name));
3872
3873        TaskRecord lastTask = null;
3874        for (i=0; i<mMainStack.mHistory.size(); i++) {
3875            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3876            final boolean samePackage = r.packageName.equals(name)
3877                    || (name == null && r.userId == userId);
3878            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3879                    && (samePackage || r.task == lastTask)
3880                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3881                if (!doit) {
3882                    if (r.finishing) {
3883                        // If this activity is just finishing, then it is not
3884                        // interesting as far as something to stop.
3885                        continue;
3886                    }
3887                    return true;
3888                }
3889                didSomething = true;
3890                Slog.i(TAG, "  Force finishing activity " + r);
3891                if (samePackage) {
3892                    if (r.app != null) {
3893                        r.app.removed = true;
3894                    }
3895                    r.app = null;
3896                }
3897                lastTask = r.task;
3898                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3899                        null, "force-stop", true)) {
3900                    i--;
3901                }
3902            }
3903        }
3904
3905        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3906            if (!doit) {
3907                return true;
3908            }
3909            didSomething = true;
3910        }
3911
3912        if (name == null) {
3913            // Remove all sticky broadcasts from this user.
3914            mStickyBroadcasts.remove(userId);
3915        }
3916
3917        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3918        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3919                userId, providers)) {
3920            if (!doit) {
3921                return true;
3922            }
3923            didSomething = true;
3924        }
3925        N = providers.size();
3926        for (i=0; i<N; i++) {
3927            removeDyingProviderLocked(null, providers.get(i), true);
3928        }
3929
3930        if (mIntentSenderRecords.size() > 0) {
3931            Iterator<WeakReference<PendingIntentRecord>> it
3932                    = mIntentSenderRecords.values().iterator();
3933            while (it.hasNext()) {
3934                WeakReference<PendingIntentRecord> wpir = it.next();
3935                if (wpir == null) {
3936                    it.remove();
3937                    continue;
3938                }
3939                PendingIntentRecord pir = wpir.get();
3940                if (pir == null) {
3941                    it.remove();
3942                    continue;
3943                }
3944                if (name == null) {
3945                    // Stopping user, remove all objects for the user.
3946                    if (pir.key.userId != userId) {
3947                        // Not the same user, skip it.
3948                        continue;
3949                    }
3950                } else {
3951                    if (UserHandle.getAppId(pir.uid) != appId) {
3952                        // Different app id, skip it.
3953                        continue;
3954                    }
3955                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3956                        // Different user, skip it.
3957                        continue;
3958                    }
3959                    if (!pir.key.packageName.equals(name)) {
3960                        // Different package, skip it.
3961                        continue;
3962                    }
3963                }
3964                if (!doit) {
3965                    return true;
3966                }
3967                didSomething = true;
3968                it.remove();
3969                pir.canceled = true;
3970                if (pir.key.activity != null) {
3971                    pir.key.activity.pendingResults.remove(pir.ref);
3972                }
3973            }
3974        }
3975
3976        if (doit) {
3977            if (purgeCache && name != null) {
3978                AttributeCache ac = AttributeCache.instance();
3979                if (ac != null) {
3980                    ac.removePackage(name);
3981                }
3982            }
3983            if (mBooted) {
3984                mMainStack.resumeTopActivityLocked(null);
3985                mMainStack.scheduleIdleLocked();
3986            }
3987        }
3988
3989        return didSomething;
3990    }
3991
3992    private final boolean removeProcessLocked(ProcessRecord app,
3993            boolean callerWillRestart, boolean allowRestart, String reason) {
3994        final String name = app.processName;
3995        final int uid = app.uid;
3996        if (DEBUG_PROCESSES) Slog.d(
3997            TAG, "Force removing proc " + app.toShortString() + " (" + name
3998            + "/" + uid + ")");
3999
4000        mProcessNames.remove(name, uid);
4001        mIsolatedProcesses.remove(app.uid);
4002        if (mHeavyWeightProcess == app) {
4003            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4004                    mHeavyWeightProcess.userId, 0));
4005            mHeavyWeightProcess = null;
4006        }
4007        boolean needRestart = false;
4008        if (app.pid > 0 && app.pid != MY_PID) {
4009            int pid = app.pid;
4010            synchronized (mPidsSelfLocked) {
4011                mPidsSelfLocked.remove(pid);
4012                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4013            }
4014            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4015            handleAppDiedLocked(app, true, allowRestart);
4016            mLruProcesses.remove(app);
4017            Process.killProcessQuiet(pid);
4018
4019            if (app.persistent && !app.isolated) {
4020                if (!callerWillRestart) {
4021                    addAppLocked(app.info, false);
4022                } else {
4023                    needRestart = true;
4024                }
4025            }
4026        } else {
4027            mRemovedProcesses.add(app);
4028        }
4029
4030        return needRestart;
4031    }
4032
4033    private final void processStartTimedOutLocked(ProcessRecord app) {
4034        final int pid = app.pid;
4035        boolean gone = false;
4036        synchronized (mPidsSelfLocked) {
4037            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4038            if (knownApp != null && knownApp.thread == null) {
4039                mPidsSelfLocked.remove(pid);
4040                gone = true;
4041            }
4042        }
4043
4044        if (gone) {
4045            Slog.w(TAG, "Process " + app + " failed to attach");
4046            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4047                    pid, app.uid, app.processName);
4048            mProcessNames.remove(app.processName, app.uid);
4049            mIsolatedProcesses.remove(app.uid);
4050            if (mHeavyWeightProcess == app) {
4051                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4052                        mHeavyWeightProcess.userId, 0));
4053                mHeavyWeightProcess = null;
4054            }
4055            // Take care of any launching providers waiting for this process.
4056            checkAppInLaunchingProvidersLocked(app, true);
4057            // Take care of any services that are waiting for the process.
4058            mServices.processStartTimedOutLocked(app);
4059            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4060                    app.processName, app.setAdj, "start timeout");
4061            Process.killProcessQuiet(pid);
4062            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4063                Slog.w(TAG, "Unattached app died before backup, skipping");
4064                try {
4065                    IBackupManager bm = IBackupManager.Stub.asInterface(
4066                            ServiceManager.getService(Context.BACKUP_SERVICE));
4067                    bm.agentDisconnected(app.info.packageName);
4068                } catch (RemoteException e) {
4069                    // Can't happen; the backup manager is local
4070                }
4071            }
4072            if (isPendingBroadcastProcessLocked(pid)) {
4073                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4074                skipPendingBroadcastLocked(pid);
4075            }
4076        } else {
4077            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4078        }
4079    }
4080
4081    private final boolean attachApplicationLocked(IApplicationThread thread,
4082            int pid) {
4083
4084        // Find the application record that is being attached...  either via
4085        // the pid if we are running in multiple processes, or just pull the
4086        // next app record if we are emulating process with anonymous threads.
4087        ProcessRecord app;
4088        if (pid != MY_PID && pid >= 0) {
4089            synchronized (mPidsSelfLocked) {
4090                app = mPidsSelfLocked.get(pid);
4091            }
4092        } else {
4093            app = null;
4094        }
4095
4096        if (app == null) {
4097            Slog.w(TAG, "No pending application record for pid " + pid
4098                    + " (IApplicationThread " + thread + "); dropping process");
4099            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4100            if (pid > 0 && pid != MY_PID) {
4101                Process.killProcessQuiet(pid);
4102            } else {
4103                try {
4104                    thread.scheduleExit();
4105                } catch (Exception e) {
4106                    // Ignore exceptions.
4107                }
4108            }
4109            return false;
4110        }
4111
4112        // If this application record is still attached to a previous
4113        // process, clean it up now.
4114        if (app.thread != null) {
4115            handleAppDiedLocked(app, true, true);
4116        }
4117
4118        // Tell the process all about itself.
4119
4120        if (localLOGV) Slog.v(
4121                TAG, "Binding process pid " + pid + " to record " + app);
4122
4123        String processName = app.processName;
4124        try {
4125            AppDeathRecipient adr = new AppDeathRecipient(
4126                    app, pid, thread);
4127            thread.asBinder().linkToDeath(adr, 0);
4128            app.deathRecipient = adr;
4129        } catch (RemoteException e) {
4130            app.resetPackageList();
4131            startProcessLocked(app, "link fail", processName);
4132            return false;
4133        }
4134
4135        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4136
4137        app.thread = thread;
4138        app.curAdj = app.setAdj = -100;
4139        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4140        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4141        app.forcingToForeground = null;
4142        app.foregroundServices = false;
4143        app.hasShownUi = false;
4144        app.debugging = false;
4145
4146        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4147
4148        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4149        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4150
4151        if (!normalMode) {
4152            Slog.i(TAG, "Launching preboot mode app: " + app);
4153        }
4154
4155        if (localLOGV) Slog.v(
4156            TAG, "New app record " + app
4157            + " thread=" + thread.asBinder() + " pid=" + pid);
4158        try {
4159            int testMode = IApplicationThread.DEBUG_OFF;
4160            if (mDebugApp != null && mDebugApp.equals(processName)) {
4161                testMode = mWaitForDebugger
4162                    ? IApplicationThread.DEBUG_WAIT
4163                    : IApplicationThread.DEBUG_ON;
4164                app.debugging = true;
4165                if (mDebugTransient) {
4166                    mDebugApp = mOrigDebugApp;
4167                    mWaitForDebugger = mOrigWaitForDebugger;
4168                }
4169            }
4170            String profileFile = app.instrumentationProfileFile;
4171            ParcelFileDescriptor profileFd = null;
4172            boolean profileAutoStop = false;
4173            if (mProfileApp != null && mProfileApp.equals(processName)) {
4174                mProfileProc = app;
4175                profileFile = mProfileFile;
4176                profileFd = mProfileFd;
4177                profileAutoStop = mAutoStopProfiler;
4178            }
4179            boolean enableOpenGlTrace = false;
4180            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4181                enableOpenGlTrace = true;
4182                mOpenGlTraceApp = null;
4183            }
4184
4185            // If the app is being launched for restore or full backup, set it up specially
4186            boolean isRestrictedBackupMode = false;
4187            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4188                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4189                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4190                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4191            }
4192
4193            ensurePackageDexOpt(app.instrumentationInfo != null
4194                    ? app.instrumentationInfo.packageName
4195                    : app.info.packageName);
4196            if (app.instrumentationClass != null) {
4197                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4198            }
4199            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4200                    + processName + " with config " + mConfiguration);
4201            ApplicationInfo appInfo = app.instrumentationInfo != null
4202                    ? app.instrumentationInfo : app.info;
4203            app.compat = compatibilityInfoForPackageLocked(appInfo);
4204            if (profileFd != null) {
4205                profileFd = profileFd.dup();
4206            }
4207            thread.bindApplication(processName, appInfo, providers,
4208                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4209                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4210                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4211                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4212                    mCoreSettingsObserver.getCoreSettingsLocked());
4213            updateLruProcessLocked(app, false);
4214            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4215        } catch (Exception e) {
4216            // todo: Yikes!  What should we do?  For now we will try to
4217            // start another process, but that could easily get us in
4218            // an infinite loop of restarting processes...
4219            Slog.w(TAG, "Exception thrown during bind!", e);
4220
4221            app.resetPackageList();
4222            app.unlinkDeathRecipient();
4223            startProcessLocked(app, "bind fail", processName);
4224            return false;
4225        }
4226
4227        // Remove this record from the list of starting applications.
4228        mPersistentStartingProcesses.remove(app);
4229        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4230                "Attach application locked removing on hold: " + app);
4231        mProcessesOnHold.remove(app);
4232
4233        boolean badApp = false;
4234        boolean didSomething = false;
4235
4236        // See if the top visible activity is waiting to run in this process...
4237        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4238        if (hr != null && normalMode) {
4239            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4240                    && processName.equals(hr.processName)) {
4241                try {
4242                    if (mHeadless) {
4243                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4244                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4245                        didSomething = true;
4246                    }
4247                } catch (Exception e) {
4248                    Slog.w(TAG, "Exception in new application when starting activity "
4249                          + hr.intent.getComponent().flattenToShortString(), e);
4250                    badApp = true;
4251                }
4252            } else {
4253                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4254            }
4255        }
4256
4257        // Find any services that should be running in this process...
4258        if (!badApp) {
4259            try {
4260                didSomething |= mServices.attachApplicationLocked(app, processName);
4261            } catch (Exception e) {
4262                badApp = true;
4263            }
4264        }
4265
4266        // Check if a next-broadcast receiver is in this process...
4267        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4268            try {
4269                didSomething = sendPendingBroadcastsLocked(app);
4270            } catch (Exception e) {
4271                // If the app died trying to launch the receiver we declare it 'bad'
4272                badApp = true;
4273            }
4274        }
4275
4276        // Check whether the next backup agent is in this process...
4277        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4278            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4279            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4280            try {
4281                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4282                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4283                        mBackupTarget.backupMode);
4284            } catch (Exception e) {
4285                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4286                e.printStackTrace();
4287            }
4288        }
4289
4290        if (badApp) {
4291            // todo: Also need to kill application to deal with all
4292            // kinds of exceptions.
4293            handleAppDiedLocked(app, false, true);
4294            return false;
4295        }
4296
4297        if (!didSomething) {
4298            updateOomAdjLocked();
4299        }
4300
4301        return true;
4302    }
4303
4304    public final void attachApplication(IApplicationThread thread) {
4305        synchronized (this) {
4306            int callingPid = Binder.getCallingPid();
4307            final long origId = Binder.clearCallingIdentity();
4308            attachApplicationLocked(thread, callingPid);
4309            Binder.restoreCallingIdentity(origId);
4310        }
4311    }
4312
4313    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4314        final long origId = Binder.clearCallingIdentity();
4315        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4316        if (stopProfiling) {
4317            synchronized (this) {
4318                if (mProfileProc == r.app) {
4319                    if (mProfileFd != null) {
4320                        try {
4321                            mProfileFd.close();
4322                        } catch (IOException e) {
4323                        }
4324                        clearProfilerLocked();
4325                    }
4326                }
4327            }
4328        }
4329        Binder.restoreCallingIdentity(origId);
4330    }
4331
4332    void enableScreenAfterBoot() {
4333        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4334                SystemClock.uptimeMillis());
4335        mWindowManager.enableScreenAfterBoot();
4336
4337        synchronized (this) {
4338            updateEventDispatchingLocked();
4339        }
4340    }
4341
4342    public void showBootMessage(final CharSequence msg, final boolean always) {
4343        enforceNotIsolatedCaller("showBootMessage");
4344        mWindowManager.showBootMessage(msg, always);
4345    }
4346
4347    public void dismissKeyguardOnNextActivity() {
4348        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4349        final long token = Binder.clearCallingIdentity();
4350        try {
4351            synchronized (this) {
4352                if (mLockScreenShown) {
4353                    mLockScreenShown = false;
4354                    comeOutOfSleepIfNeededLocked();
4355                }
4356                mMainStack.dismissKeyguardOnNextActivityLocked();
4357            }
4358        } finally {
4359            Binder.restoreCallingIdentity(token);
4360        }
4361    }
4362
4363    final void finishBooting() {
4364        IntentFilter pkgFilter = new IntentFilter();
4365        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4366        pkgFilter.addDataScheme("package");
4367        mContext.registerReceiver(new BroadcastReceiver() {
4368            @Override
4369            public void onReceive(Context context, Intent intent) {
4370                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4371                if (pkgs != null) {
4372                    for (String pkg : pkgs) {
4373                        synchronized (ActivityManagerService.this) {
4374                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4375                                setResultCode(Activity.RESULT_OK);
4376                                return;
4377                            }
4378                        }
4379                    }
4380                }
4381            }
4382        }, pkgFilter);
4383
4384        synchronized (this) {
4385            // Ensure that any processes we had put on hold are now started
4386            // up.
4387            final int NP = mProcessesOnHold.size();
4388            if (NP > 0) {
4389                ArrayList<ProcessRecord> procs =
4390                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4391                for (int ip=0; ip<NP; ip++) {
4392                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4393                            + procs.get(ip));
4394                    startProcessLocked(procs.get(ip), "on-hold", null);
4395                }
4396            }
4397
4398            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4399                // Start looking for apps that are abusing wake locks.
4400                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4401                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4402                // Tell anyone interested that we are done booting!
4403                SystemProperties.set("sys.boot_completed", "1");
4404                SystemProperties.set("dev.bootcomplete", "1");
4405                for (int i=0; i<mStartedUsers.size(); i++) {
4406                    UserStartedState uss = mStartedUsers.valueAt(i);
4407                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4408                        uss.mState = UserStartedState.STATE_RUNNING;
4409                        final int userId = mStartedUsers.keyAt(i);
4410                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4411                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4412                        broadcastIntentLocked(null, null, intent,
4413                                null, null, 0, null, null,
4414                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4415                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4416                    }
4417                }
4418            }
4419        }
4420    }
4421
4422    final void ensureBootCompleted() {
4423        boolean booting;
4424        boolean enableScreen;
4425        synchronized (this) {
4426            booting = mBooting;
4427            mBooting = false;
4428            enableScreen = !mBooted;
4429            mBooted = true;
4430        }
4431
4432        if (booting) {
4433            finishBooting();
4434        }
4435
4436        if (enableScreen) {
4437            enableScreenAfterBoot();
4438        }
4439    }
4440
4441    public final void activityResumed(IBinder token) {
4442        final long origId = Binder.clearCallingIdentity();
4443        mMainStack.activityResumed(token);
4444        Binder.restoreCallingIdentity(origId);
4445    }
4446
4447    public final void activityPaused(IBinder token) {
4448        final long origId = Binder.clearCallingIdentity();
4449        mMainStack.activityPaused(token, false);
4450        Binder.restoreCallingIdentity(origId);
4451    }
4452
4453    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4454            CharSequence description) {
4455        if (localLOGV) Slog.v(
4456            TAG, "Activity stopped: token=" + token);
4457
4458        // Refuse possible leaked file descriptors
4459        if (icicle != null && icicle.hasFileDescriptors()) {
4460            throw new IllegalArgumentException("File descriptors passed in Bundle");
4461        }
4462
4463        ActivityRecord r = null;
4464
4465        final long origId = Binder.clearCallingIdentity();
4466
4467        synchronized (this) {
4468            r = mMainStack.isInStackLocked(token);
4469            if (r != null) {
4470                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4471            }
4472        }
4473
4474        if (r != null) {
4475            sendPendingThumbnail(r, null, null, null, false);
4476        }
4477
4478        trimApplications();
4479
4480        Binder.restoreCallingIdentity(origId);
4481    }
4482
4483    public final void activityDestroyed(IBinder token) {
4484        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4485        mMainStack.activityDestroyed(token);
4486    }
4487
4488    public String getCallingPackage(IBinder token) {
4489        synchronized (this) {
4490            ActivityRecord r = getCallingRecordLocked(token);
4491            return r != null && r.app != null ? r.info.packageName : null;
4492        }
4493    }
4494
4495    public ComponentName getCallingActivity(IBinder token) {
4496        synchronized (this) {
4497            ActivityRecord r = getCallingRecordLocked(token);
4498            return r != null ? r.intent.getComponent() : null;
4499        }
4500    }
4501
4502    private ActivityRecord getCallingRecordLocked(IBinder token) {
4503        ActivityRecord r = mMainStack.isInStackLocked(token);
4504        if (r == null) {
4505            return null;
4506        }
4507        return r.resultTo;
4508    }
4509
4510    public ComponentName getActivityClassForToken(IBinder token) {
4511        synchronized(this) {
4512            ActivityRecord r = mMainStack.isInStackLocked(token);
4513            if (r == null) {
4514                return null;
4515            }
4516            return r.intent.getComponent();
4517        }
4518    }
4519
4520    public String getPackageForToken(IBinder token) {
4521        synchronized(this) {
4522            ActivityRecord r = mMainStack.isInStackLocked(token);
4523            if (r == null) {
4524                return null;
4525            }
4526            return r.packageName;
4527        }
4528    }
4529
4530    public IIntentSender getIntentSender(int type,
4531            String packageName, IBinder token, String resultWho,
4532            int requestCode, Intent[] intents, String[] resolvedTypes,
4533            int flags, Bundle options, int userId) {
4534        enforceNotIsolatedCaller("getIntentSender");
4535        // Refuse possible leaked file descriptors
4536        if (intents != null) {
4537            if (intents.length < 1) {
4538                throw new IllegalArgumentException("Intents array length must be >= 1");
4539            }
4540            for (int i=0; i<intents.length; i++) {
4541                Intent intent = intents[i];
4542                if (intent != null) {
4543                    if (intent.hasFileDescriptors()) {
4544                        throw new IllegalArgumentException("File descriptors passed in Intent");
4545                    }
4546                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4547                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4548                        throw new IllegalArgumentException(
4549                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4550                    }
4551                    intents[i] = new Intent(intent);
4552                }
4553            }
4554            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4555                throw new IllegalArgumentException(
4556                        "Intent array length does not match resolvedTypes length");
4557            }
4558        }
4559        if (options != null) {
4560            if (options.hasFileDescriptors()) {
4561                throw new IllegalArgumentException("File descriptors passed in options");
4562            }
4563        }
4564
4565        synchronized(this) {
4566            int callingUid = Binder.getCallingUid();
4567            int origUserId = userId;
4568            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4569                    type == ActivityManager.INTENT_SENDER_BROADCAST, true,
4570                    "getIntentSender", null);
4571            if (origUserId == UserHandle.USER_CURRENT) {
4572                // We don't want to evaluate this until the pending intent is
4573                // actually executed.  However, we do want to always do the
4574                // security checking for it above.
4575                userId = UserHandle.USER_CURRENT;
4576            }
4577            try {
4578                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4579                    int uid = AppGlobals.getPackageManager()
4580                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4581                    if (!UserHandle.isSameApp(callingUid, uid)) {
4582                        String msg = "Permission Denial: getIntentSender() from pid="
4583                            + Binder.getCallingPid()
4584                            + ", uid=" + Binder.getCallingUid()
4585                            + ", (need uid=" + uid + ")"
4586                            + " is not allowed to send as package " + packageName;
4587                        Slog.w(TAG, msg);
4588                        throw new SecurityException(msg);
4589                    }
4590                }
4591
4592                return getIntentSenderLocked(type, packageName, callingUid, userId,
4593                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4594
4595            } catch (RemoteException e) {
4596                throw new SecurityException(e);
4597            }
4598        }
4599    }
4600
4601    IIntentSender getIntentSenderLocked(int type, String packageName,
4602            int callingUid, int userId, IBinder token, String resultWho,
4603            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4604            Bundle options) {
4605        if (DEBUG_MU)
4606            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4607        ActivityRecord activity = null;
4608        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4609            activity = mMainStack.isInStackLocked(token);
4610            if (activity == null) {
4611                return null;
4612            }
4613            if (activity.finishing) {
4614                return null;
4615            }
4616        }
4617
4618        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4619        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4620        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4621        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4622                |PendingIntent.FLAG_UPDATE_CURRENT);
4623
4624        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4625                type, packageName, activity, resultWho,
4626                requestCode, intents, resolvedTypes, flags, options, userId);
4627        WeakReference<PendingIntentRecord> ref;
4628        ref = mIntentSenderRecords.get(key);
4629        PendingIntentRecord rec = ref != null ? ref.get() : null;
4630        if (rec != null) {
4631            if (!cancelCurrent) {
4632                if (updateCurrent) {
4633                    if (rec.key.requestIntent != null) {
4634                        rec.key.requestIntent.replaceExtras(intents != null ?
4635                                intents[intents.length - 1] : null);
4636                    }
4637                    if (intents != null) {
4638                        intents[intents.length-1] = rec.key.requestIntent;
4639                        rec.key.allIntents = intents;
4640                        rec.key.allResolvedTypes = resolvedTypes;
4641                    } else {
4642                        rec.key.allIntents = null;
4643                        rec.key.allResolvedTypes = null;
4644                    }
4645                }
4646                return rec;
4647            }
4648            rec.canceled = true;
4649            mIntentSenderRecords.remove(key);
4650        }
4651        if (noCreate) {
4652            return rec;
4653        }
4654        rec = new PendingIntentRecord(this, key, callingUid);
4655        mIntentSenderRecords.put(key, rec.ref);
4656        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4657            if (activity.pendingResults == null) {
4658                activity.pendingResults
4659                        = new HashSet<WeakReference<PendingIntentRecord>>();
4660            }
4661            activity.pendingResults.add(rec.ref);
4662        }
4663        return rec;
4664    }
4665
4666    public void cancelIntentSender(IIntentSender sender) {
4667        if (!(sender instanceof PendingIntentRecord)) {
4668            return;
4669        }
4670        synchronized(this) {
4671            PendingIntentRecord rec = (PendingIntentRecord)sender;
4672            try {
4673                int uid = AppGlobals.getPackageManager()
4674                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4675                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4676                    String msg = "Permission Denial: cancelIntentSender() from pid="
4677                        + Binder.getCallingPid()
4678                        + ", uid=" + Binder.getCallingUid()
4679                        + " is not allowed to cancel packges "
4680                        + rec.key.packageName;
4681                    Slog.w(TAG, msg);
4682                    throw new SecurityException(msg);
4683                }
4684            } catch (RemoteException e) {
4685                throw new SecurityException(e);
4686            }
4687            cancelIntentSenderLocked(rec, true);
4688        }
4689    }
4690
4691    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4692        rec.canceled = true;
4693        mIntentSenderRecords.remove(rec.key);
4694        if (cleanActivity && rec.key.activity != null) {
4695            rec.key.activity.pendingResults.remove(rec.ref);
4696        }
4697    }
4698
4699    public String getPackageForIntentSender(IIntentSender pendingResult) {
4700        if (!(pendingResult instanceof PendingIntentRecord)) {
4701            return null;
4702        }
4703        try {
4704            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4705            return res.key.packageName;
4706        } catch (ClassCastException e) {
4707        }
4708        return null;
4709    }
4710
4711    public int getUidForIntentSender(IIntentSender sender) {
4712        if (sender instanceof PendingIntentRecord) {
4713            try {
4714                PendingIntentRecord res = (PendingIntentRecord)sender;
4715                return res.uid;
4716            } catch (ClassCastException e) {
4717            }
4718        }
4719        return -1;
4720    }
4721
4722    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4723        if (!(pendingResult instanceof PendingIntentRecord)) {
4724            return false;
4725        }
4726        try {
4727            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4728            if (res.key.allIntents == null) {
4729                return false;
4730            }
4731            for (int i=0; i<res.key.allIntents.length; i++) {
4732                Intent intent = res.key.allIntents[i];
4733                if (intent.getPackage() != null && intent.getComponent() != null) {
4734                    return false;
4735                }
4736            }
4737            return true;
4738        } catch (ClassCastException e) {
4739        }
4740        return false;
4741    }
4742
4743    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4744        if (!(pendingResult instanceof PendingIntentRecord)) {
4745            return false;
4746        }
4747        try {
4748            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4749            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4750                return true;
4751            }
4752            return false;
4753        } catch (ClassCastException e) {
4754        }
4755        return false;
4756    }
4757
4758    public void setProcessLimit(int max) {
4759        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4760                "setProcessLimit()");
4761        synchronized (this) {
4762            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4763            mProcessLimitOverride = max;
4764        }
4765        trimApplications();
4766    }
4767
4768    public int getProcessLimit() {
4769        synchronized (this) {
4770            return mProcessLimitOverride;
4771        }
4772    }
4773
4774    void foregroundTokenDied(ForegroundToken token) {
4775        synchronized (ActivityManagerService.this) {
4776            synchronized (mPidsSelfLocked) {
4777                ForegroundToken cur
4778                    = mForegroundProcesses.get(token.pid);
4779                if (cur != token) {
4780                    return;
4781                }
4782                mForegroundProcesses.remove(token.pid);
4783                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4784                if (pr == null) {
4785                    return;
4786                }
4787                pr.forcingToForeground = null;
4788                pr.foregroundServices = false;
4789            }
4790            updateOomAdjLocked();
4791        }
4792    }
4793
4794    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4795        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4796                "setProcessForeground()");
4797        synchronized(this) {
4798            boolean changed = false;
4799
4800            synchronized (mPidsSelfLocked) {
4801                ProcessRecord pr = mPidsSelfLocked.get(pid);
4802                if (pr == null && isForeground) {
4803                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4804                    return;
4805                }
4806                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4807                if (oldToken != null) {
4808                    oldToken.token.unlinkToDeath(oldToken, 0);
4809                    mForegroundProcesses.remove(pid);
4810                    if (pr != null) {
4811                        pr.forcingToForeground = null;
4812                    }
4813                    changed = true;
4814                }
4815                if (isForeground && token != null) {
4816                    ForegroundToken newToken = new ForegroundToken() {
4817                        public void binderDied() {
4818                            foregroundTokenDied(this);
4819                        }
4820                    };
4821                    newToken.pid = pid;
4822                    newToken.token = token;
4823                    try {
4824                        token.linkToDeath(newToken, 0);
4825                        mForegroundProcesses.put(pid, newToken);
4826                        pr.forcingToForeground = token;
4827                        changed = true;
4828                    } catch (RemoteException e) {
4829                        // If the process died while doing this, we will later
4830                        // do the cleanup with the process death link.
4831                    }
4832                }
4833            }
4834
4835            if (changed) {
4836                updateOomAdjLocked();
4837            }
4838        }
4839    }
4840
4841    // =========================================================
4842    // PERMISSIONS
4843    // =========================================================
4844
4845    static class PermissionController extends IPermissionController.Stub {
4846        ActivityManagerService mActivityManagerService;
4847        PermissionController(ActivityManagerService activityManagerService) {
4848            mActivityManagerService = activityManagerService;
4849        }
4850
4851        public boolean checkPermission(String permission, int pid, int uid) {
4852            return mActivityManagerService.checkPermission(permission, pid,
4853                    uid) == PackageManager.PERMISSION_GRANTED;
4854        }
4855    }
4856
4857    /**
4858     * This can be called with or without the global lock held.
4859     */
4860    int checkComponentPermission(String permission, int pid, int uid,
4861            int owningUid, boolean exported) {
4862        // We might be performing an operation on behalf of an indirect binder
4863        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4864        // client identity accordingly before proceeding.
4865        Identity tlsIdentity = sCallerIdentity.get();
4866        if (tlsIdentity != null) {
4867            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4868                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4869            uid = tlsIdentity.uid;
4870            pid = tlsIdentity.pid;
4871        }
4872
4873        if (pid == MY_PID) {
4874            return PackageManager.PERMISSION_GRANTED;
4875        }
4876
4877        return ActivityManager.checkComponentPermission(permission, uid,
4878                owningUid, exported);
4879    }
4880
4881    /**
4882     * As the only public entry point for permissions checking, this method
4883     * can enforce the semantic that requesting a check on a null global
4884     * permission is automatically denied.  (Internally a null permission
4885     * string is used when calling {@link #checkComponentPermission} in cases
4886     * when only uid-based security is needed.)
4887     *
4888     * This can be called with or without the global lock held.
4889     */
4890    public int checkPermission(String permission, int pid, int uid) {
4891        if (permission == null) {
4892            return PackageManager.PERMISSION_DENIED;
4893        }
4894        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4895    }
4896
4897    /**
4898     * Binder IPC calls go through the public entry point.
4899     * This can be called with or without the global lock held.
4900     */
4901    int checkCallingPermission(String permission) {
4902        return checkPermission(permission,
4903                Binder.getCallingPid(),
4904                UserHandle.getAppId(Binder.getCallingUid()));
4905    }
4906
4907    /**
4908     * This can be called with or without the global lock held.
4909     */
4910    void enforceCallingPermission(String permission, String func) {
4911        if (checkCallingPermission(permission)
4912                == PackageManager.PERMISSION_GRANTED) {
4913            return;
4914        }
4915
4916        String msg = "Permission Denial: " + func + " from pid="
4917                + Binder.getCallingPid()
4918                + ", uid=" + Binder.getCallingUid()
4919                + " requires " + permission;
4920        Slog.w(TAG, msg);
4921        throw new SecurityException(msg);
4922    }
4923
4924    /**
4925     * Determine if UID is holding permissions required to access {@link Uri} in
4926     * the given {@link ProviderInfo}. Final permission checking is always done
4927     * in {@link ContentProvider}.
4928     */
4929    private final boolean checkHoldingPermissionsLocked(
4930            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4931        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4932                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4933
4934        if (pi.applicationInfo.uid == uid) {
4935            return true;
4936        } else if (!pi.exported) {
4937            return false;
4938        }
4939
4940        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4941        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4942        try {
4943            // check if target holds top-level <provider> permissions
4944            if (!readMet && pi.readPermission != null
4945                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4946                readMet = true;
4947            }
4948            if (!writeMet && pi.writePermission != null
4949                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4950                writeMet = true;
4951            }
4952
4953            // track if unprotected read/write is allowed; any denied
4954            // <path-permission> below removes this ability
4955            boolean allowDefaultRead = pi.readPermission == null;
4956            boolean allowDefaultWrite = pi.writePermission == null;
4957
4958            // check if target holds any <path-permission> that match uri
4959            final PathPermission[] pps = pi.pathPermissions;
4960            if (pps != null) {
4961                final String path = uri.getPath();
4962                int i = pps.length;
4963                while (i > 0 && (!readMet || !writeMet)) {
4964                    i--;
4965                    PathPermission pp = pps[i];
4966                    if (pp.match(path)) {
4967                        if (!readMet) {
4968                            final String pprperm = pp.getReadPermission();
4969                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4970                                    + pprperm + " for " + pp.getPath()
4971                                    + ": match=" + pp.match(path)
4972                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4973                            if (pprperm != null) {
4974                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4975                                    readMet = true;
4976                                } else {
4977                                    allowDefaultRead = false;
4978                                }
4979                            }
4980                        }
4981                        if (!writeMet) {
4982                            final String ppwperm = pp.getWritePermission();
4983                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4984                                    + ppwperm + " for " + pp.getPath()
4985                                    + ": match=" + pp.match(path)
4986                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4987                            if (ppwperm != null) {
4988                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4989                                    writeMet = true;
4990                                } else {
4991                                    allowDefaultWrite = false;
4992                                }
4993                            }
4994                        }
4995                    }
4996                }
4997            }
4998
4999            // grant unprotected <provider> read/write, if not blocked by
5000            // <path-permission> above
5001            if (allowDefaultRead) readMet = true;
5002            if (allowDefaultWrite) writeMet = true;
5003
5004        } catch (RemoteException e) {
5005            return false;
5006        }
5007
5008        return readMet && writeMet;
5009    }
5010
5011    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5012            int modeFlags) {
5013        // Root gets to do everything.
5014        if (uid == 0) {
5015            return true;
5016        }
5017        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5018        if (perms == null) return false;
5019        UriPermission perm = perms.get(uri);
5020        if (perm == null) return false;
5021        return (modeFlags&perm.modeFlags) == modeFlags;
5022    }
5023
5024    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5025        enforceNotIsolatedCaller("checkUriPermission");
5026
5027        // Another redirected-binder-call permissions check as in
5028        // {@link checkComponentPermission}.
5029        Identity tlsIdentity = sCallerIdentity.get();
5030        if (tlsIdentity != null) {
5031            uid = tlsIdentity.uid;
5032            pid = tlsIdentity.pid;
5033        }
5034
5035        // Our own process gets to do everything.
5036        if (pid == MY_PID) {
5037            return PackageManager.PERMISSION_GRANTED;
5038        }
5039        synchronized(this) {
5040            return checkUriPermissionLocked(uri, uid, modeFlags)
5041                    ? PackageManager.PERMISSION_GRANTED
5042                    : PackageManager.PERMISSION_DENIED;
5043        }
5044    }
5045
5046    /**
5047     * Check if the targetPkg can be granted permission to access uri by
5048     * the callingUid using the given modeFlags.  Throws a security exception
5049     * if callingUid is not allowed to do this.  Returns the uid of the target
5050     * if the URI permission grant should be performed; returns -1 if it is not
5051     * needed (for example targetPkg already has permission to access the URI).
5052     * If you already know the uid of the target, you can supply it in
5053     * lastTargetUid else set that to -1.
5054     */
5055    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5056            Uri uri, int modeFlags, int lastTargetUid) {
5057        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5058                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5059        if (modeFlags == 0) {
5060            return -1;
5061        }
5062
5063        if (targetPkg != null) {
5064            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5065                    "Checking grant " + targetPkg + " permission to " + uri);
5066        }
5067
5068        final IPackageManager pm = AppGlobals.getPackageManager();
5069
5070        // If this is not a content: uri, we can't do anything with it.
5071        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5072            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5073                    "Can't grant URI permission for non-content URI: " + uri);
5074            return -1;
5075        }
5076
5077        String name = uri.getAuthority();
5078        ProviderInfo pi = null;
5079        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5080                UserHandle.getUserId(callingUid));
5081        if (cpr != null) {
5082            pi = cpr.info;
5083        } else {
5084            try {
5085                pi = pm.resolveContentProvider(name,
5086                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5087                        UserHandle.getUserId(callingUid));
5088            } catch (RemoteException ex) {
5089            }
5090        }
5091        if (pi == null) {
5092            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5093            return -1;
5094        }
5095
5096        int targetUid = lastTargetUid;
5097        if (targetUid < 0 && targetPkg != null) {
5098            try {
5099                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5100                if (targetUid < 0) {
5101                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5102                            "Can't grant URI permission no uid for: " + targetPkg);
5103                    return -1;
5104                }
5105            } catch (RemoteException ex) {
5106                return -1;
5107            }
5108        }
5109
5110        if (targetUid >= 0) {
5111            // First...  does the target actually need this permission?
5112            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5113                // No need to grant the target this permission.
5114                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5115                        "Target " + targetPkg + " already has full permission to " + uri);
5116                return -1;
5117            }
5118        } else {
5119            // First...  there is no target package, so can anyone access it?
5120            boolean allowed = pi.exported;
5121            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5122                if (pi.readPermission != null) {
5123                    allowed = false;
5124                }
5125            }
5126            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5127                if (pi.writePermission != null) {
5128                    allowed = false;
5129                }
5130            }
5131            if (allowed) {
5132                return -1;
5133            }
5134        }
5135
5136        // Second...  is the provider allowing granting of URI permissions?
5137        if (!pi.grantUriPermissions) {
5138            throw new SecurityException("Provider " + pi.packageName
5139                    + "/" + pi.name
5140                    + " does not allow granting of Uri permissions (uri "
5141                    + uri + ")");
5142        }
5143        if (pi.uriPermissionPatterns != null) {
5144            final int N = pi.uriPermissionPatterns.length;
5145            boolean allowed = false;
5146            for (int i=0; i<N; i++) {
5147                if (pi.uriPermissionPatterns[i] != null
5148                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5149                    allowed = true;
5150                    break;
5151                }
5152            }
5153            if (!allowed) {
5154                throw new SecurityException("Provider " + pi.packageName
5155                        + "/" + pi.name
5156                        + " does not allow granting of permission to path of Uri "
5157                        + uri);
5158            }
5159        }
5160
5161        // Third...  does the caller itself have permission to access
5162        // this uri?
5163        if (callingUid != Process.myUid()) {
5164            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5165                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5166                    throw new SecurityException("Uid " + callingUid
5167                            + " does not have permission to uri " + uri);
5168                }
5169            }
5170        }
5171
5172        return targetUid;
5173    }
5174
5175    public int checkGrantUriPermission(int callingUid, String targetPkg,
5176            Uri uri, int modeFlags) {
5177        enforceNotIsolatedCaller("checkGrantUriPermission");
5178        synchronized(this) {
5179            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5180        }
5181    }
5182
5183    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5184            Uri uri, int modeFlags, UriPermissionOwner owner) {
5185        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5186                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5187        if (modeFlags == 0) {
5188            return;
5189        }
5190
5191        // So here we are: the caller has the assumed permission
5192        // to the uri, and the target doesn't.  Let's now give this to
5193        // the target.
5194
5195        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5196                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5197
5198        HashMap<Uri, UriPermission> targetUris
5199                = mGrantedUriPermissions.get(targetUid);
5200        if (targetUris == null) {
5201            targetUris = new HashMap<Uri, UriPermission>();
5202            mGrantedUriPermissions.put(targetUid, targetUris);
5203        }
5204
5205        UriPermission perm = targetUris.get(uri);
5206        if (perm == null) {
5207            perm = new UriPermission(targetUid, uri);
5208            targetUris.put(uri, perm);
5209        }
5210
5211        perm.modeFlags |= modeFlags;
5212        if (owner == null) {
5213            perm.globalModeFlags |= modeFlags;
5214        } else {
5215            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5216                 perm.readOwners.add(owner);
5217                 owner.addReadPermission(perm);
5218            }
5219            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5220                 perm.writeOwners.add(owner);
5221                 owner.addWritePermission(perm);
5222            }
5223        }
5224    }
5225
5226    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5227            int modeFlags, UriPermissionOwner owner) {
5228        if (targetPkg == null) {
5229            throw new NullPointerException("targetPkg");
5230        }
5231
5232        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5233        if (targetUid < 0) {
5234            return;
5235        }
5236
5237        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5238    }
5239
5240    static class NeededUriGrants extends ArrayList<Uri> {
5241        final String targetPkg;
5242        final int targetUid;
5243        final int flags;
5244
5245        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5246            targetPkg = _targetPkg;
5247            targetUid = _targetUid;
5248            flags = _flags;
5249        }
5250    }
5251
5252    /**
5253     * Like checkGrantUriPermissionLocked, but takes an Intent.
5254     */
5255    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5256            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5257        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5258                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5259                + " clip=" + (intent != null ? intent.getClipData() : null)
5260                + " from " + intent + "; flags=0x"
5261                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5262
5263        if (targetPkg == null) {
5264            throw new NullPointerException("targetPkg");
5265        }
5266
5267        if (intent == null) {
5268            return null;
5269        }
5270        Uri data = intent.getData();
5271        ClipData clip = intent.getClipData();
5272        if (data == null && clip == null) {
5273            return null;
5274        }
5275        if (data != null) {
5276            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5277                mode, needed != null ? needed.targetUid : -1);
5278            if (target > 0) {
5279                if (needed == null) {
5280                    needed = new NeededUriGrants(targetPkg, target, mode);
5281                }
5282                needed.add(data);
5283            }
5284        }
5285        if (clip != null) {
5286            for (int i=0; i<clip.getItemCount(); i++) {
5287                Uri uri = clip.getItemAt(i).getUri();
5288                if (uri != null) {
5289                    int target = -1;
5290                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5291                            mode, needed != null ? needed.targetUid : -1);
5292                    if (target > 0) {
5293                        if (needed == null) {
5294                            needed = new NeededUriGrants(targetPkg, target, mode);
5295                        }
5296                        needed.add(uri);
5297                    }
5298                } else {
5299                    Intent clipIntent = clip.getItemAt(i).getIntent();
5300                    if (clipIntent != null) {
5301                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5302                                callingUid, targetPkg, clipIntent, mode, needed);
5303                        if (newNeeded != null) {
5304                            needed = newNeeded;
5305                        }
5306                    }
5307                }
5308            }
5309        }
5310
5311        return needed;
5312    }
5313
5314    /**
5315     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5316     */
5317    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5318            UriPermissionOwner owner) {
5319        if (needed != null) {
5320            for (int i=0; i<needed.size(); i++) {
5321                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5322                        needed.get(i), needed.flags, owner);
5323            }
5324        }
5325    }
5326
5327    void grantUriPermissionFromIntentLocked(int callingUid,
5328            String targetPkg, Intent intent, UriPermissionOwner owner) {
5329        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5330                intent, intent != null ? intent.getFlags() : 0, null);
5331        if (needed == null) {
5332            return;
5333        }
5334
5335        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5336    }
5337
5338    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5339            Uri uri, int modeFlags) {
5340        enforceNotIsolatedCaller("grantUriPermission");
5341        synchronized(this) {
5342            final ProcessRecord r = getRecordForAppLocked(caller);
5343            if (r == null) {
5344                throw new SecurityException("Unable to find app for caller "
5345                        + caller
5346                        + " when granting permission to uri " + uri);
5347            }
5348            if (targetPkg == null) {
5349                throw new IllegalArgumentException("null target");
5350            }
5351            if (uri == null) {
5352                throw new IllegalArgumentException("null uri");
5353            }
5354
5355            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5356                    null);
5357        }
5358    }
5359
5360    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5361        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5362                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5363            HashMap<Uri, UriPermission> perms
5364                    = mGrantedUriPermissions.get(perm.uid);
5365            if (perms != null) {
5366                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5367                        "Removing " + perm.uid + " permission to " + perm.uri);
5368                perms.remove(perm.uri);
5369                if (perms.size() == 0) {
5370                    mGrantedUriPermissions.remove(perm.uid);
5371                }
5372            }
5373        }
5374    }
5375
5376    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5377            int modeFlags) {
5378        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5379                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5380        if (modeFlags == 0) {
5381            return;
5382        }
5383
5384        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5385                "Revoking all granted permissions to " + uri);
5386
5387        final IPackageManager pm = AppGlobals.getPackageManager();
5388
5389        final String authority = uri.getAuthority();
5390        ProviderInfo pi = null;
5391        int userId = UserHandle.getUserId(callingUid);
5392        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5393        if (cpr != null) {
5394            pi = cpr.info;
5395        } else {
5396            try {
5397                pi = pm.resolveContentProvider(authority,
5398                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5399            } catch (RemoteException ex) {
5400            }
5401        }
5402        if (pi == null) {
5403            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5404            return;
5405        }
5406
5407        // Does the caller have this permission on the URI?
5408        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5409            // Right now, if you are not the original owner of the permission,
5410            // you are not allowed to revoke it.
5411            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5412                throw new SecurityException("Uid " + callingUid
5413                        + " does not have permission to uri " + uri);
5414            //}
5415        }
5416
5417        // Go through all of the permissions and remove any that match.
5418        final List<String> SEGMENTS = uri.getPathSegments();
5419        if (SEGMENTS != null) {
5420            final int NS = SEGMENTS.size();
5421            int N = mGrantedUriPermissions.size();
5422            for (int i=0; i<N; i++) {
5423                HashMap<Uri, UriPermission> perms
5424                        = mGrantedUriPermissions.valueAt(i);
5425                Iterator<UriPermission> it = perms.values().iterator();
5426            toploop:
5427                while (it.hasNext()) {
5428                    UriPermission perm = it.next();
5429                    Uri targetUri = perm.uri;
5430                    if (!authority.equals(targetUri.getAuthority())) {
5431                        continue;
5432                    }
5433                    List<String> targetSegments = targetUri.getPathSegments();
5434                    if (targetSegments == null) {
5435                        continue;
5436                    }
5437                    if (targetSegments.size() < NS) {
5438                        continue;
5439                    }
5440                    for (int j=0; j<NS; j++) {
5441                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5442                            continue toploop;
5443                        }
5444                    }
5445                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5446                            "Revoking " + perm.uid + " permission to " + perm.uri);
5447                    perm.clearModes(modeFlags);
5448                    if (perm.modeFlags == 0) {
5449                        it.remove();
5450                    }
5451                }
5452                if (perms.size() == 0) {
5453                    mGrantedUriPermissions.remove(
5454                            mGrantedUriPermissions.keyAt(i));
5455                    N--;
5456                    i--;
5457                }
5458            }
5459        }
5460    }
5461
5462    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5463            int modeFlags) {
5464        enforceNotIsolatedCaller("revokeUriPermission");
5465        synchronized(this) {
5466            final ProcessRecord r = getRecordForAppLocked(caller);
5467            if (r == null) {
5468                throw new SecurityException("Unable to find app for caller "
5469                        + caller
5470                        + " when revoking permission to uri " + uri);
5471            }
5472            if (uri == null) {
5473                Slog.w(TAG, "revokeUriPermission: null uri");
5474                return;
5475            }
5476
5477            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5478                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5479            if (modeFlags == 0) {
5480                return;
5481            }
5482
5483            final IPackageManager pm = AppGlobals.getPackageManager();
5484
5485            final String authority = uri.getAuthority();
5486            ProviderInfo pi = null;
5487            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5488            if (cpr != null) {
5489                pi = cpr.info;
5490            } else {
5491                try {
5492                    pi = pm.resolveContentProvider(authority,
5493                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5494                } catch (RemoteException ex) {
5495                }
5496            }
5497            if (pi == null) {
5498                Slog.w(TAG, "No content provider found for permission revoke: "
5499                        + uri.toSafeString());
5500                return;
5501            }
5502
5503            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5504        }
5505    }
5506
5507    @Override
5508    public IBinder newUriPermissionOwner(String name) {
5509        enforceNotIsolatedCaller("newUriPermissionOwner");
5510        synchronized(this) {
5511            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5512            return owner.getExternalTokenLocked();
5513        }
5514    }
5515
5516    @Override
5517    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5518            Uri uri, int modeFlags) {
5519        synchronized(this) {
5520            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5521            if (owner == null) {
5522                throw new IllegalArgumentException("Unknown owner: " + token);
5523            }
5524            if (fromUid != Binder.getCallingUid()) {
5525                if (Binder.getCallingUid() != Process.myUid()) {
5526                    // Only system code can grant URI permissions on behalf
5527                    // of other users.
5528                    throw new SecurityException("nice try");
5529                }
5530            }
5531            if (targetPkg == null) {
5532                throw new IllegalArgumentException("null target");
5533            }
5534            if (uri == null) {
5535                throw new IllegalArgumentException("null uri");
5536            }
5537
5538            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5539        }
5540    }
5541
5542    @Override
5543    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5544        synchronized(this) {
5545            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5546            if (owner == null) {
5547                throw new IllegalArgumentException("Unknown owner: " + token);
5548            }
5549
5550            if (uri == null) {
5551                owner.removeUriPermissionsLocked(mode);
5552            } else {
5553                owner.removeUriPermissionLocked(uri, mode);
5554            }
5555        }
5556    }
5557
5558    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5559        synchronized (this) {
5560            ProcessRecord app =
5561                who != null ? getRecordForAppLocked(who) : null;
5562            if (app == null) return;
5563
5564            Message msg = Message.obtain();
5565            msg.what = WAIT_FOR_DEBUGGER_MSG;
5566            msg.obj = app;
5567            msg.arg1 = waiting ? 1 : 0;
5568            mHandler.sendMessage(msg);
5569        }
5570    }
5571
5572    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5573        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5574        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5575        outInfo.availMem = Process.getFreeMemory();
5576        outInfo.totalMem = Process.getTotalMemory();
5577        outInfo.threshold = homeAppMem;
5578        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5579        outInfo.hiddenAppThreshold = hiddenAppMem;
5580        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5581                ProcessList.SERVICE_ADJ);
5582        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5583                ProcessList.VISIBLE_APP_ADJ);
5584        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5585                ProcessList.FOREGROUND_APP_ADJ);
5586    }
5587
5588    // =========================================================
5589    // TASK MANAGEMENT
5590    // =========================================================
5591
5592    public List getTasks(int maxNum, int flags,
5593                         IThumbnailReceiver receiver) {
5594        ArrayList list = new ArrayList();
5595
5596        PendingThumbnailsRecord pending = null;
5597        IApplicationThread topThumbnail = null;
5598        ActivityRecord topRecord = null;
5599
5600        synchronized(this) {
5601            if (localLOGV) Slog.v(
5602                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5603                + ", receiver=" + receiver);
5604
5605            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5606                    != PackageManager.PERMISSION_GRANTED) {
5607                if (receiver != null) {
5608                    // If the caller wants to wait for pending thumbnails,
5609                    // it ain't gonna get them.
5610                    try {
5611                        receiver.finished();
5612                    } catch (RemoteException ex) {
5613                    }
5614                }
5615                String msg = "Permission Denial: getTasks() from pid="
5616                        + Binder.getCallingPid()
5617                        + ", uid=" + Binder.getCallingUid()
5618                        + " requires " + android.Manifest.permission.GET_TASKS;
5619                Slog.w(TAG, msg);
5620                throw new SecurityException(msg);
5621            }
5622
5623            int pos = mMainStack.mHistory.size()-1;
5624            ActivityRecord next =
5625                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5626            ActivityRecord top = null;
5627            TaskRecord curTask = null;
5628            int numActivities = 0;
5629            int numRunning = 0;
5630            while (pos >= 0 && maxNum > 0) {
5631                final ActivityRecord r = next;
5632                pos--;
5633                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5634
5635                // Initialize state for next task if needed.
5636                if (top == null ||
5637                        (top.state == ActivityState.INITIALIZING
5638                            && top.task == r.task)) {
5639                    top = r;
5640                    curTask = r.task;
5641                    numActivities = numRunning = 0;
5642                }
5643
5644                // Add 'r' into the current task.
5645                numActivities++;
5646                if (r.app != null && r.app.thread != null) {
5647                    numRunning++;
5648                }
5649
5650                if (localLOGV) Slog.v(
5651                    TAG, r.intent.getComponent().flattenToShortString()
5652                    + ": task=" + r.task);
5653
5654                // If the next one is a different task, generate a new
5655                // TaskInfo entry for what we have.
5656                if (next == null || next.task != curTask) {
5657                    ActivityManager.RunningTaskInfo ci
5658                            = new ActivityManager.RunningTaskInfo();
5659                    ci.id = curTask.taskId;
5660                    ci.baseActivity = r.intent.getComponent();
5661                    ci.topActivity = top.intent.getComponent();
5662                    if (top.thumbHolder != null) {
5663                        ci.description = top.thumbHolder.lastDescription;
5664                    }
5665                    ci.numActivities = numActivities;
5666                    ci.numRunning = numRunning;
5667                    //System.out.println(
5668                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5669                    if (ci.thumbnail == null && receiver != null) {
5670                        if (localLOGV) Slog.v(
5671                            TAG, "State=" + top.state + "Idle=" + top.idle
5672                            + " app=" + top.app
5673                            + " thr=" + (top.app != null ? top.app.thread : null));
5674                        if (top.state == ActivityState.RESUMED
5675                                || top.state == ActivityState.PAUSING) {
5676                            if (top.idle && top.app != null
5677                                && top.app.thread != null) {
5678                                topRecord = top;
5679                                topThumbnail = top.app.thread;
5680                            } else {
5681                                top.thumbnailNeeded = true;
5682                            }
5683                        }
5684                        if (pending == null) {
5685                            pending = new PendingThumbnailsRecord(receiver);
5686                        }
5687                        pending.pendingRecords.add(top);
5688                    }
5689                    list.add(ci);
5690                    maxNum--;
5691                    top = null;
5692                }
5693            }
5694
5695            if (pending != null) {
5696                mPendingThumbnails.add(pending);
5697            }
5698        }
5699
5700        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5701
5702        if (topThumbnail != null) {
5703            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5704            try {
5705                topThumbnail.requestThumbnail(topRecord.appToken);
5706            } catch (Exception e) {
5707                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5708                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5709            }
5710        }
5711
5712        if (pending == null && receiver != null) {
5713            // In this case all thumbnails were available and the client
5714            // is being asked to be told when the remaining ones come in...
5715            // which is unusually, since the top-most currently running
5716            // activity should never have a canned thumbnail!  Oh well.
5717            try {
5718                receiver.finished();
5719            } catch (RemoteException ex) {
5720            }
5721        }
5722
5723        return list;
5724    }
5725
5726    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5727            int flags, int userId) {
5728        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5729                false, true, "getRecentTasks", null);
5730
5731        synchronized (this) {
5732            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5733                    "getRecentTasks()");
5734            final boolean detailed = checkCallingPermission(
5735                    android.Manifest.permission.GET_DETAILED_TASKS)
5736                    == PackageManager.PERMISSION_GRANTED;
5737
5738            IPackageManager pm = AppGlobals.getPackageManager();
5739
5740            final int N = mRecentTasks.size();
5741            ArrayList<ActivityManager.RecentTaskInfo> res
5742                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5743                            maxNum < N ? maxNum : N);
5744            for (int i=0; i<N && maxNum > 0; i++) {
5745                TaskRecord tr = mRecentTasks.get(i);
5746                // Only add calling user's recent tasks
5747                if (tr.userId != userId) continue;
5748                // Return the entry if desired by the caller.  We always return
5749                // the first entry, because callers always expect this to be the
5750                // foreground app.  We may filter others if the caller has
5751                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5752                // we should exclude the entry.
5753
5754                if (i == 0
5755                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5756                        || (tr.intent == null)
5757                        || ((tr.intent.getFlags()
5758                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5759                    ActivityManager.RecentTaskInfo rti
5760                            = new ActivityManager.RecentTaskInfo();
5761                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5762                    rti.persistentId = tr.taskId;
5763                    rti.baseIntent = new Intent(
5764                            tr.intent != null ? tr.intent : tr.affinityIntent);
5765                    if (!detailed) {
5766                        rti.baseIntent.replaceExtras((Bundle)null);
5767                    }
5768                    rti.origActivity = tr.origActivity;
5769                    rti.description = tr.lastDescription;
5770
5771                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5772                        // Check whether this activity is currently available.
5773                        try {
5774                            if (rti.origActivity != null) {
5775                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5776                                        == null) {
5777                                    continue;
5778                                }
5779                            } else if (rti.baseIntent != null) {
5780                                if (pm.queryIntentActivities(rti.baseIntent,
5781                                        null, 0, userId) == null) {
5782                                    continue;
5783                                }
5784                            }
5785                        } catch (RemoteException e) {
5786                            // Will never happen.
5787                        }
5788                    }
5789
5790                    res.add(rti);
5791                    maxNum--;
5792                }
5793            }
5794            return res;
5795        }
5796    }
5797
5798    private TaskRecord taskForIdLocked(int id) {
5799        final int N = mRecentTasks.size();
5800        for (int i=0; i<N; i++) {
5801            TaskRecord tr = mRecentTasks.get(i);
5802            if (tr.taskId == id) {
5803                return tr;
5804            }
5805        }
5806        return null;
5807    }
5808
5809    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5810        synchronized (this) {
5811            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5812                    "getTaskThumbnails()");
5813            TaskRecord tr = taskForIdLocked(id);
5814            if (tr != null) {
5815                return mMainStack.getTaskThumbnailsLocked(tr);
5816            }
5817        }
5818        return null;
5819    }
5820
5821    public Bitmap getTaskTopThumbnail(int id) {
5822        synchronized (this) {
5823            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5824                    "getTaskTopThumbnail()");
5825            TaskRecord tr = taskForIdLocked(id);
5826            if (tr != null) {
5827                return mMainStack.getTaskTopThumbnailLocked(tr);
5828            }
5829        }
5830        return null;
5831    }
5832
5833    public boolean removeSubTask(int taskId, int subTaskIndex) {
5834        synchronized (this) {
5835            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5836                    "removeSubTask()");
5837            long ident = Binder.clearCallingIdentity();
5838            try {
5839                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5840                        true) != null;
5841            } finally {
5842                Binder.restoreCallingIdentity(ident);
5843            }
5844        }
5845    }
5846
5847    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5848        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5849        Intent baseIntent = new Intent(
5850                tr.intent != null ? tr.intent : tr.affinityIntent);
5851        ComponentName component = baseIntent.getComponent();
5852        if (component == null) {
5853            Slog.w(TAG, "Now component for base intent of task: " + tr);
5854            return;
5855        }
5856
5857        // Find any running services associated with this app.
5858        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5859
5860        if (killProcesses) {
5861            // Find any running processes associated with this app.
5862            final String pkg = component.getPackageName();
5863            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5864            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5865            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5866                for (int i=0; i<uids.size(); i++) {
5867                    ProcessRecord proc = uids.valueAt(i);
5868                    if (proc.userId != tr.userId) {
5869                        continue;
5870                    }
5871                    if (!proc.pkgList.contains(pkg)) {
5872                        continue;
5873                    }
5874                    procs.add(proc);
5875                }
5876            }
5877
5878            // Kill the running processes.
5879            for (int i=0; i<procs.size(); i++) {
5880                ProcessRecord pr = procs.get(i);
5881                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5882                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5883                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5884                            pr.processName, pr.setAdj, "remove task");
5885                    pr.killedBackground = true;
5886                    Process.killProcessQuiet(pr.pid);
5887                } else {
5888                    pr.waitingToKill = "remove task";
5889                }
5890            }
5891        }
5892    }
5893
5894    public boolean removeTask(int taskId, int flags) {
5895        synchronized (this) {
5896            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5897                    "removeTask()");
5898            long ident = Binder.clearCallingIdentity();
5899            try {
5900                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5901                        false);
5902                if (r != null) {
5903                    mRecentTasks.remove(r.task);
5904                    cleanUpRemovedTaskLocked(r.task, flags);
5905                    return true;
5906                } else {
5907                    TaskRecord tr = null;
5908                    int i=0;
5909                    while (i < mRecentTasks.size()) {
5910                        TaskRecord t = mRecentTasks.get(i);
5911                        if (t.taskId == taskId) {
5912                            tr = t;
5913                            break;
5914                        }
5915                        i++;
5916                    }
5917                    if (tr != null) {
5918                        if (tr.numActivities <= 0) {
5919                            // Caller is just removing a recent task that is
5920                            // not actively running.  That is easy!
5921                            mRecentTasks.remove(i);
5922                            cleanUpRemovedTaskLocked(tr, flags);
5923                            return true;
5924                        } else {
5925                            Slog.w(TAG, "removeTask: task " + taskId
5926                                    + " does not have activities to remove, "
5927                                    + " but numActivities=" + tr.numActivities
5928                                    + ": " + tr);
5929                        }
5930                    }
5931                }
5932            } finally {
5933                Binder.restoreCallingIdentity(ident);
5934            }
5935        }
5936        return false;
5937    }
5938
5939    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5940        int j;
5941        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5942        TaskRecord jt = startTask;
5943
5944        // First look backwards
5945        for (j=startIndex-1; j>=0; j--) {
5946            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5947            if (r.task != jt) {
5948                jt = r.task;
5949                if (affinity.equals(jt.affinity)) {
5950                    return j;
5951                }
5952            }
5953        }
5954
5955        // Now look forwards
5956        final int N = mMainStack.mHistory.size();
5957        jt = startTask;
5958        for (j=startIndex+1; j<N; j++) {
5959            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5960            if (r.task != jt) {
5961                if (affinity.equals(jt.affinity)) {
5962                    return j;
5963                }
5964                jt = r.task;
5965            }
5966        }
5967
5968        // Might it be at the top?
5969        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5970            return N-1;
5971        }
5972
5973        return -1;
5974    }
5975
5976    /**
5977     * TODO: Add mController hook
5978     */
5979    public void moveTaskToFront(int task, int flags, Bundle options) {
5980        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5981                "moveTaskToFront()");
5982
5983        synchronized(this) {
5984            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5985                    Binder.getCallingUid(), "Task to front")) {
5986                ActivityOptions.abort(options);
5987                return;
5988            }
5989            final long origId = Binder.clearCallingIdentity();
5990            try {
5991                TaskRecord tr = taskForIdLocked(task);
5992                if (tr != null) {
5993                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5994                        mMainStack.mUserLeaving = true;
5995                    }
5996                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5997                        // Caller wants the home activity moved with it.  To accomplish this,
5998                        // we'll just move the home task to the top first.
5999                        mMainStack.moveHomeToFrontLocked();
6000                    }
6001                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6002                    return;
6003                }
6004                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6005                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6006                    if (hr.task.taskId == task) {
6007                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6008                            mMainStack.mUserLeaving = true;
6009                        }
6010                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6011                            // Caller wants the home activity moved with it.  To accomplish this,
6012                            // we'll just move the home task to the top first.
6013                            mMainStack.moveHomeToFrontLocked();
6014                        }
6015                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6016                        return;
6017                    }
6018                }
6019            } finally {
6020                Binder.restoreCallingIdentity(origId);
6021            }
6022            ActivityOptions.abort(options);
6023        }
6024    }
6025
6026    public void moveTaskToBack(int task) {
6027        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6028                "moveTaskToBack()");
6029
6030        synchronized(this) {
6031            if (mMainStack.mResumedActivity != null
6032                    && mMainStack.mResumedActivity.task.taskId == task) {
6033                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6034                        Binder.getCallingUid(), "Task to back")) {
6035                    return;
6036                }
6037            }
6038            final long origId = Binder.clearCallingIdentity();
6039            mMainStack.moveTaskToBackLocked(task, null);
6040            Binder.restoreCallingIdentity(origId);
6041        }
6042    }
6043
6044    /**
6045     * Moves an activity, and all of the other activities within the same task, to the bottom
6046     * of the history stack.  The activity's order within the task is unchanged.
6047     *
6048     * @param token A reference to the activity we wish to move
6049     * @param nonRoot If false then this only works if the activity is the root
6050     *                of a task; if true it will work for any activity in a task.
6051     * @return Returns true if the move completed, false if not.
6052     */
6053    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6054        enforceNotIsolatedCaller("moveActivityTaskToBack");
6055        synchronized(this) {
6056            final long origId = Binder.clearCallingIdentity();
6057            int taskId = getTaskForActivityLocked(token, !nonRoot);
6058            if (taskId >= 0) {
6059                return mMainStack.moveTaskToBackLocked(taskId, null);
6060            }
6061            Binder.restoreCallingIdentity(origId);
6062        }
6063        return false;
6064    }
6065
6066    public void moveTaskBackwards(int task) {
6067        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6068                "moveTaskBackwards()");
6069
6070        synchronized(this) {
6071            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6072                    Binder.getCallingUid(), "Task backwards")) {
6073                return;
6074            }
6075            final long origId = Binder.clearCallingIdentity();
6076            moveTaskBackwardsLocked(task);
6077            Binder.restoreCallingIdentity(origId);
6078        }
6079    }
6080
6081    private final void moveTaskBackwardsLocked(int task) {
6082        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6083    }
6084
6085    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6086        synchronized(this) {
6087            return getTaskForActivityLocked(token, onlyRoot);
6088        }
6089    }
6090
6091    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6092        final int N = mMainStack.mHistory.size();
6093        TaskRecord lastTask = null;
6094        for (int i=0; i<N; i++) {
6095            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6096            if (r.appToken == token) {
6097                if (!onlyRoot || lastTask != r.task) {
6098                    return r.task.taskId;
6099                }
6100                return -1;
6101            }
6102            lastTask = r.task;
6103        }
6104
6105        return -1;
6106    }
6107
6108    // =========================================================
6109    // THUMBNAILS
6110    // =========================================================
6111
6112    public void reportThumbnail(IBinder token,
6113            Bitmap thumbnail, CharSequence description) {
6114        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6115        final long origId = Binder.clearCallingIdentity();
6116        sendPendingThumbnail(null, token, thumbnail, description, true);
6117        Binder.restoreCallingIdentity(origId);
6118    }
6119
6120    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6121            Bitmap thumbnail, CharSequence description, boolean always) {
6122        TaskRecord task = null;
6123        ArrayList receivers = null;
6124
6125        //System.out.println("Send pending thumbnail: " + r);
6126
6127        synchronized(this) {
6128            if (r == null) {
6129                r = mMainStack.isInStackLocked(token);
6130                if (r == null) {
6131                    return;
6132                }
6133            }
6134            if (thumbnail == null && r.thumbHolder != null) {
6135                thumbnail = r.thumbHolder.lastThumbnail;
6136                description = r.thumbHolder.lastDescription;
6137            }
6138            if (thumbnail == null && !always) {
6139                // If there is no thumbnail, and this entry is not actually
6140                // going away, then abort for now and pick up the next
6141                // thumbnail we get.
6142                return;
6143            }
6144            task = r.task;
6145
6146            int N = mPendingThumbnails.size();
6147            int i=0;
6148            while (i<N) {
6149                PendingThumbnailsRecord pr =
6150                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6151                //System.out.println("Looking in " + pr.pendingRecords);
6152                if (pr.pendingRecords.remove(r)) {
6153                    if (receivers == null) {
6154                        receivers = new ArrayList();
6155                    }
6156                    receivers.add(pr);
6157                    if (pr.pendingRecords.size() == 0) {
6158                        pr.finished = true;
6159                        mPendingThumbnails.remove(i);
6160                        N--;
6161                        continue;
6162                    }
6163                }
6164                i++;
6165            }
6166        }
6167
6168        if (receivers != null) {
6169            final int N = receivers.size();
6170            for (int i=0; i<N; i++) {
6171                try {
6172                    PendingThumbnailsRecord pr =
6173                        (PendingThumbnailsRecord)receivers.get(i);
6174                    pr.receiver.newThumbnail(
6175                        task != null ? task.taskId : -1, thumbnail, description);
6176                    if (pr.finished) {
6177                        pr.receiver.finished();
6178                    }
6179                } catch (Exception e) {
6180                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6181                }
6182            }
6183        }
6184    }
6185
6186    // =========================================================
6187    // CONTENT PROVIDERS
6188    // =========================================================
6189
6190    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6191        List<ProviderInfo> providers = null;
6192        try {
6193            providers = AppGlobals.getPackageManager().
6194                queryContentProviders(app.processName, app.uid,
6195                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6196        } catch (RemoteException ex) {
6197        }
6198        if (DEBUG_MU)
6199            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6200        int userId = app.userId;
6201        if (providers != null) {
6202            int N = providers.size();
6203            for (int i=0; i<N; i++) {
6204                ProviderInfo cpi =
6205                    (ProviderInfo)providers.get(i);
6206                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6207                        cpi.name, cpi.flags);
6208                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6209                    // This is a singleton provider, but a user besides the
6210                    // default user is asking to initialize a process it runs
6211                    // in...  well, no, it doesn't actually run in this process,
6212                    // it runs in the process of the default user.  Get rid of it.
6213                    providers.remove(i);
6214                    N--;
6215                    continue;
6216                }
6217
6218                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6219                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6220                if (cpr == null) {
6221                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6222                    mProviderMap.putProviderByClass(comp, cpr);
6223                }
6224                if (DEBUG_MU)
6225                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6226                app.pubProviders.put(cpi.name, cpr);
6227                app.addPackage(cpi.applicationInfo.packageName);
6228                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6229            }
6230        }
6231        return providers;
6232    }
6233
6234    /**
6235     * Check if {@link ProcessRecord} has a possible chance at accessing the
6236     * given {@link ProviderInfo}. Final permission checking is always done
6237     * in {@link ContentProvider}.
6238     */
6239    private final String checkContentProviderPermissionLocked(
6240            ProviderInfo cpi, ProcessRecord r) {
6241        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6242        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6243        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6244                cpi.applicationInfo.uid, cpi.exported)
6245                == PackageManager.PERMISSION_GRANTED) {
6246            return null;
6247        }
6248        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6249                cpi.applicationInfo.uid, cpi.exported)
6250                == PackageManager.PERMISSION_GRANTED) {
6251            return null;
6252        }
6253
6254        PathPermission[] pps = cpi.pathPermissions;
6255        if (pps != null) {
6256            int i = pps.length;
6257            while (i > 0) {
6258                i--;
6259                PathPermission pp = pps[i];
6260                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6261                        cpi.applicationInfo.uid, cpi.exported)
6262                        == PackageManager.PERMISSION_GRANTED) {
6263                    return null;
6264                }
6265                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6266                        cpi.applicationInfo.uid, cpi.exported)
6267                        == PackageManager.PERMISSION_GRANTED) {
6268                    return null;
6269                }
6270            }
6271        }
6272
6273        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6274        if (perms != null) {
6275            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6276                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6277                    return null;
6278                }
6279            }
6280        }
6281
6282        String msg;
6283        if (!cpi.exported) {
6284            msg = "Permission Denial: opening provider " + cpi.name
6285                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6286                    + ", uid=" + callingUid + ") that is not exported from uid "
6287                    + cpi.applicationInfo.uid;
6288        } else {
6289            msg = "Permission Denial: opening provider " + cpi.name
6290                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6291                    + ", uid=" + callingUid + ") requires "
6292                    + cpi.readPermission + " or " + cpi.writePermission;
6293        }
6294        Slog.w(TAG, msg);
6295        return msg;
6296    }
6297
6298    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6299            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6300        if (r != null) {
6301            for (int i=0; i<r.conProviders.size(); i++) {
6302                ContentProviderConnection conn = r.conProviders.get(i);
6303                if (conn.provider == cpr) {
6304                    if (DEBUG_PROVIDER) Slog.v(TAG,
6305                            "Adding provider requested by "
6306                            + r.processName + " from process "
6307                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6308                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6309                    if (stable) {
6310                        conn.stableCount++;
6311                        conn.numStableIncs++;
6312                    } else {
6313                        conn.unstableCount++;
6314                        conn.numUnstableIncs++;
6315                    }
6316                    return conn;
6317                }
6318            }
6319            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6320            if (stable) {
6321                conn.stableCount = 1;
6322                conn.numStableIncs = 1;
6323            } else {
6324                conn.unstableCount = 1;
6325                conn.numUnstableIncs = 1;
6326            }
6327            cpr.connections.add(conn);
6328            r.conProviders.add(conn);
6329            return conn;
6330        }
6331        cpr.addExternalProcessHandleLocked(externalProcessToken);
6332        return null;
6333    }
6334
6335    boolean decProviderCountLocked(ContentProviderConnection conn,
6336            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6337        if (conn != null) {
6338            cpr = conn.provider;
6339            if (DEBUG_PROVIDER) Slog.v(TAG,
6340                    "Removing provider requested by "
6341                    + conn.client.processName + " from process "
6342                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6343                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6344            if (stable) {
6345                conn.stableCount--;
6346            } else {
6347                conn.unstableCount--;
6348            }
6349            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6350                cpr.connections.remove(conn);
6351                conn.client.conProviders.remove(conn);
6352                return true;
6353            }
6354            return false;
6355        }
6356        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6357        return false;
6358    }
6359
6360    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6361            String name, IBinder token, boolean stable, int userId) {
6362        ContentProviderRecord cpr;
6363        ContentProviderConnection conn = null;
6364        ProviderInfo cpi = null;
6365
6366        synchronized(this) {
6367            ProcessRecord r = null;
6368            if (caller != null) {
6369                r = getRecordForAppLocked(caller);
6370                if (r == null) {
6371                    throw new SecurityException(
6372                            "Unable to find app for caller " + caller
6373                          + " (pid=" + Binder.getCallingPid()
6374                          + ") when getting content provider " + name);
6375                }
6376            }
6377
6378            // First check if this content provider has been published...
6379            cpr = mProviderMap.getProviderByName(name, userId);
6380            boolean providerRunning = cpr != null;
6381            if (providerRunning) {
6382                cpi = cpr.info;
6383                String msg;
6384                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6385                    throw new SecurityException(msg);
6386                }
6387
6388                if (r != null && cpr.canRunHere(r)) {
6389                    // This provider has been published or is in the process
6390                    // of being published...  but it is also allowed to run
6391                    // in the caller's process, so don't make a connection
6392                    // and just let the caller instantiate its own instance.
6393                    ContentProviderHolder holder = cpr.newHolder(null);
6394                    // don't give caller the provider object, it needs
6395                    // to make its own.
6396                    holder.provider = null;
6397                    return holder;
6398                }
6399
6400                final long origId = Binder.clearCallingIdentity();
6401
6402                // In this case the provider instance already exists, so we can
6403                // return it right away.
6404                conn = incProviderCountLocked(r, cpr, token, stable);
6405                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6406                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6407                        // If this is a perceptible app accessing the provider,
6408                        // make sure to count it as being accessed and thus
6409                        // back up on the LRU list.  This is good because
6410                        // content providers are often expensive to start.
6411                        updateLruProcessLocked(cpr.proc, false);
6412                    }
6413                }
6414
6415                if (cpr.proc != null) {
6416                    if (false) {
6417                        if (cpr.name.flattenToShortString().equals(
6418                                "com.android.providers.calendar/.CalendarProvider2")) {
6419                            Slog.v(TAG, "****************** KILLING "
6420                                + cpr.name.flattenToShortString());
6421                            Process.killProcess(cpr.proc.pid);
6422                        }
6423                    }
6424                    boolean success = updateOomAdjLocked(cpr.proc);
6425                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6426                    // NOTE: there is still a race here where a signal could be
6427                    // pending on the process even though we managed to update its
6428                    // adj level.  Not sure what to do about this, but at least
6429                    // the race is now smaller.
6430                    if (!success) {
6431                        // Uh oh...  it looks like the provider's process
6432                        // has been killed on us.  We need to wait for a new
6433                        // process to be started, and make sure its death
6434                        // doesn't kill our process.
6435                        Slog.i(TAG,
6436                                "Existing provider " + cpr.name.flattenToShortString()
6437                                + " is crashing; detaching " + r);
6438                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6439                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6440                        if (!lastRef) {
6441                            // This wasn't the last ref our process had on
6442                            // the provider...  we have now been killed, bail.
6443                            return null;
6444                        }
6445                        providerRunning = false;
6446                        conn = null;
6447                    }
6448                }
6449
6450                Binder.restoreCallingIdentity(origId);
6451            }
6452
6453            boolean singleton;
6454            if (!providerRunning) {
6455                try {
6456                    cpi = AppGlobals.getPackageManager().
6457                        resolveContentProvider(name,
6458                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6459                } catch (RemoteException ex) {
6460                }
6461                if (cpi == null) {
6462                    return null;
6463                }
6464                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6465                        cpi.name, cpi.flags);
6466                if (singleton) {
6467                    userId = 0;
6468                }
6469                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6470
6471                String msg;
6472                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6473                    throw new SecurityException(msg);
6474                }
6475
6476                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6477                        && !cpi.processName.equals("system")) {
6478                    // If this content provider does not run in the system
6479                    // process, and the system is not yet ready to run other
6480                    // processes, then fail fast instead of hanging.
6481                    throw new IllegalArgumentException(
6482                            "Attempt to launch content provider before system ready");
6483                }
6484
6485                // Make sure that the user who owns this provider is started.  If not,
6486                // we don't want to allow it to run.
6487                if (mStartedUsers.get(userId) == null) {
6488                    Slog.w(TAG, "Unable to launch app "
6489                            + cpi.applicationInfo.packageName + "/"
6490                            + cpi.applicationInfo.uid + " for provider "
6491                            + name + ": user " + userId + " is stopped");
6492                    return null;
6493                }
6494
6495                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6496                cpr = mProviderMap.getProviderByClass(comp, userId);
6497                final boolean firstClass = cpr == null;
6498                if (firstClass) {
6499                    try {
6500                        ApplicationInfo ai =
6501                            AppGlobals.getPackageManager().
6502                                getApplicationInfo(
6503                                        cpi.applicationInfo.packageName,
6504                                        STOCK_PM_FLAGS, userId);
6505                        if (ai == null) {
6506                            Slog.w(TAG, "No package info for content provider "
6507                                    + cpi.name);
6508                            return null;
6509                        }
6510                        ai = getAppInfoForUser(ai, userId);
6511                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6512                    } catch (RemoteException ex) {
6513                        // pm is in same process, this will never happen.
6514                    }
6515                }
6516
6517                if (r != null && cpr.canRunHere(r)) {
6518                    // If this is a multiprocess provider, then just return its
6519                    // info and allow the caller to instantiate it.  Only do
6520                    // this if the provider is the same user as the caller's
6521                    // process, or can run as root (so can be in any process).
6522                    return cpr.newHolder(null);
6523                }
6524
6525                if (DEBUG_PROVIDER) {
6526                    RuntimeException e = new RuntimeException("here");
6527                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6528                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6529                }
6530
6531                // This is single process, and our app is now connecting to it.
6532                // See if we are already in the process of launching this
6533                // provider.
6534                final int N = mLaunchingProviders.size();
6535                int i;
6536                for (i=0; i<N; i++) {
6537                    if (mLaunchingProviders.get(i) == cpr) {
6538                        break;
6539                    }
6540                }
6541
6542                // If the provider is not already being launched, then get it
6543                // started.
6544                if (i >= N) {
6545                    final long origId = Binder.clearCallingIdentity();
6546
6547                    try {
6548                        // Content provider is now in use, its package can't be stopped.
6549                        try {
6550                            AppGlobals.getPackageManager().setPackageStoppedState(
6551                                    cpr.appInfo.packageName, false, userId);
6552                        } catch (RemoteException e) {
6553                        } catch (IllegalArgumentException e) {
6554                            Slog.w(TAG, "Failed trying to unstop package "
6555                                    + cpr.appInfo.packageName + ": " + e);
6556                        }
6557
6558                        ProcessRecord proc = startProcessLocked(cpi.processName,
6559                                cpr.appInfo, false, 0, "content provider",
6560                                new ComponentName(cpi.applicationInfo.packageName,
6561                                        cpi.name), false, false);
6562                        if (proc == null) {
6563                            Slog.w(TAG, "Unable to launch app "
6564                                    + cpi.applicationInfo.packageName + "/"
6565                                    + cpi.applicationInfo.uid + " for provider "
6566                                    + name + ": process is bad");
6567                            return null;
6568                        }
6569                        cpr.launchingApp = proc;
6570                        mLaunchingProviders.add(cpr);
6571                    } finally {
6572                        Binder.restoreCallingIdentity(origId);
6573                    }
6574                }
6575
6576                // Make sure the provider is published (the same provider class
6577                // may be published under multiple names).
6578                if (firstClass) {
6579                    mProviderMap.putProviderByClass(comp, cpr);
6580                }
6581
6582                mProviderMap.putProviderByName(name, cpr);
6583                conn = incProviderCountLocked(r, cpr, token, stable);
6584                if (conn != null) {
6585                    conn.waiting = true;
6586                }
6587            }
6588        }
6589
6590        // Wait for the provider to be published...
6591        synchronized (cpr) {
6592            while (cpr.provider == null) {
6593                if (cpr.launchingApp == null) {
6594                    Slog.w(TAG, "Unable to launch app "
6595                            + cpi.applicationInfo.packageName + "/"
6596                            + cpi.applicationInfo.uid + " for provider "
6597                            + name + ": launching app became null");
6598                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6599                            UserHandle.getUserId(cpi.applicationInfo.uid),
6600                            cpi.applicationInfo.packageName,
6601                            cpi.applicationInfo.uid, name);
6602                    return null;
6603                }
6604                try {
6605                    if (DEBUG_MU) {
6606                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6607                                + cpr.launchingApp);
6608                    }
6609                    if (conn != null) {
6610                        conn.waiting = true;
6611                    }
6612                    cpr.wait();
6613                } catch (InterruptedException ex) {
6614                } finally {
6615                    if (conn != null) {
6616                        conn.waiting = false;
6617                    }
6618                }
6619            }
6620        }
6621        return cpr != null ? cpr.newHolder(conn) : null;
6622    }
6623
6624    public final ContentProviderHolder getContentProvider(
6625            IApplicationThread caller, String name, int userId, boolean stable) {
6626        enforceNotIsolatedCaller("getContentProvider");
6627        if (caller == null) {
6628            String msg = "null IApplicationThread when getting content provider "
6629                    + name;
6630            Slog.w(TAG, msg);
6631            throw new SecurityException(msg);
6632        }
6633
6634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6635                false, true, "getContentProvider", null);
6636        return getContentProviderImpl(caller, name, null, stable, userId);
6637    }
6638
6639    public ContentProviderHolder getContentProviderExternal(
6640            String name, int userId, IBinder token) {
6641        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6642            "Do not have permission in call getContentProviderExternal()");
6643        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6644                false, true, "getContentProvider", null);
6645        return getContentProviderExternalUnchecked(name, token, userId);
6646    }
6647
6648    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6649            IBinder token, int userId) {
6650        return getContentProviderImpl(null, name, token, true, userId);
6651    }
6652
6653    /**
6654     * Drop a content provider from a ProcessRecord's bookkeeping
6655     * @param cpr
6656     */
6657    public void removeContentProvider(IBinder connection, boolean stable) {
6658        enforceNotIsolatedCaller("removeContentProvider");
6659        synchronized (this) {
6660            ContentProviderConnection conn;
6661            try {
6662                conn = (ContentProviderConnection)connection;
6663            } catch (ClassCastException e) {
6664                String msg ="removeContentProvider: " + connection
6665                        + " not a ContentProviderConnection";
6666                Slog.w(TAG, msg);
6667                throw new IllegalArgumentException(msg);
6668            }
6669            if (conn == null) {
6670                throw new NullPointerException("connection is null");
6671            }
6672            if (decProviderCountLocked(conn, null, null, stable)) {
6673                updateOomAdjLocked();
6674            }
6675        }
6676    }
6677
6678    public void removeContentProviderExternal(String name, IBinder token) {
6679        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6680            "Do not have permission in call removeContentProviderExternal()");
6681        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6682    }
6683
6684    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6685        synchronized (this) {
6686            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6687            if(cpr == null) {
6688                //remove from mProvidersByClass
6689                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6690                return;
6691            }
6692
6693            //update content provider record entry info
6694            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6695            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6696            if (localCpr.hasExternalProcessHandles()) {
6697                if (localCpr.removeExternalProcessHandleLocked(token)) {
6698                    updateOomAdjLocked();
6699                } else {
6700                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6701                            + " with no external reference for token: "
6702                            + token + ".");
6703                }
6704            } else {
6705                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6706                        + " with no external references.");
6707            }
6708        }
6709    }
6710
6711    public final void publishContentProviders(IApplicationThread caller,
6712            List<ContentProviderHolder> providers) {
6713        if (providers == null) {
6714            return;
6715        }
6716
6717        enforceNotIsolatedCaller("publishContentProviders");
6718        synchronized (this) {
6719            final ProcessRecord r = getRecordForAppLocked(caller);
6720            if (DEBUG_MU)
6721                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6722            if (r == null) {
6723                throw new SecurityException(
6724                        "Unable to find app for caller " + caller
6725                      + " (pid=" + Binder.getCallingPid()
6726                      + ") when publishing content providers");
6727            }
6728
6729            final long origId = Binder.clearCallingIdentity();
6730
6731            final int N = providers.size();
6732            for (int i=0; i<N; i++) {
6733                ContentProviderHolder src = providers.get(i);
6734                if (src == null || src.info == null || src.provider == null) {
6735                    continue;
6736                }
6737                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6738                if (DEBUG_MU)
6739                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6740                if (dst != null) {
6741                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6742                    mProviderMap.putProviderByClass(comp, dst);
6743                    String names[] = dst.info.authority.split(";");
6744                    for (int j = 0; j < names.length; j++) {
6745                        mProviderMap.putProviderByName(names[j], dst);
6746                    }
6747
6748                    int NL = mLaunchingProviders.size();
6749                    int j;
6750                    for (j=0; j<NL; j++) {
6751                        if (mLaunchingProviders.get(j) == dst) {
6752                            mLaunchingProviders.remove(j);
6753                            j--;
6754                            NL--;
6755                        }
6756                    }
6757                    synchronized (dst) {
6758                        dst.provider = src.provider;
6759                        dst.proc = r;
6760                        dst.notifyAll();
6761                    }
6762                    updateOomAdjLocked(r);
6763                }
6764            }
6765
6766            Binder.restoreCallingIdentity(origId);
6767        }
6768    }
6769
6770    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6771        ContentProviderConnection conn;
6772        try {
6773            conn = (ContentProviderConnection)connection;
6774        } catch (ClassCastException e) {
6775            String msg ="refContentProvider: " + connection
6776                    + " not a ContentProviderConnection";
6777            Slog.w(TAG, msg);
6778            throw new IllegalArgumentException(msg);
6779        }
6780        if (conn == null) {
6781            throw new NullPointerException("connection is null");
6782        }
6783
6784        synchronized (this) {
6785            if (stable > 0) {
6786                conn.numStableIncs += stable;
6787            }
6788            stable = conn.stableCount + stable;
6789            if (stable < 0) {
6790                throw new IllegalStateException("stableCount < 0: " + stable);
6791            }
6792
6793            if (unstable > 0) {
6794                conn.numUnstableIncs += unstable;
6795            }
6796            unstable = conn.unstableCount + unstable;
6797            if (unstable < 0) {
6798                throw new IllegalStateException("unstableCount < 0: " + unstable);
6799            }
6800
6801            if ((stable+unstable) <= 0) {
6802                throw new IllegalStateException("ref counts can't go to zero here: stable="
6803                        + stable + " unstable=" + unstable);
6804            }
6805            conn.stableCount = stable;
6806            conn.unstableCount = unstable;
6807            return !conn.dead;
6808        }
6809    }
6810
6811    public void unstableProviderDied(IBinder connection) {
6812        ContentProviderConnection conn;
6813        try {
6814            conn = (ContentProviderConnection)connection;
6815        } catch (ClassCastException e) {
6816            String msg ="refContentProvider: " + connection
6817                    + " not a ContentProviderConnection";
6818            Slog.w(TAG, msg);
6819            throw new IllegalArgumentException(msg);
6820        }
6821        if (conn == null) {
6822            throw new NullPointerException("connection is null");
6823        }
6824
6825        // Safely retrieve the content provider associated with the connection.
6826        IContentProvider provider;
6827        synchronized (this) {
6828            provider = conn.provider.provider;
6829        }
6830
6831        if (provider == null) {
6832            // Um, yeah, we're way ahead of you.
6833            return;
6834        }
6835
6836        // Make sure the caller is being honest with us.
6837        if (provider.asBinder().pingBinder()) {
6838            // Er, no, still looks good to us.
6839            synchronized (this) {
6840                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6841                        + " says " + conn + " died, but we don't agree");
6842                return;
6843            }
6844        }
6845
6846        // Well look at that!  It's dead!
6847        synchronized (this) {
6848            if (conn.provider.provider != provider) {
6849                // But something changed...  good enough.
6850                return;
6851            }
6852
6853            ProcessRecord proc = conn.provider.proc;
6854            if (proc == null || proc.thread == null) {
6855                // Seems like the process is already cleaned up.
6856                return;
6857            }
6858
6859            // As far as we're concerned, this is just like receiving a
6860            // death notification...  just a bit prematurely.
6861            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6862                    + ") early provider death");
6863            final long ident = Binder.clearCallingIdentity();
6864            try {
6865                appDiedLocked(proc, proc.pid, proc.thread);
6866            } finally {
6867                Binder.restoreCallingIdentity(ident);
6868            }
6869        }
6870    }
6871
6872    public static final void installSystemProviders() {
6873        List<ProviderInfo> providers;
6874        synchronized (mSelf) {
6875            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6876            providers = mSelf.generateApplicationProvidersLocked(app);
6877            if (providers != null) {
6878                for (int i=providers.size()-1; i>=0; i--) {
6879                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6880                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6881                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6882                                + ": not system .apk");
6883                        providers.remove(i);
6884                    }
6885                }
6886            }
6887        }
6888        if (providers != null) {
6889            mSystemThread.installSystemProviders(providers);
6890        }
6891
6892        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6893
6894        mSelf.mUsageStatsService.monitorPackages();
6895    }
6896
6897    /**
6898     * Allows app to retrieve the MIME type of a URI without having permission
6899     * to access its content provider.
6900     *
6901     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6902     *
6903     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6904     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6905     */
6906    public String getProviderMimeType(Uri uri, int userId) {
6907        enforceNotIsolatedCaller("getProviderMimeType");
6908        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6909                userId, false, true, "getProviderMimeType", null);
6910        final String name = uri.getAuthority();
6911        final long ident = Binder.clearCallingIdentity();
6912        ContentProviderHolder holder = null;
6913
6914        try {
6915            holder = getContentProviderExternalUnchecked(name, null, userId);
6916            if (holder != null) {
6917                return holder.provider.getType(uri);
6918            }
6919        } catch (RemoteException e) {
6920            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6921            return null;
6922        } finally {
6923            if (holder != null) {
6924                removeContentProviderExternalUnchecked(name, null, userId);
6925            }
6926            Binder.restoreCallingIdentity(ident);
6927        }
6928
6929        return null;
6930    }
6931
6932    // =========================================================
6933    // GLOBAL MANAGEMENT
6934    // =========================================================
6935
6936    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6937            ApplicationInfo info, String customProcess, boolean isolated) {
6938        String proc = customProcess != null ? customProcess : info.processName;
6939        BatteryStatsImpl.Uid.Proc ps = null;
6940        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6941        int uid = info.uid;
6942        if (isolated) {
6943            int userId = UserHandle.getUserId(uid);
6944            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6945            uid = 0;
6946            while (true) {
6947                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6948                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6949                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6950                }
6951                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6952                mNextIsolatedProcessUid++;
6953                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6954                    // No process for this uid, use it.
6955                    break;
6956                }
6957                stepsLeft--;
6958                if (stepsLeft <= 0) {
6959                    return null;
6960                }
6961            }
6962        }
6963        synchronized (stats) {
6964            ps = stats.getProcessStatsLocked(info.uid, proc);
6965        }
6966        return new ProcessRecord(ps, thread, info, proc, uid);
6967    }
6968
6969    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6970        ProcessRecord app;
6971        if (!isolated) {
6972            app = getProcessRecordLocked(info.processName, info.uid);
6973        } else {
6974            app = null;
6975        }
6976
6977        if (app == null) {
6978            app = newProcessRecordLocked(null, info, null, isolated);
6979            mProcessNames.put(info.processName, app.uid, app);
6980            if (isolated) {
6981                mIsolatedProcesses.put(app.uid, app);
6982            }
6983            updateLruProcessLocked(app, true);
6984        }
6985
6986        // This package really, really can not be stopped.
6987        try {
6988            AppGlobals.getPackageManager().setPackageStoppedState(
6989                    info.packageName, false, UserHandle.getUserId(app.uid));
6990        } catch (RemoteException e) {
6991        } catch (IllegalArgumentException e) {
6992            Slog.w(TAG, "Failed trying to unstop package "
6993                    + info.packageName + ": " + e);
6994        }
6995
6996        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6997                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6998            app.persistent = true;
6999            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7000        }
7001        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7002            mPersistentStartingProcesses.add(app);
7003            startProcessLocked(app, "added application", app.processName);
7004        }
7005
7006        return app;
7007    }
7008
7009    public void unhandledBack() {
7010        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7011                "unhandledBack()");
7012
7013        synchronized(this) {
7014            int count = mMainStack.mHistory.size();
7015            if (DEBUG_SWITCH) Slog.d(
7016                TAG, "Performing unhandledBack(): stack size = " + count);
7017            if (count > 1) {
7018                final long origId = Binder.clearCallingIdentity();
7019                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7020                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7021                Binder.restoreCallingIdentity(origId);
7022            }
7023        }
7024    }
7025
7026    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7027        enforceNotIsolatedCaller("openContentUri");
7028        final int userId = UserHandle.getCallingUserId();
7029        String name = uri.getAuthority();
7030        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7031        ParcelFileDescriptor pfd = null;
7032        if (cph != null) {
7033            // We record the binder invoker's uid in thread-local storage before
7034            // going to the content provider to open the file.  Later, in the code
7035            // that handles all permissions checks, we look for this uid and use
7036            // that rather than the Activity Manager's own uid.  The effect is that
7037            // we do the check against the caller's permissions even though it looks
7038            // to the content provider like the Activity Manager itself is making
7039            // the request.
7040            sCallerIdentity.set(new Identity(
7041                    Binder.getCallingPid(), Binder.getCallingUid()));
7042            try {
7043                pfd = cph.provider.openFile(uri, "r");
7044            } catch (FileNotFoundException e) {
7045                // do nothing; pfd will be returned null
7046            } finally {
7047                // Ensure that whatever happens, we clean up the identity state
7048                sCallerIdentity.remove();
7049            }
7050
7051            // We've got the fd now, so we're done with the provider.
7052            removeContentProviderExternalUnchecked(name, null, userId);
7053        } else {
7054            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7055        }
7056        return pfd;
7057    }
7058
7059    // Actually is sleeping or shutting down or whatever else in the future
7060    // is an inactive state.
7061    public boolean isSleeping() {
7062        return mSleeping || mShuttingDown;
7063    }
7064
7065    public void goingToSleep() {
7066        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7067                != PackageManager.PERMISSION_GRANTED) {
7068            throw new SecurityException("Requires permission "
7069                    + android.Manifest.permission.DEVICE_POWER);
7070        }
7071
7072        synchronized(this) {
7073            mWentToSleep = true;
7074            updateEventDispatchingLocked();
7075
7076            if (!mSleeping) {
7077                mSleeping = true;
7078                mMainStack.stopIfSleepingLocked();
7079
7080                // Initialize the wake times of all processes.
7081                checkExcessivePowerUsageLocked(false);
7082                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7083                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7084                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7085            }
7086        }
7087    }
7088
7089    public boolean shutdown(int timeout) {
7090        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7091                != PackageManager.PERMISSION_GRANTED) {
7092            throw new SecurityException("Requires permission "
7093                    + android.Manifest.permission.SHUTDOWN);
7094        }
7095
7096        boolean timedout = false;
7097
7098        synchronized(this) {
7099            mShuttingDown = true;
7100            updateEventDispatchingLocked();
7101
7102            if (mMainStack.mResumedActivity != null) {
7103                mMainStack.stopIfSleepingLocked();
7104                final long endTime = System.currentTimeMillis() + timeout;
7105                while (mMainStack.mResumedActivity != null
7106                        || mMainStack.mPausingActivity != null) {
7107                    long delay = endTime - System.currentTimeMillis();
7108                    if (delay <= 0) {
7109                        Slog.w(TAG, "Activity manager shutdown timed out");
7110                        timedout = true;
7111                        break;
7112                    }
7113                    try {
7114                        this.wait();
7115                    } catch (InterruptedException e) {
7116                    }
7117                }
7118            }
7119        }
7120
7121        mUsageStatsService.shutdown();
7122        mBatteryStatsService.shutdown();
7123
7124        return timedout;
7125    }
7126
7127    public final void activitySlept(IBinder token) {
7128        if (localLOGV) Slog.v(
7129            TAG, "Activity slept: token=" + token);
7130
7131        ActivityRecord r = null;
7132
7133        final long origId = Binder.clearCallingIdentity();
7134
7135        synchronized (this) {
7136            r = mMainStack.isInStackLocked(token);
7137            if (r != null) {
7138                mMainStack.activitySleptLocked(r);
7139            }
7140        }
7141
7142        Binder.restoreCallingIdentity(origId);
7143    }
7144
7145    private void comeOutOfSleepIfNeededLocked() {
7146        if (!mWentToSleep && !mLockScreenShown) {
7147            if (mSleeping) {
7148                mSleeping = false;
7149                mMainStack.awakeFromSleepingLocked();
7150                mMainStack.resumeTopActivityLocked(null);
7151            }
7152        }
7153    }
7154
7155    public void wakingUp() {
7156        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7157                != PackageManager.PERMISSION_GRANTED) {
7158            throw new SecurityException("Requires permission "
7159                    + android.Manifest.permission.DEVICE_POWER);
7160        }
7161
7162        synchronized(this) {
7163            mWentToSleep = false;
7164            updateEventDispatchingLocked();
7165            comeOutOfSleepIfNeededLocked();
7166        }
7167    }
7168
7169    private void updateEventDispatchingLocked() {
7170        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7171    }
7172
7173    public void setLockScreenShown(boolean shown) {
7174        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7175                != PackageManager.PERMISSION_GRANTED) {
7176            throw new SecurityException("Requires permission "
7177                    + android.Manifest.permission.DEVICE_POWER);
7178        }
7179
7180        synchronized(this) {
7181            mLockScreenShown = shown;
7182            comeOutOfSleepIfNeededLocked();
7183        }
7184    }
7185
7186    public void stopAppSwitches() {
7187        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7188                != PackageManager.PERMISSION_GRANTED) {
7189            throw new SecurityException("Requires permission "
7190                    + android.Manifest.permission.STOP_APP_SWITCHES);
7191        }
7192
7193        synchronized(this) {
7194            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7195                    + APP_SWITCH_DELAY_TIME;
7196            mDidAppSwitch = false;
7197            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7198            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7199            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7200        }
7201    }
7202
7203    public void resumeAppSwitches() {
7204        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7205                != PackageManager.PERMISSION_GRANTED) {
7206            throw new SecurityException("Requires permission "
7207                    + android.Manifest.permission.STOP_APP_SWITCHES);
7208        }
7209
7210        synchronized(this) {
7211            // Note that we don't execute any pending app switches... we will
7212            // let those wait until either the timeout, or the next start
7213            // activity request.
7214            mAppSwitchesAllowedTime = 0;
7215        }
7216    }
7217
7218    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7219            String name) {
7220        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7221            return true;
7222        }
7223
7224        final int perm = checkComponentPermission(
7225                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7226                callingUid, -1, true);
7227        if (perm == PackageManager.PERMISSION_GRANTED) {
7228            return true;
7229        }
7230
7231        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7232        return false;
7233    }
7234
7235    public void setDebugApp(String packageName, boolean waitForDebugger,
7236            boolean persistent) {
7237        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7238                "setDebugApp()");
7239
7240        // Note that this is not really thread safe if there are multiple
7241        // callers into it at the same time, but that's not a situation we
7242        // care about.
7243        if (persistent) {
7244            final ContentResolver resolver = mContext.getContentResolver();
7245            Settings.System.putString(
7246                resolver, Settings.System.DEBUG_APP,
7247                packageName);
7248            Settings.System.putInt(
7249                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7250                waitForDebugger ? 1 : 0);
7251        }
7252
7253        synchronized (this) {
7254            if (!persistent) {
7255                mOrigDebugApp = mDebugApp;
7256                mOrigWaitForDebugger = mWaitForDebugger;
7257            }
7258            mDebugApp = packageName;
7259            mWaitForDebugger = waitForDebugger;
7260            mDebugTransient = !persistent;
7261            if (packageName != null) {
7262                final long origId = Binder.clearCallingIdentity();
7263                forceStopPackageLocked(packageName, -1, false, false, true, true,
7264                        UserHandle.USER_ALL);
7265                Binder.restoreCallingIdentity(origId);
7266            }
7267        }
7268    }
7269
7270    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7271        synchronized (this) {
7272            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7273            if (!isDebuggable) {
7274                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7275                    throw new SecurityException("Process not debuggable: " + app.packageName);
7276                }
7277            }
7278
7279            mOpenGlTraceApp = processName;
7280        }
7281    }
7282
7283    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7284            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7285        synchronized (this) {
7286            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7287            if (!isDebuggable) {
7288                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7289                    throw new SecurityException("Process not debuggable: " + app.packageName);
7290                }
7291            }
7292            mProfileApp = processName;
7293            mProfileFile = profileFile;
7294            if (mProfileFd != null) {
7295                try {
7296                    mProfileFd.close();
7297                } catch (IOException e) {
7298                }
7299                mProfileFd = null;
7300            }
7301            mProfileFd = profileFd;
7302            mProfileType = 0;
7303            mAutoStopProfiler = autoStopProfiler;
7304        }
7305    }
7306
7307    public void setAlwaysFinish(boolean enabled) {
7308        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7309                "setAlwaysFinish()");
7310
7311        Settings.System.putInt(
7312                mContext.getContentResolver(),
7313                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7314
7315        synchronized (this) {
7316            mAlwaysFinishActivities = enabled;
7317        }
7318    }
7319
7320    public void setActivityController(IActivityController controller) {
7321        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7322                "setActivityController()");
7323        synchronized (this) {
7324            mController = controller;
7325        }
7326    }
7327
7328    public boolean isUserAMonkey() {
7329        // For now the fact that there is a controller implies
7330        // we have a monkey.
7331        synchronized (this) {
7332            return mController != null;
7333        }
7334    }
7335
7336    public void requestBugReport() {
7337        // No permission check because this can't do anything harmful --
7338        // it will just eventually cause the user to be presented with
7339        // a UI to select where the bug report goes.
7340        SystemProperties.set("ctl.start", "bugreport");
7341    }
7342
7343    public void registerProcessObserver(IProcessObserver observer) {
7344        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7345                "registerProcessObserver()");
7346        synchronized (this) {
7347            mProcessObservers.register(observer);
7348        }
7349    }
7350
7351    public void unregisterProcessObserver(IProcessObserver observer) {
7352        synchronized (this) {
7353            mProcessObservers.unregister(observer);
7354        }
7355    }
7356
7357    public void setImmersive(IBinder token, boolean immersive) {
7358        synchronized(this) {
7359            ActivityRecord r = mMainStack.isInStackLocked(token);
7360            if (r == null) {
7361                throw new IllegalArgumentException();
7362            }
7363            r.immersive = immersive;
7364        }
7365    }
7366
7367    public boolean isImmersive(IBinder token) {
7368        synchronized (this) {
7369            ActivityRecord r = mMainStack.isInStackLocked(token);
7370            if (r == null) {
7371                throw new IllegalArgumentException();
7372            }
7373            return r.immersive;
7374        }
7375    }
7376
7377    public boolean isTopActivityImmersive() {
7378        enforceNotIsolatedCaller("startActivity");
7379        synchronized (this) {
7380            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7381            return (r != null) ? r.immersive : false;
7382        }
7383    }
7384
7385    public final void enterSafeMode() {
7386        synchronized(this) {
7387            // It only makes sense to do this before the system is ready
7388            // and started launching other packages.
7389            if (!mSystemReady) {
7390                try {
7391                    AppGlobals.getPackageManager().enterSafeMode();
7392                } catch (RemoteException e) {
7393                }
7394            }
7395        }
7396    }
7397
7398    public final void showSafeModeOverlay() {
7399        View v = LayoutInflater.from(mContext).inflate(
7400                com.android.internal.R.layout.safe_mode, null);
7401        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7402        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7403        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7404        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7405        lp.gravity = Gravity.BOTTOM | Gravity.START;
7406        lp.format = v.getBackground().getOpacity();
7407        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7408                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7409        ((WindowManager)mContext.getSystemService(
7410                Context.WINDOW_SERVICE)).addView(v, lp);
7411    }
7412
7413    public void noteWakeupAlarm(IIntentSender sender) {
7414        if (!(sender instanceof PendingIntentRecord)) {
7415            return;
7416        }
7417        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7418        synchronized (stats) {
7419            if (mBatteryStatsService.isOnBattery()) {
7420                mBatteryStatsService.enforceCallingPermission();
7421                PendingIntentRecord rec = (PendingIntentRecord)sender;
7422                int MY_UID = Binder.getCallingUid();
7423                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7424                BatteryStatsImpl.Uid.Pkg pkg =
7425                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7426                pkg.incWakeupsLocked();
7427            }
7428        }
7429    }
7430
7431    public boolean killPids(int[] pids, String pReason, boolean secure) {
7432        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7433            throw new SecurityException("killPids only available to the system");
7434        }
7435        String reason = (pReason == null) ? "Unknown" : pReason;
7436        // XXX Note: don't acquire main activity lock here, because the window
7437        // manager calls in with its locks held.
7438
7439        boolean killed = false;
7440        synchronized (mPidsSelfLocked) {
7441            int[] types = new int[pids.length];
7442            int worstType = 0;
7443            for (int i=0; i<pids.length; i++) {
7444                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7445                if (proc != null) {
7446                    int type = proc.setAdj;
7447                    types[i] = type;
7448                    if (type > worstType) {
7449                        worstType = type;
7450                    }
7451                }
7452            }
7453
7454            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7455            // then constrain it so we will kill all hidden procs.
7456            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7457                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7458                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7459            }
7460
7461            // If this is not a secure call, don't let it kill processes that
7462            // are important.
7463            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7464                worstType = ProcessList.SERVICE_ADJ;
7465            }
7466
7467            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7468            for (int i=0; i<pids.length; i++) {
7469                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7470                if (proc == null) {
7471                    continue;
7472                }
7473                int adj = proc.setAdj;
7474                if (adj >= worstType && !proc.killedBackground) {
7475                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7476                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7477                            proc.processName, adj, reason);
7478                    killed = true;
7479                    proc.killedBackground = true;
7480                    Process.killProcessQuiet(pids[i]);
7481                }
7482            }
7483        }
7484        return killed;
7485    }
7486
7487    @Override
7488    public boolean killProcessesBelowForeground(String reason) {
7489        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7490            throw new SecurityException("killProcessesBelowForeground() only available to system");
7491        }
7492
7493        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7494    }
7495
7496    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7497        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7498            throw new SecurityException("killProcessesBelowAdj() only available to system");
7499        }
7500
7501        boolean killed = false;
7502        synchronized (mPidsSelfLocked) {
7503            final int size = mPidsSelfLocked.size();
7504            for (int i = 0; i < size; i++) {
7505                final int pid = mPidsSelfLocked.keyAt(i);
7506                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7507                if (proc == null) continue;
7508
7509                final int adj = proc.setAdj;
7510                if (adj > belowAdj && !proc.killedBackground) {
7511                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7512                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7513                            proc.pid, proc.processName, adj, reason);
7514                    killed = true;
7515                    proc.killedBackground = true;
7516                    Process.killProcessQuiet(pid);
7517                }
7518            }
7519        }
7520        return killed;
7521    }
7522
7523    public final void startRunning(String pkg, String cls, String action,
7524            String data) {
7525        synchronized(this) {
7526            if (mStartRunning) {
7527                return;
7528            }
7529            mStartRunning = true;
7530            mTopComponent = pkg != null && cls != null
7531                    ? new ComponentName(pkg, cls) : null;
7532            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7533            mTopData = data;
7534            if (!mSystemReady) {
7535                return;
7536            }
7537        }
7538
7539        systemReady(null);
7540    }
7541
7542    private void retrieveSettings() {
7543        final ContentResolver resolver = mContext.getContentResolver();
7544        String debugApp = Settings.System.getString(
7545            resolver, Settings.System.DEBUG_APP);
7546        boolean waitForDebugger = Settings.System.getInt(
7547            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7548        boolean alwaysFinishActivities = Settings.System.getInt(
7549            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7550
7551        Configuration configuration = new Configuration();
7552        Settings.System.getConfiguration(resolver, configuration);
7553
7554        synchronized (this) {
7555            mDebugApp = mOrigDebugApp = debugApp;
7556            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7557            mAlwaysFinishActivities = alwaysFinishActivities;
7558            // This happens before any activities are started, so we can
7559            // change mConfiguration in-place.
7560            updateConfigurationLocked(configuration, null, false, true);
7561            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7562        }
7563    }
7564
7565    public boolean testIsSystemReady() {
7566        // no need to synchronize(this) just to read & return the value
7567        return mSystemReady;
7568    }
7569
7570    private static File getCalledPreBootReceiversFile() {
7571        File dataDir = Environment.getDataDirectory();
7572        File systemDir = new File(dataDir, "system");
7573        File fname = new File(systemDir, "called_pre_boots.dat");
7574        return fname;
7575    }
7576
7577    static final int LAST_DONE_VERSION = 10000;
7578
7579    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7580        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7581        File file = getCalledPreBootReceiversFile();
7582        FileInputStream fis = null;
7583        try {
7584            fis = new FileInputStream(file);
7585            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7586            int fvers = dis.readInt();
7587            if (fvers == LAST_DONE_VERSION) {
7588                String vers = dis.readUTF();
7589                String codename = dis.readUTF();
7590                String build = dis.readUTF();
7591                if (android.os.Build.VERSION.RELEASE.equals(vers)
7592                        && android.os.Build.VERSION.CODENAME.equals(codename)
7593                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7594                    int num = dis.readInt();
7595                    while (num > 0) {
7596                        num--;
7597                        String pkg = dis.readUTF();
7598                        String cls = dis.readUTF();
7599                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7600                    }
7601                }
7602            }
7603        } catch (FileNotFoundException e) {
7604        } catch (IOException e) {
7605            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7606        } finally {
7607            if (fis != null) {
7608                try {
7609                    fis.close();
7610                } catch (IOException e) {
7611                }
7612            }
7613        }
7614        return lastDoneReceivers;
7615    }
7616
7617    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7618        File file = getCalledPreBootReceiversFile();
7619        FileOutputStream fos = null;
7620        DataOutputStream dos = null;
7621        try {
7622            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7623            fos = new FileOutputStream(file);
7624            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7625            dos.writeInt(LAST_DONE_VERSION);
7626            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7627            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7628            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7629            dos.writeInt(list.size());
7630            for (int i=0; i<list.size(); i++) {
7631                dos.writeUTF(list.get(i).getPackageName());
7632                dos.writeUTF(list.get(i).getClassName());
7633            }
7634        } catch (IOException e) {
7635            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7636            file.delete();
7637        } finally {
7638            FileUtils.sync(fos);
7639            if (dos != null) {
7640                try {
7641                    dos.close();
7642                } catch (IOException e) {
7643                    // TODO Auto-generated catch block
7644                    e.printStackTrace();
7645                }
7646            }
7647        }
7648    }
7649
7650    public void systemReady(final Runnable goingCallback) {
7651        synchronized(this) {
7652            if (mSystemReady) {
7653                if (goingCallback != null) goingCallback.run();
7654                return;
7655            }
7656
7657            // Check to see if there are any update receivers to run.
7658            if (!mDidUpdate) {
7659                if (mWaitingUpdate) {
7660                    return;
7661                }
7662                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7663                List<ResolveInfo> ris = null;
7664                try {
7665                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7666                            intent, null, 0, 0);
7667                } catch (RemoteException e) {
7668                }
7669                if (ris != null) {
7670                    for (int i=ris.size()-1; i>=0; i--) {
7671                        if ((ris.get(i).activityInfo.applicationInfo.flags
7672                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7673                            ris.remove(i);
7674                        }
7675                    }
7676                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7677
7678                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7679
7680                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7681                    for (int i=0; i<ris.size(); i++) {
7682                        ActivityInfo ai = ris.get(i).activityInfo;
7683                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7684                        if (lastDoneReceivers.contains(comp)) {
7685                            ris.remove(i);
7686                            i--;
7687                        }
7688                    }
7689
7690                    final int[] users = getUsersLocked();
7691                    for (int i=0; i<ris.size(); i++) {
7692                        ActivityInfo ai = ris.get(i).activityInfo;
7693                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7694                        doneReceivers.add(comp);
7695                        intent.setComponent(comp);
7696                        for (int j=0; j<users.length; j++) {
7697                            IIntentReceiver finisher = null;
7698                            if (i == ris.size()-1 && j == users.length-1) {
7699                                finisher = new IIntentReceiver.Stub() {
7700                                    public void performReceive(Intent intent, int resultCode,
7701                                            String data, Bundle extras, boolean ordered,
7702                                            boolean sticky, int sendingUser) {
7703                                        // The raw IIntentReceiver interface is called
7704                                        // with the AM lock held, so redispatch to
7705                                        // execute our code without the lock.
7706                                        mHandler.post(new Runnable() {
7707                                            public void run() {
7708                                                synchronized (ActivityManagerService.this) {
7709                                                    mDidUpdate = true;
7710                                                }
7711                                                writeLastDonePreBootReceivers(doneReceivers);
7712                                                showBootMessage(mContext.getText(
7713                                                        R.string.android_upgrading_complete),
7714                                                        false);
7715                                                systemReady(goingCallback);
7716                                            }
7717                                        });
7718                                    }
7719                                };
7720                            }
7721                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7722                                    + " for user " + users[j]);
7723                            broadcastIntentLocked(null, null, intent, null, finisher,
7724                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7725                                    users[j]);
7726                            if (finisher != null) {
7727                                mWaitingUpdate = true;
7728                            }
7729                        }
7730                    }
7731                }
7732                if (mWaitingUpdate) {
7733                    return;
7734                }
7735                mDidUpdate = true;
7736            }
7737
7738            mSystemReady = true;
7739            if (!mStartRunning) {
7740                return;
7741            }
7742        }
7743
7744        ArrayList<ProcessRecord> procsToKill = null;
7745        synchronized(mPidsSelfLocked) {
7746            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7747                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7748                if (!isAllowedWhileBooting(proc.info)){
7749                    if (procsToKill == null) {
7750                        procsToKill = new ArrayList<ProcessRecord>();
7751                    }
7752                    procsToKill.add(proc);
7753                }
7754            }
7755        }
7756
7757        synchronized(this) {
7758            if (procsToKill != null) {
7759                for (int i=procsToKill.size()-1; i>=0; i--) {
7760                    ProcessRecord proc = procsToKill.get(i);
7761                    Slog.i(TAG, "Removing system update proc: " + proc);
7762                    removeProcessLocked(proc, true, false, "system update done");
7763                }
7764            }
7765
7766            // Now that we have cleaned up any update processes, we
7767            // are ready to start launching real processes and know that
7768            // we won't trample on them any more.
7769            mProcessesReady = true;
7770        }
7771
7772        Slog.i(TAG, "System now ready");
7773        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7774            SystemClock.uptimeMillis());
7775
7776        synchronized(this) {
7777            // Make sure we have no pre-ready processes sitting around.
7778
7779            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7780                ResolveInfo ri = mContext.getPackageManager()
7781                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7782                                STOCK_PM_FLAGS);
7783                CharSequence errorMsg = null;
7784                if (ri != null) {
7785                    ActivityInfo ai = ri.activityInfo;
7786                    ApplicationInfo app = ai.applicationInfo;
7787                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7788                        mTopAction = Intent.ACTION_FACTORY_TEST;
7789                        mTopData = null;
7790                        mTopComponent = new ComponentName(app.packageName,
7791                                ai.name);
7792                    } else {
7793                        errorMsg = mContext.getResources().getText(
7794                                com.android.internal.R.string.factorytest_not_system);
7795                    }
7796                } else {
7797                    errorMsg = mContext.getResources().getText(
7798                            com.android.internal.R.string.factorytest_no_action);
7799                }
7800                if (errorMsg != null) {
7801                    mTopAction = null;
7802                    mTopData = null;
7803                    mTopComponent = null;
7804                    Message msg = Message.obtain();
7805                    msg.what = SHOW_FACTORY_ERROR_MSG;
7806                    msg.getData().putCharSequence("msg", errorMsg);
7807                    mHandler.sendMessage(msg);
7808                }
7809            }
7810        }
7811
7812        retrieveSettings();
7813
7814        if (goingCallback != null) goingCallback.run();
7815
7816        synchronized (this) {
7817            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7818                try {
7819                    List apps = AppGlobals.getPackageManager().
7820                        getPersistentApplications(STOCK_PM_FLAGS);
7821                    if (apps != null) {
7822                        int N = apps.size();
7823                        int i;
7824                        for (i=0; i<N; i++) {
7825                            ApplicationInfo info
7826                                = (ApplicationInfo)apps.get(i);
7827                            if (info != null &&
7828                                    !info.packageName.equals("android")) {
7829                                addAppLocked(info, false);
7830                            }
7831                        }
7832                    }
7833                } catch (RemoteException ex) {
7834                    // pm is in same process, this will never happen.
7835                }
7836            }
7837
7838            // Start up initial activity.
7839            mBooting = true;
7840
7841            try {
7842                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7843                    Message msg = Message.obtain();
7844                    msg.what = SHOW_UID_ERROR_MSG;
7845                    mHandler.sendMessage(msg);
7846                }
7847            } catch (RemoteException e) {
7848            }
7849
7850            long ident = Binder.clearCallingIdentity();
7851            try {
7852                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7853                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7854                        | Intent.FLAG_RECEIVER_FOREGROUND);
7855                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7856                broadcastIntentLocked(null, null, intent,
7857                        null, null, 0, null, null, null,
7858                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7859            } finally {
7860                Binder.restoreCallingIdentity(ident);
7861            }
7862            mMainStack.resumeTopActivityLocked(null);
7863            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7864        }
7865    }
7866
7867    private boolean makeAppCrashingLocked(ProcessRecord app,
7868            String shortMsg, String longMsg, String stackTrace) {
7869        app.crashing = true;
7870        app.crashingReport = generateProcessError(app,
7871                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7872        startAppProblemLocked(app);
7873        app.stopFreezingAllLocked();
7874        return handleAppCrashLocked(app);
7875    }
7876
7877    private void makeAppNotRespondingLocked(ProcessRecord app,
7878            String activity, String shortMsg, String longMsg) {
7879        app.notResponding = true;
7880        app.notRespondingReport = generateProcessError(app,
7881                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7882                activity, shortMsg, longMsg, null);
7883        startAppProblemLocked(app);
7884        app.stopFreezingAllLocked();
7885    }
7886
7887    /**
7888     * Generate a process error record, suitable for attachment to a ProcessRecord.
7889     *
7890     * @param app The ProcessRecord in which the error occurred.
7891     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7892     *                      ActivityManager.AppErrorStateInfo
7893     * @param activity The activity associated with the crash, if known.
7894     * @param shortMsg Short message describing the crash.
7895     * @param longMsg Long message describing the crash.
7896     * @param stackTrace Full crash stack trace, may be null.
7897     *
7898     * @return Returns a fully-formed AppErrorStateInfo record.
7899     */
7900    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7901            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7902        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7903
7904        report.condition = condition;
7905        report.processName = app.processName;
7906        report.pid = app.pid;
7907        report.uid = app.info.uid;
7908        report.tag = activity;
7909        report.shortMsg = shortMsg;
7910        report.longMsg = longMsg;
7911        report.stackTrace = stackTrace;
7912
7913        return report;
7914    }
7915
7916    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7917        synchronized (this) {
7918            app.crashing = false;
7919            app.crashingReport = null;
7920            app.notResponding = false;
7921            app.notRespondingReport = null;
7922            if (app.anrDialog == fromDialog) {
7923                app.anrDialog = null;
7924            }
7925            if (app.waitDialog == fromDialog) {
7926                app.waitDialog = null;
7927            }
7928            if (app.pid > 0 && app.pid != MY_PID) {
7929                handleAppCrashLocked(app);
7930                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7931                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
7932                        app.processName, app.setAdj, "user's request after error");
7933                Process.killProcessQuiet(app.pid);
7934            }
7935        }
7936    }
7937
7938    private boolean handleAppCrashLocked(ProcessRecord app) {
7939        if (mHeadless) {
7940            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7941            return false;
7942        }
7943        long now = SystemClock.uptimeMillis();
7944
7945        Long crashTime;
7946        if (!app.isolated) {
7947            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7948        } else {
7949            crashTime = null;
7950        }
7951        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7952            // This process loses!
7953            Slog.w(TAG, "Process " + app.info.processName
7954                    + " has crashed too many times: killing!");
7955            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7956                    app.userId, app.info.processName, app.uid);
7957            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7958                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7959                if (r.app == app) {
7960                    Slog.w(TAG, "  Force finishing activity "
7961                        + r.intent.getComponent().flattenToShortString());
7962                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7963                            null, "crashed", false);
7964                }
7965            }
7966            if (!app.persistent) {
7967                // We don't want to start this process again until the user
7968                // explicitly does so...  but for persistent process, we really
7969                // need to keep it running.  If a persistent process is actually
7970                // repeatedly crashing, then badness for everyone.
7971                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
7972                        app.info.processName);
7973                if (!app.isolated) {
7974                    // XXX We don't have a way to mark isolated processes
7975                    // as bad, since they don't have a peristent identity.
7976                    mBadProcesses.put(app.info.processName, app.uid, now);
7977                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7978                }
7979                app.bad = true;
7980                app.removed = true;
7981                // Don't let services in this process be restarted and potentially
7982                // annoy the user repeatedly.  Unless it is persistent, since those
7983                // processes run critical code.
7984                removeProcessLocked(app, false, false, "crash");
7985                mMainStack.resumeTopActivityLocked(null);
7986                return false;
7987            }
7988            mMainStack.resumeTopActivityLocked(null);
7989        } else {
7990            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7991            if (r != null && r.app == app) {
7992                // If the top running activity is from this crashing
7993                // process, then terminate it to avoid getting in a loop.
7994                Slog.w(TAG, "  Force finishing activity "
7995                        + r.intent.getComponent().flattenToShortString());
7996                int index = mMainStack.indexOfActivityLocked(r);
7997                r.stack.finishActivityLocked(r, index,
7998                        Activity.RESULT_CANCELED, null, "crashed", false);
7999                // Also terminate any activities below it that aren't yet
8000                // stopped, to avoid a situation where one will get
8001                // re-start our crashing activity once it gets resumed again.
8002                index--;
8003                if (index >= 0) {
8004                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8005                    if (r.state == ActivityState.RESUMED
8006                            || r.state == ActivityState.PAUSING
8007                            || r.state == ActivityState.PAUSED) {
8008                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8009                            Slog.w(TAG, "  Force finishing activity "
8010                                    + r.intent.getComponent().flattenToShortString());
8011                            r.stack.finishActivityLocked(r, index,
8012                                    Activity.RESULT_CANCELED, null, "crashed", false);
8013                        }
8014                    }
8015                }
8016            }
8017        }
8018
8019        // Bump up the crash count of any services currently running in the proc.
8020        if (app.services.size() != 0) {
8021            // Any services running in the application need to be placed
8022            // back in the pending list.
8023            Iterator<ServiceRecord> it = app.services.iterator();
8024            while (it.hasNext()) {
8025                ServiceRecord sr = it.next();
8026                sr.crashCount++;
8027            }
8028        }
8029
8030        // If the crashing process is what we consider to be the "home process" and it has been
8031        // replaced by a third-party app, clear the package preferred activities from packages
8032        // with a home activity running in the process to prevent a repeatedly crashing app
8033        // from blocking the user to manually clear the list.
8034        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8035                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8036            Iterator it = mHomeProcess.activities.iterator();
8037            while (it.hasNext()) {
8038                ActivityRecord r = (ActivityRecord)it.next();
8039                if (r.isHomeActivity) {
8040                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8041                    try {
8042                        ActivityThread.getPackageManager()
8043                                .clearPackagePreferredActivities(r.packageName);
8044                    } catch (RemoteException c) {
8045                        // pm is in same process, this will never happen.
8046                    }
8047                }
8048            }
8049        }
8050
8051        if (!app.isolated) {
8052            // XXX Can't keep track of crash times for isolated processes,
8053            // because they don't have a perisistent identity.
8054            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8055        }
8056
8057        return true;
8058    }
8059
8060    void startAppProblemLocked(ProcessRecord app) {
8061        if (app.userId == mCurrentUserId) {
8062            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8063                    mContext, app.info.packageName, app.info.flags);
8064        } else {
8065            // If this app is not running under the current user, then we
8066            // can't give it a report button because that would require
8067            // launching the report UI under a different user.
8068            app.errorReportReceiver = null;
8069        }
8070        skipCurrentReceiverLocked(app);
8071    }
8072
8073    void skipCurrentReceiverLocked(ProcessRecord app) {
8074        for (BroadcastQueue queue : mBroadcastQueues) {
8075            queue.skipCurrentReceiverLocked(app);
8076        }
8077    }
8078
8079    /**
8080     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8081     * The application process will exit immediately after this call returns.
8082     * @param app object of the crashing app, null for the system server
8083     * @param crashInfo describing the exception
8084     */
8085    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8086        ProcessRecord r = findAppProcess(app, "Crash");
8087        final String processName = app == null ? "system_server"
8088                : (r == null ? "unknown" : r.processName);
8089
8090        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8091                UserHandle.getUserId(Binder.getCallingUid()), processName,
8092                r == null ? -1 : r.info.flags,
8093                crashInfo.exceptionClassName,
8094                crashInfo.exceptionMessage,
8095                crashInfo.throwFileName,
8096                crashInfo.throwLineNumber);
8097
8098        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8099
8100        crashApplication(r, crashInfo);
8101    }
8102
8103    public void handleApplicationStrictModeViolation(
8104            IBinder app,
8105            int violationMask,
8106            StrictMode.ViolationInfo info) {
8107        ProcessRecord r = findAppProcess(app, "StrictMode");
8108        if (r == null) {
8109            return;
8110        }
8111
8112        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8113            Integer stackFingerprint = info.hashCode();
8114            boolean logIt = true;
8115            synchronized (mAlreadyLoggedViolatedStacks) {
8116                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8117                    logIt = false;
8118                    // TODO: sub-sample into EventLog for these, with
8119                    // the info.durationMillis?  Then we'd get
8120                    // the relative pain numbers, without logging all
8121                    // the stack traces repeatedly.  We'd want to do
8122                    // likewise in the client code, which also does
8123                    // dup suppression, before the Binder call.
8124                } else {
8125                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8126                        mAlreadyLoggedViolatedStacks.clear();
8127                    }
8128                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8129                }
8130            }
8131            if (logIt) {
8132                logStrictModeViolationToDropBox(r, info);
8133            }
8134        }
8135
8136        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8137            AppErrorResult result = new AppErrorResult();
8138            synchronized (this) {
8139                final long origId = Binder.clearCallingIdentity();
8140
8141                Message msg = Message.obtain();
8142                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8143                HashMap<String, Object> data = new HashMap<String, Object>();
8144                data.put("result", result);
8145                data.put("app", r);
8146                data.put("violationMask", violationMask);
8147                data.put("info", info);
8148                msg.obj = data;
8149                mHandler.sendMessage(msg);
8150
8151                Binder.restoreCallingIdentity(origId);
8152            }
8153            int res = result.get();
8154            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8155        }
8156    }
8157
8158    // Depending on the policy in effect, there could be a bunch of
8159    // these in quick succession so we try to batch these together to
8160    // minimize disk writes, number of dropbox entries, and maximize
8161    // compression, by having more fewer, larger records.
8162    private void logStrictModeViolationToDropBox(
8163            ProcessRecord process,
8164            StrictMode.ViolationInfo info) {
8165        if (info == null) {
8166            return;
8167        }
8168        final boolean isSystemApp = process == null ||
8169                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8170                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8171        final String processName = process == null ? "unknown" : process.processName;
8172        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8173        final DropBoxManager dbox = (DropBoxManager)
8174                mContext.getSystemService(Context.DROPBOX_SERVICE);
8175
8176        // Exit early if the dropbox isn't configured to accept this report type.
8177        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8178
8179        boolean bufferWasEmpty;
8180        boolean needsFlush;
8181        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8182        synchronized (sb) {
8183            bufferWasEmpty = sb.length() == 0;
8184            appendDropBoxProcessHeaders(process, processName, sb);
8185            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8186            sb.append("System-App: ").append(isSystemApp).append("\n");
8187            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8188            if (info.violationNumThisLoop != 0) {
8189                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8190            }
8191            if (info.numAnimationsRunning != 0) {
8192                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8193            }
8194            if (info.broadcastIntentAction != null) {
8195                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8196            }
8197            if (info.durationMillis != -1) {
8198                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8199            }
8200            if (info.numInstances != -1) {
8201                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8202            }
8203            if (info.tags != null) {
8204                for (String tag : info.tags) {
8205                    sb.append("Span-Tag: ").append(tag).append("\n");
8206                }
8207            }
8208            sb.append("\n");
8209            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8210                sb.append(info.crashInfo.stackTrace);
8211            }
8212            sb.append("\n");
8213
8214            // Only buffer up to ~64k.  Various logging bits truncate
8215            // things at 128k.
8216            needsFlush = (sb.length() > 64 * 1024);
8217        }
8218
8219        // Flush immediately if the buffer's grown too large, or this
8220        // is a non-system app.  Non-system apps are isolated with a
8221        // different tag & policy and not batched.
8222        //
8223        // Batching is useful during internal testing with
8224        // StrictMode settings turned up high.  Without batching,
8225        // thousands of separate files could be created on boot.
8226        if (!isSystemApp || needsFlush) {
8227            new Thread("Error dump: " + dropboxTag) {
8228                @Override
8229                public void run() {
8230                    String report;
8231                    synchronized (sb) {
8232                        report = sb.toString();
8233                        sb.delete(0, sb.length());
8234                        sb.trimToSize();
8235                    }
8236                    if (report.length() != 0) {
8237                        dbox.addText(dropboxTag, report);
8238                    }
8239                }
8240            }.start();
8241            return;
8242        }
8243
8244        // System app batching:
8245        if (!bufferWasEmpty) {
8246            // An existing dropbox-writing thread is outstanding, so
8247            // we don't need to start it up.  The existing thread will
8248            // catch the buffer appends we just did.
8249            return;
8250        }
8251
8252        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8253        // (After this point, we shouldn't access AMS internal data structures.)
8254        new Thread("Error dump: " + dropboxTag) {
8255            @Override
8256            public void run() {
8257                // 5 second sleep to let stacks arrive and be batched together
8258                try {
8259                    Thread.sleep(5000);  // 5 seconds
8260                } catch (InterruptedException e) {}
8261
8262                String errorReport;
8263                synchronized (mStrictModeBuffer) {
8264                    errorReport = mStrictModeBuffer.toString();
8265                    if (errorReport.length() == 0) {
8266                        return;
8267                    }
8268                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8269                    mStrictModeBuffer.trimToSize();
8270                }
8271                dbox.addText(dropboxTag, errorReport);
8272            }
8273        }.start();
8274    }
8275
8276    /**
8277     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8278     * @param app object of the crashing app, null for the system server
8279     * @param tag reported by the caller
8280     * @param crashInfo describing the context of the error
8281     * @return true if the process should exit immediately (WTF is fatal)
8282     */
8283    public boolean handleApplicationWtf(IBinder app, String tag,
8284            ApplicationErrorReport.CrashInfo crashInfo) {
8285        ProcessRecord r = findAppProcess(app, "WTF");
8286        final String processName = app == null ? "system_server"
8287                : (r == null ? "unknown" : r.processName);
8288
8289        EventLog.writeEvent(EventLogTags.AM_WTF,
8290                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8291                processName,
8292                r == null ? -1 : r.info.flags,
8293                tag, crashInfo.exceptionMessage);
8294
8295        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8296
8297        if (r != null && r.pid != Process.myPid() &&
8298                Settings.Global.getInt(mContext.getContentResolver(),
8299                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8300            crashApplication(r, crashInfo);
8301            return true;
8302        } else {
8303            return false;
8304        }
8305    }
8306
8307    /**
8308     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8309     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8310     */
8311    private ProcessRecord findAppProcess(IBinder app, String reason) {
8312        if (app == null) {
8313            return null;
8314        }
8315
8316        synchronized (this) {
8317            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8318                final int NA = apps.size();
8319                for (int ia=0; ia<NA; ia++) {
8320                    ProcessRecord p = apps.valueAt(ia);
8321                    if (p.thread != null && p.thread.asBinder() == app) {
8322                        return p;
8323                    }
8324                }
8325            }
8326
8327            Slog.w(TAG, "Can't find mystery application for " + reason
8328                    + " from pid=" + Binder.getCallingPid()
8329                    + " uid=" + Binder.getCallingUid() + ": " + app);
8330            return null;
8331        }
8332    }
8333
8334    /**
8335     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8336     * to append various headers to the dropbox log text.
8337     */
8338    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8339            StringBuilder sb) {
8340        // Watchdog thread ends up invoking this function (with
8341        // a null ProcessRecord) to add the stack file to dropbox.
8342        // Do not acquire a lock on this (am) in such cases, as it
8343        // could cause a potential deadlock, if and when watchdog
8344        // is invoked due to unavailability of lock on am and it
8345        // would prevent watchdog from killing system_server.
8346        if (process == null) {
8347            sb.append("Process: ").append(processName).append("\n");
8348            return;
8349        }
8350        // Note: ProcessRecord 'process' is guarded by the service
8351        // instance.  (notably process.pkgList, which could otherwise change
8352        // concurrently during execution of this method)
8353        synchronized (this) {
8354            sb.append("Process: ").append(processName).append("\n");
8355            int flags = process.info.flags;
8356            IPackageManager pm = AppGlobals.getPackageManager();
8357            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8358            for (String pkg : process.pkgList) {
8359                sb.append("Package: ").append(pkg);
8360                try {
8361                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8362                    if (pi != null) {
8363                        sb.append(" v").append(pi.versionCode);
8364                        if (pi.versionName != null) {
8365                            sb.append(" (").append(pi.versionName).append(")");
8366                        }
8367                    }
8368                } catch (RemoteException e) {
8369                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8370                }
8371                sb.append("\n");
8372            }
8373        }
8374    }
8375
8376    private static String processClass(ProcessRecord process) {
8377        if (process == null || process.pid == MY_PID) {
8378            return "system_server";
8379        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8380            return "system_app";
8381        } else {
8382            return "data_app";
8383        }
8384    }
8385
8386    /**
8387     * Write a description of an error (crash, WTF, ANR) to the drop box.
8388     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8389     * @param process which caused the error, null means the system server
8390     * @param activity which triggered the error, null if unknown
8391     * @param parent activity related to the error, null if unknown
8392     * @param subject line related to the error, null if absent
8393     * @param report in long form describing the error, null if absent
8394     * @param logFile to include in the report, null if none
8395     * @param crashInfo giving an application stack trace, null if absent
8396     */
8397    public void addErrorToDropBox(String eventType,
8398            ProcessRecord process, String processName, ActivityRecord activity,
8399            ActivityRecord parent, String subject,
8400            final String report, final File logFile,
8401            final ApplicationErrorReport.CrashInfo crashInfo) {
8402        // NOTE -- this must never acquire the ActivityManagerService lock,
8403        // otherwise the watchdog may be prevented from resetting the system.
8404
8405        final String dropboxTag = processClass(process) + "_" + eventType;
8406        final DropBoxManager dbox = (DropBoxManager)
8407                mContext.getSystemService(Context.DROPBOX_SERVICE);
8408
8409        // Exit early if the dropbox isn't configured to accept this report type.
8410        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8411
8412        final StringBuilder sb = new StringBuilder(1024);
8413        appendDropBoxProcessHeaders(process, processName, sb);
8414        if (activity != null) {
8415            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8416        }
8417        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8418            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8419        }
8420        if (parent != null && parent != activity) {
8421            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8422        }
8423        if (subject != null) {
8424            sb.append("Subject: ").append(subject).append("\n");
8425        }
8426        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8427        if (Debug.isDebuggerConnected()) {
8428            sb.append("Debugger: Connected\n");
8429        }
8430        sb.append("\n");
8431
8432        // Do the rest in a worker thread to avoid blocking the caller on I/O
8433        // (After this point, we shouldn't access AMS internal data structures.)
8434        Thread worker = new Thread("Error dump: " + dropboxTag) {
8435            @Override
8436            public void run() {
8437                if (report != null) {
8438                    sb.append(report);
8439                }
8440                if (logFile != null) {
8441                    try {
8442                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8443                    } catch (IOException e) {
8444                        Slog.e(TAG, "Error reading " + logFile, e);
8445                    }
8446                }
8447                if (crashInfo != null && crashInfo.stackTrace != null) {
8448                    sb.append(crashInfo.stackTrace);
8449                }
8450
8451                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8452                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8453                if (lines > 0) {
8454                    sb.append("\n");
8455
8456                    // Merge several logcat streams, and take the last N lines
8457                    InputStreamReader input = null;
8458                    try {
8459                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8460                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8461                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8462
8463                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8464                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8465                        input = new InputStreamReader(logcat.getInputStream());
8466
8467                        int num;
8468                        char[] buf = new char[8192];
8469                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8470                    } catch (IOException e) {
8471                        Slog.e(TAG, "Error running logcat", e);
8472                    } finally {
8473                        if (input != null) try { input.close(); } catch (IOException e) {}
8474                    }
8475                }
8476
8477                dbox.addText(dropboxTag, sb.toString());
8478            }
8479        };
8480
8481        if (process == null) {
8482            // If process is null, we are being called from some internal code
8483            // and may be about to die -- run this synchronously.
8484            worker.run();
8485        } else {
8486            worker.start();
8487        }
8488    }
8489
8490    /**
8491     * Bring up the "unexpected error" dialog box for a crashing app.
8492     * Deal with edge cases (intercepts from instrumented applications,
8493     * ActivityController, error intent receivers, that sort of thing).
8494     * @param r the application crashing
8495     * @param crashInfo describing the failure
8496     */
8497    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8498        long timeMillis = System.currentTimeMillis();
8499        String shortMsg = crashInfo.exceptionClassName;
8500        String longMsg = crashInfo.exceptionMessage;
8501        String stackTrace = crashInfo.stackTrace;
8502        if (shortMsg != null && longMsg != null) {
8503            longMsg = shortMsg + ": " + longMsg;
8504        } else if (shortMsg != null) {
8505            longMsg = shortMsg;
8506        }
8507
8508        AppErrorResult result = new AppErrorResult();
8509        synchronized (this) {
8510            if (mController != null) {
8511                try {
8512                    String name = r != null ? r.processName : null;
8513                    int pid = r != null ? r.pid : Binder.getCallingPid();
8514                    if (!mController.appCrashed(name, pid,
8515                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8516                        Slog.w(TAG, "Force-killing crashed app " + name
8517                                + " at watcher's request");
8518                        Process.killProcess(pid);
8519                        return;
8520                    }
8521                } catch (RemoteException e) {
8522                    mController = null;
8523                }
8524            }
8525
8526            final long origId = Binder.clearCallingIdentity();
8527
8528            // If this process is running instrumentation, finish it.
8529            if (r != null && r.instrumentationClass != null) {
8530                Slog.w(TAG, "Error in app " + r.processName
8531                      + " running instrumentation " + r.instrumentationClass + ":");
8532                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8533                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8534                Bundle info = new Bundle();
8535                info.putString("shortMsg", shortMsg);
8536                info.putString("longMsg", longMsg);
8537                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8538                Binder.restoreCallingIdentity(origId);
8539                return;
8540            }
8541
8542            // If we can't identify the process or it's already exceeded its crash quota,
8543            // quit right away without showing a crash dialog.
8544            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8545                Binder.restoreCallingIdentity(origId);
8546                return;
8547            }
8548
8549            Message msg = Message.obtain();
8550            msg.what = SHOW_ERROR_MSG;
8551            HashMap data = new HashMap();
8552            data.put("result", result);
8553            data.put("app", r);
8554            msg.obj = data;
8555            mHandler.sendMessage(msg);
8556
8557            Binder.restoreCallingIdentity(origId);
8558        }
8559
8560        int res = result.get();
8561
8562        Intent appErrorIntent = null;
8563        synchronized (this) {
8564            if (r != null && !r.isolated) {
8565                // XXX Can't keep track of crash time for isolated processes,
8566                // since they don't have a persistent identity.
8567                mProcessCrashTimes.put(r.info.processName, r.uid,
8568                        SystemClock.uptimeMillis());
8569            }
8570            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8571                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8572            }
8573        }
8574
8575        if (appErrorIntent != null) {
8576            try {
8577                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8578            } catch (ActivityNotFoundException e) {
8579                Slog.w(TAG, "bug report receiver dissappeared", e);
8580            }
8581        }
8582    }
8583
8584    Intent createAppErrorIntentLocked(ProcessRecord r,
8585            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8586        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8587        if (report == null) {
8588            return null;
8589        }
8590        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8591        result.setComponent(r.errorReportReceiver);
8592        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8593        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8594        return result;
8595    }
8596
8597    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8598            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8599        if (r.errorReportReceiver == null) {
8600            return null;
8601        }
8602
8603        if (!r.crashing && !r.notResponding) {
8604            return null;
8605        }
8606
8607        ApplicationErrorReport report = new ApplicationErrorReport();
8608        report.packageName = r.info.packageName;
8609        report.installerPackageName = r.errorReportReceiver.getPackageName();
8610        report.processName = r.processName;
8611        report.time = timeMillis;
8612        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8613
8614        if (r.crashing) {
8615            report.type = ApplicationErrorReport.TYPE_CRASH;
8616            report.crashInfo = crashInfo;
8617        } else if (r.notResponding) {
8618            report.type = ApplicationErrorReport.TYPE_ANR;
8619            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8620
8621            report.anrInfo.activity = r.notRespondingReport.tag;
8622            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8623            report.anrInfo.info = r.notRespondingReport.longMsg;
8624        }
8625
8626        return report;
8627    }
8628
8629    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8630        enforceNotIsolatedCaller("getProcessesInErrorState");
8631        // assume our apps are happy - lazy create the list
8632        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8633
8634        final boolean allUsers = ActivityManager.checkUidPermission(
8635                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8636                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8637        int userId = UserHandle.getUserId(Binder.getCallingUid());
8638
8639        synchronized (this) {
8640
8641            // iterate across all processes
8642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8643                ProcessRecord app = mLruProcesses.get(i);
8644                if (!allUsers && app.userId != userId) {
8645                    continue;
8646                }
8647                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8648                    // This one's in trouble, so we'll generate a report for it
8649                    // crashes are higher priority (in case there's a crash *and* an anr)
8650                    ActivityManager.ProcessErrorStateInfo report = null;
8651                    if (app.crashing) {
8652                        report = app.crashingReport;
8653                    } else if (app.notResponding) {
8654                        report = app.notRespondingReport;
8655                    }
8656
8657                    if (report != null) {
8658                        if (errList == null) {
8659                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8660                        }
8661                        errList.add(report);
8662                    } else {
8663                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8664                                " crashing = " + app.crashing +
8665                                " notResponding = " + app.notResponding);
8666                    }
8667                }
8668            }
8669        }
8670
8671        return errList;
8672    }
8673
8674    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8675        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8676            if (currApp != null) {
8677                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8678            }
8679            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8680        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8681            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8682        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8683            if (currApp != null) {
8684                currApp.lru = 0;
8685            }
8686            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8687        } else if (adj >= ProcessList.SERVICE_ADJ) {
8688            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8689        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8690            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8691        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8692            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8693        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8694            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8695        } else {
8696            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8697        }
8698    }
8699
8700    private void fillInProcMemInfo(ProcessRecord app,
8701            ActivityManager.RunningAppProcessInfo outInfo) {
8702        outInfo.pid = app.pid;
8703        outInfo.uid = app.info.uid;
8704        if (mHeavyWeightProcess == app) {
8705            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8706        }
8707        if (app.persistent) {
8708            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8709        }
8710        if (app.hasActivities) {
8711            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8712        }
8713        outInfo.lastTrimLevel = app.trimMemoryLevel;
8714        int adj = app.curAdj;
8715        outInfo.importance = oomAdjToImportance(adj, outInfo);
8716        outInfo.importanceReasonCode = app.adjTypeCode;
8717    }
8718
8719    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8720        enforceNotIsolatedCaller("getRunningAppProcesses");
8721        // Lazy instantiation of list
8722        List<ActivityManager.RunningAppProcessInfo> runList = null;
8723        final boolean allUsers = ActivityManager.checkUidPermission(
8724                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8725                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8726        int userId = UserHandle.getUserId(Binder.getCallingUid());
8727        synchronized (this) {
8728            // Iterate across all processes
8729            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8730                ProcessRecord app = mLruProcesses.get(i);
8731                if (!allUsers && app.userId != userId) {
8732                    continue;
8733                }
8734                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8735                    // Generate process state info for running application
8736                    ActivityManager.RunningAppProcessInfo currApp =
8737                        new ActivityManager.RunningAppProcessInfo(app.processName,
8738                                app.pid, app.getPackageList());
8739                    fillInProcMemInfo(app, currApp);
8740                    if (app.adjSource instanceof ProcessRecord) {
8741                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8742                        currApp.importanceReasonImportance = oomAdjToImportance(
8743                                app.adjSourceOom, null);
8744                    } else if (app.adjSource instanceof ActivityRecord) {
8745                        ActivityRecord r = (ActivityRecord)app.adjSource;
8746                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8747                    }
8748                    if (app.adjTarget instanceof ComponentName) {
8749                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8750                    }
8751                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8752                    //        + " lru=" + currApp.lru);
8753                    if (runList == null) {
8754                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8755                    }
8756                    runList.add(currApp);
8757                }
8758            }
8759        }
8760        return runList;
8761    }
8762
8763    public List<ApplicationInfo> getRunningExternalApplications() {
8764        enforceNotIsolatedCaller("getRunningExternalApplications");
8765        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8766        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8767        if (runningApps != null && runningApps.size() > 0) {
8768            Set<String> extList = new HashSet<String>();
8769            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8770                if (app.pkgList != null) {
8771                    for (String pkg : app.pkgList) {
8772                        extList.add(pkg);
8773                    }
8774                }
8775            }
8776            IPackageManager pm = AppGlobals.getPackageManager();
8777            for (String pkg : extList) {
8778                try {
8779                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8780                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8781                        retList.add(info);
8782                    }
8783                } catch (RemoteException e) {
8784                }
8785            }
8786        }
8787        return retList;
8788    }
8789
8790    @Override
8791    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8792        enforceNotIsolatedCaller("getMyMemoryState");
8793        synchronized (this) {
8794            ProcessRecord proc;
8795            synchronized (mPidsSelfLocked) {
8796                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8797            }
8798            fillInProcMemInfo(proc, outInfo);
8799        }
8800    }
8801
8802    @Override
8803    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8804        if (checkCallingPermission(android.Manifest.permission.DUMP)
8805                != PackageManager.PERMISSION_GRANTED) {
8806            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8807                    + Binder.getCallingPid()
8808                    + ", uid=" + Binder.getCallingUid()
8809                    + " without permission "
8810                    + android.Manifest.permission.DUMP);
8811            return;
8812        }
8813
8814        boolean dumpAll = false;
8815        boolean dumpClient = false;
8816        String dumpPackage = null;
8817
8818        int opti = 0;
8819        while (opti < args.length) {
8820            String opt = args[opti];
8821            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8822                break;
8823            }
8824            opti++;
8825            if ("-a".equals(opt)) {
8826                dumpAll = true;
8827            } else if ("-c".equals(opt)) {
8828                dumpClient = true;
8829            } else if ("-h".equals(opt)) {
8830                pw.println("Activity manager dump options:");
8831                pw.println("  [-a] [-c] [-h] [cmd] ...");
8832                pw.println("  cmd may be one of:");
8833                pw.println("    a[ctivities]: activity stack state");
8834                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8835                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8836                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8837                pw.println("    o[om]: out of memory management");
8838                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8839                pw.println("    provider [COMP_SPEC]: provider client-side state");
8840                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8841                pw.println("    service [COMP_SPEC]: service client-side state");
8842                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8843                pw.println("    all: dump all activities");
8844                pw.println("    top: dump the top activity");
8845                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8846                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8847                pw.println("    a partial substring in a component name, a");
8848                pw.println("    hex object identifier.");
8849                pw.println("  -a: include all available server state.");
8850                pw.println("  -c: include client state.");
8851                return;
8852            } else {
8853                pw.println("Unknown argument: " + opt + "; use -h for help");
8854            }
8855        }
8856
8857        long origId = Binder.clearCallingIdentity();
8858        boolean more = false;
8859        // Is the caller requesting to dump a particular piece of data?
8860        if (opti < args.length) {
8861            String cmd = args[opti];
8862            opti++;
8863            if ("activities".equals(cmd) || "a".equals(cmd)) {
8864                synchronized (this) {
8865                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8866                }
8867            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8868                String[] newArgs;
8869                String name;
8870                if (opti >= args.length) {
8871                    name = null;
8872                    newArgs = EMPTY_STRING_ARRAY;
8873                } else {
8874                    name = args[opti];
8875                    opti++;
8876                    newArgs = new String[args.length - opti];
8877                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8878                            args.length - opti);
8879                }
8880                synchronized (this) {
8881                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8882                }
8883            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8884                String[] newArgs;
8885                String name;
8886                if (opti >= args.length) {
8887                    name = null;
8888                    newArgs = EMPTY_STRING_ARRAY;
8889                } else {
8890                    name = args[opti];
8891                    opti++;
8892                    newArgs = new String[args.length - opti];
8893                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8894                            args.length - opti);
8895                }
8896                synchronized (this) {
8897                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8898                }
8899            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8900                String[] newArgs;
8901                String name;
8902                if (opti >= args.length) {
8903                    name = null;
8904                    newArgs = EMPTY_STRING_ARRAY;
8905                } else {
8906                    name = args[opti];
8907                    opti++;
8908                    newArgs = new String[args.length - opti];
8909                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8910                            args.length - opti);
8911                }
8912                synchronized (this) {
8913                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8914                }
8915            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8916                synchronized (this) {
8917                    dumpOomLocked(fd, pw, args, opti, true);
8918                }
8919            } else if ("provider".equals(cmd)) {
8920                String[] newArgs;
8921                String name;
8922                if (opti >= args.length) {
8923                    name = null;
8924                    newArgs = EMPTY_STRING_ARRAY;
8925                } else {
8926                    name = args[opti];
8927                    opti++;
8928                    newArgs = new String[args.length - opti];
8929                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8930                }
8931                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8932                    pw.println("No providers match: " + name);
8933                    pw.println("Use -h for help.");
8934                }
8935            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8936                synchronized (this) {
8937                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8938                }
8939            } else if ("service".equals(cmd)) {
8940                String[] newArgs;
8941                String name;
8942                if (opti >= args.length) {
8943                    name = null;
8944                    newArgs = EMPTY_STRING_ARRAY;
8945                } else {
8946                    name = args[opti];
8947                    opti++;
8948                    newArgs = new String[args.length - opti];
8949                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8950                            args.length - opti);
8951                }
8952                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8953                    pw.println("No services match: " + name);
8954                    pw.println("Use -h for help.");
8955                }
8956            } else if ("package".equals(cmd)) {
8957                String[] newArgs;
8958                if (opti >= args.length) {
8959                    pw.println("package: no package name specified");
8960                    pw.println("Use -h for help.");
8961                } else {
8962                    dumpPackage = args[opti];
8963                    opti++;
8964                    newArgs = new String[args.length - opti];
8965                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8966                            args.length - opti);
8967                    args = newArgs;
8968                    opti = 0;
8969                    more = true;
8970                }
8971            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8972                synchronized (this) {
8973                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8974                }
8975            } else {
8976                // Dumping a single activity?
8977                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8978                    pw.println("Bad activity command, or no activities match: " + cmd);
8979                    pw.println("Use -h for help.");
8980                }
8981            }
8982            if (!more) {
8983                Binder.restoreCallingIdentity(origId);
8984                return;
8985            }
8986        }
8987
8988        // No piece of data specified, dump everything.
8989        synchronized (this) {
8990            boolean needSep;
8991            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8992            if (needSep) {
8993                pw.println(" ");
8994            }
8995            if (dumpAll) {
8996                pw.println("-------------------------------------------------------------------------------");
8997            }
8998            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8999            if (needSep) {
9000                pw.println(" ");
9001            }
9002            if (dumpAll) {
9003                pw.println("-------------------------------------------------------------------------------");
9004            }
9005            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9006            if (needSep) {
9007                pw.println(" ");
9008            }
9009            if (dumpAll) {
9010                pw.println("-------------------------------------------------------------------------------");
9011            }
9012            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9013            if (needSep) {
9014                pw.println(" ");
9015            }
9016            if (dumpAll) {
9017                pw.println("-------------------------------------------------------------------------------");
9018            }
9019            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9020            if (needSep) {
9021                pw.println(" ");
9022            }
9023            if (dumpAll) {
9024                pw.println("-------------------------------------------------------------------------------");
9025            }
9026            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9027        }
9028        Binder.restoreCallingIdentity(origId);
9029    }
9030
9031    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9032            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9033        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9034        pw.println("  Main stack:");
9035        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9036                dumpPackage);
9037        pw.println(" ");
9038        pw.println("  Running activities (most recent first):");
9039        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9040                dumpPackage);
9041        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9042            pw.println(" ");
9043            pw.println("  Activities waiting for another to become visible:");
9044            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9045                    !dumpAll, false, dumpPackage);
9046        }
9047        if (mMainStack.mStoppingActivities.size() > 0) {
9048            pw.println(" ");
9049            pw.println("  Activities waiting to stop:");
9050            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9051                    !dumpAll, false, dumpPackage);
9052        }
9053        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9054            pw.println(" ");
9055            pw.println("  Activities waiting to sleep:");
9056            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9057                    !dumpAll, false, dumpPackage);
9058        }
9059        if (mMainStack.mFinishingActivities.size() > 0) {
9060            pw.println(" ");
9061            pw.println("  Activities waiting to finish:");
9062            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9063                    !dumpAll, false, dumpPackage);
9064        }
9065
9066        pw.println(" ");
9067        if (mMainStack.mPausingActivity != null) {
9068            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9069        }
9070        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9071        pw.println("  mFocusedActivity: " + mFocusedActivity);
9072        if (dumpAll) {
9073            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9074            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9075            pw.println("  mDismissKeyguardOnNextActivity: "
9076                    + mMainStack.mDismissKeyguardOnNextActivity);
9077        }
9078
9079        if (mRecentTasks.size() > 0) {
9080            pw.println();
9081            pw.println("  Recent tasks:");
9082
9083            final int N = mRecentTasks.size();
9084            for (int i=0; i<N; i++) {
9085                TaskRecord tr = mRecentTasks.get(i);
9086                if (dumpPackage != null) {
9087                    if (tr.realActivity == null ||
9088                            !dumpPackage.equals(tr.realActivity)) {
9089                        continue;
9090                    }
9091                }
9092                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9093                        pw.println(tr);
9094                if (dumpAll) {
9095                    mRecentTasks.get(i).dump(pw, "    ");
9096                }
9097            }
9098        }
9099
9100        if (dumpAll) {
9101            pw.println(" ");
9102            pw.println("  mCurTask: " + mCurTask);
9103        }
9104
9105        return true;
9106    }
9107
9108    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9109            int opti, boolean dumpAll, String dumpPackage) {
9110        boolean needSep = false;
9111        int numPers = 0;
9112
9113        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9114
9115        if (dumpAll) {
9116            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9117                final int NA = procs.size();
9118                for (int ia=0; ia<NA; ia++) {
9119                    ProcessRecord r = procs.valueAt(ia);
9120                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9121                        continue;
9122                    }
9123                    if (!needSep) {
9124                        pw.println("  All known processes:");
9125                        needSep = true;
9126                    }
9127                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9128                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9129                        pw.print(" "); pw.println(r);
9130                    r.dump(pw, "    ");
9131                    if (r.persistent) {
9132                        numPers++;
9133                    }
9134                }
9135            }
9136        }
9137
9138        if (mIsolatedProcesses.size() > 0) {
9139            if (needSep) pw.println(" ");
9140            needSep = true;
9141            pw.println("  Isolated process list (sorted by uid):");
9142            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9143                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9144                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9145                    continue;
9146                }
9147                pw.println(String.format("%sIsolated #%2d: %s",
9148                        "    ", i, r.toString()));
9149            }
9150        }
9151
9152        if (mLruProcesses.size() > 0) {
9153            if (needSep) pw.println(" ");
9154            needSep = true;
9155            pw.println("  Process LRU list (sorted by oom_adj):");
9156            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9157                    "Proc", "PERS", false, dumpPackage);
9158            needSep = true;
9159        }
9160
9161        if (dumpAll) {
9162            synchronized (mPidsSelfLocked) {
9163                boolean printed = false;
9164                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9165                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9166                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9167                        continue;
9168                    }
9169                    if (!printed) {
9170                        if (needSep) pw.println(" ");
9171                        needSep = true;
9172                        pw.println("  PID mappings:");
9173                        printed = true;
9174                    }
9175                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9176                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9177                }
9178            }
9179        }
9180
9181        if (mForegroundProcesses.size() > 0) {
9182            synchronized (mPidsSelfLocked) {
9183                boolean printed = false;
9184                for (int i=0; i<mForegroundProcesses.size(); i++) {
9185                    ProcessRecord r = mPidsSelfLocked.get(
9186                            mForegroundProcesses.valueAt(i).pid);
9187                    if (dumpPackage != null && (r == null
9188                            || !dumpPackage.equals(r.info.packageName))) {
9189                        continue;
9190                    }
9191                    if (!printed) {
9192                        if (needSep) pw.println(" ");
9193                        needSep = true;
9194                        pw.println("  Foreground Processes:");
9195                        printed = true;
9196                    }
9197                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9198                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9199                }
9200            }
9201        }
9202
9203        if (mPersistentStartingProcesses.size() > 0) {
9204            if (needSep) pw.println(" ");
9205            needSep = true;
9206            pw.println("  Persisent processes that are starting:");
9207            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9208                    "Starting Norm", "Restarting PERS", dumpPackage);
9209        }
9210
9211        if (mRemovedProcesses.size() > 0) {
9212            if (needSep) pw.println(" ");
9213            needSep = true;
9214            pw.println("  Processes that are being removed:");
9215            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9216                    "Removed Norm", "Removed PERS", dumpPackage);
9217        }
9218
9219        if (mProcessesOnHold.size() > 0) {
9220            if (needSep) pw.println(" ");
9221            needSep = true;
9222            pw.println("  Processes that are on old until the system is ready:");
9223            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9224                    "OnHold Norm", "OnHold PERS", dumpPackage);
9225        }
9226
9227        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9228
9229        if (mProcessCrashTimes.getMap().size() > 0) {
9230            boolean printed = false;
9231            long now = SystemClock.uptimeMillis();
9232            for (Map.Entry<String, SparseArray<Long>> procs
9233                    : mProcessCrashTimes.getMap().entrySet()) {
9234                String pname = procs.getKey();
9235                SparseArray<Long> uids = procs.getValue();
9236                final int N = uids.size();
9237                for (int i=0; i<N; i++) {
9238                    int puid = uids.keyAt(i);
9239                    ProcessRecord r = mProcessNames.get(pname, puid);
9240                    if (dumpPackage != null && (r == null
9241                            || !dumpPackage.equals(r.info.packageName))) {
9242                        continue;
9243                    }
9244                    if (!printed) {
9245                        if (needSep) pw.println(" ");
9246                        needSep = true;
9247                        pw.println("  Time since processes crashed:");
9248                        printed = true;
9249                    }
9250                    pw.print("    Process "); pw.print(pname);
9251                            pw.print(" uid "); pw.print(puid);
9252                            pw.print(": last crashed ");
9253                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9254                            pw.println(" ago");
9255                }
9256            }
9257        }
9258
9259        if (mBadProcesses.getMap().size() > 0) {
9260            boolean printed = false;
9261            for (Map.Entry<String, SparseArray<Long>> procs
9262                    : mBadProcesses.getMap().entrySet()) {
9263                String pname = procs.getKey();
9264                SparseArray<Long> uids = procs.getValue();
9265                final int N = uids.size();
9266                for (int i=0; i<N; i++) {
9267                    int puid = uids.keyAt(i);
9268                    ProcessRecord r = mProcessNames.get(pname, puid);
9269                    if (dumpPackage != null && (r == null
9270                            || !dumpPackage.equals(r.info.packageName))) {
9271                        continue;
9272                    }
9273                    if (!printed) {
9274                        if (needSep) pw.println(" ");
9275                        needSep = true;
9276                        pw.println("  Bad processes:");
9277                    }
9278                    pw.print("    Bad process "); pw.print(pname);
9279                            pw.print(" uid "); pw.print(puid);
9280                            pw.print(": crashed at time ");
9281                            pw.println(uids.valueAt(i));
9282                }
9283            }
9284        }
9285
9286        pw.println();
9287        pw.println("  mStartedUsers:");
9288        for (int i=0; i<mStartedUsers.size(); i++) {
9289            UserStartedState uss = mStartedUsers.valueAt(i);
9290            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9291                    pw.print(": "); uss.dump("", pw);
9292        }
9293        pw.print("  mUserLru: [");
9294        for (int i=0; i<mUserLru.size(); i++) {
9295            if (i > 0) pw.print(", ");
9296            pw.print(mUserLru.get(i));
9297        }
9298        pw.println("]");
9299        if (dumpAll) {
9300            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9301        }
9302        pw.println("  mHomeProcess: " + mHomeProcess);
9303        pw.println("  mPreviousProcess: " + mPreviousProcess);
9304        if (dumpAll) {
9305            StringBuilder sb = new StringBuilder(128);
9306            sb.append("  mPreviousProcessVisibleTime: ");
9307            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9308            pw.println(sb);
9309        }
9310        if (mHeavyWeightProcess != null) {
9311            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9312        }
9313        pw.println("  mConfiguration: " + mConfiguration);
9314        if (dumpAll) {
9315            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9316            if (mCompatModePackages.getPackages().size() > 0) {
9317                boolean printed = false;
9318                for (Map.Entry<String, Integer> entry
9319                        : mCompatModePackages.getPackages().entrySet()) {
9320                    String pkg = entry.getKey();
9321                    int mode = entry.getValue();
9322                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9323                        continue;
9324                    }
9325                    if (!printed) {
9326                        pw.println("  mScreenCompatPackages:");
9327                        printed = true;
9328                    }
9329                    pw.print("    "); pw.print(pkg); pw.print(": ");
9330                            pw.print(mode); pw.println();
9331                }
9332            }
9333        }
9334        if (mSleeping || mWentToSleep || mLockScreenShown) {
9335            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9336                    + " mLockScreenShown " + mLockScreenShown);
9337        }
9338        if (mShuttingDown) {
9339            pw.println("  mShuttingDown=" + mShuttingDown);
9340        }
9341        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9342                || mOrigWaitForDebugger) {
9343            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9344                    + " mDebugTransient=" + mDebugTransient
9345                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9346        }
9347        if (mOpenGlTraceApp != null) {
9348            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9349        }
9350        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9351                || mProfileFd != null) {
9352            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9353            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9354            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9355                    + mAutoStopProfiler);
9356        }
9357        if (mAlwaysFinishActivities || mController != null) {
9358            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9359                    + " mController=" + mController);
9360        }
9361        if (dumpAll) {
9362            pw.println("  Total persistent processes: " + numPers);
9363            pw.println("  mStartRunning=" + mStartRunning
9364                    + " mProcessesReady=" + mProcessesReady
9365                    + " mSystemReady=" + mSystemReady);
9366            pw.println("  mBooting=" + mBooting
9367                    + " mBooted=" + mBooted
9368                    + " mFactoryTest=" + mFactoryTest);
9369            pw.print("  mLastPowerCheckRealtime=");
9370                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9371                    pw.println("");
9372            pw.print("  mLastPowerCheckUptime=");
9373                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9374                    pw.println("");
9375            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9376            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9377            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9378            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9379                    + " mNumHiddenProcs=" + mNumHiddenProcs
9380                    + " mNumServiceProcs=" + mNumServiceProcs
9381                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9382        }
9383
9384        return true;
9385    }
9386
9387    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9388            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9389        if (mProcessesToGc.size() > 0) {
9390            boolean printed = false;
9391            long now = SystemClock.uptimeMillis();
9392            for (int i=0; i<mProcessesToGc.size(); i++) {
9393                ProcessRecord proc = mProcessesToGc.get(i);
9394                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9395                    continue;
9396                }
9397                if (!printed) {
9398                    if (needSep) pw.println(" ");
9399                    needSep = true;
9400                    pw.println("  Processes that are waiting to GC:");
9401                    printed = true;
9402                }
9403                pw.print("    Process "); pw.println(proc);
9404                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9405                        pw.print(", last gced=");
9406                        pw.print(now-proc.lastRequestedGc);
9407                        pw.print(" ms ago, last lowMem=");
9408                        pw.print(now-proc.lastLowMemory);
9409                        pw.println(" ms ago");
9410
9411            }
9412        }
9413        return needSep;
9414    }
9415
9416    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9417            int opti, boolean dumpAll) {
9418        boolean needSep = false;
9419
9420        if (mLruProcesses.size() > 0) {
9421            if (needSep) pw.println(" ");
9422            needSep = true;
9423            pw.println("  OOM levels:");
9424            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9425            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9426            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9427            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9428            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9429            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9430            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9431            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9432            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9433            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9434            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9435            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9436            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9437
9438            if (needSep) pw.println(" ");
9439            needSep = true;
9440            pw.println("  Process OOM control:");
9441            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9442                    "Proc", "PERS", true, null);
9443            needSep = true;
9444        }
9445
9446        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9447
9448        pw.println();
9449        pw.println("  mHomeProcess: " + mHomeProcess);
9450        pw.println("  mPreviousProcess: " + mPreviousProcess);
9451        if (mHeavyWeightProcess != null) {
9452            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9453        }
9454
9455        return true;
9456    }
9457
9458    /**
9459     * There are three ways to call this:
9460     *  - no provider specified: dump all the providers
9461     *  - a flattened component name that matched an existing provider was specified as the
9462     *    first arg: dump that one provider
9463     *  - the first arg isn't the flattened component name of an existing provider:
9464     *    dump all providers whose component contains the first arg as a substring
9465     */
9466    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9467            int opti, boolean dumpAll) {
9468        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9469    }
9470
9471    static class ItemMatcher {
9472        ArrayList<ComponentName> components;
9473        ArrayList<String> strings;
9474        ArrayList<Integer> objects;
9475        boolean all;
9476
9477        ItemMatcher() {
9478            all = true;
9479        }
9480
9481        void build(String name) {
9482            ComponentName componentName = ComponentName.unflattenFromString(name);
9483            if (componentName != null) {
9484                if (components == null) {
9485                    components = new ArrayList<ComponentName>();
9486                }
9487                components.add(componentName);
9488                all = false;
9489            } else {
9490                int objectId = 0;
9491                // Not a '/' separated full component name; maybe an object ID?
9492                try {
9493                    objectId = Integer.parseInt(name, 16);
9494                    if (objects == null) {
9495                        objects = new ArrayList<Integer>();
9496                    }
9497                    objects.add(objectId);
9498                    all = false;
9499                } catch (RuntimeException e) {
9500                    // Not an integer; just do string match.
9501                    if (strings == null) {
9502                        strings = new ArrayList<String>();
9503                    }
9504                    strings.add(name);
9505                    all = false;
9506                }
9507            }
9508        }
9509
9510        int build(String[] args, int opti) {
9511            for (; opti<args.length; opti++) {
9512                String name = args[opti];
9513                if ("--".equals(name)) {
9514                    return opti+1;
9515                }
9516                build(name);
9517            }
9518            return opti;
9519        }
9520
9521        boolean match(Object object, ComponentName comp) {
9522            if (all) {
9523                return true;
9524            }
9525            if (components != null) {
9526                for (int i=0; i<components.size(); i++) {
9527                    if (components.get(i).equals(comp)) {
9528                        return true;
9529                    }
9530                }
9531            }
9532            if (objects != null) {
9533                for (int i=0; i<objects.size(); i++) {
9534                    if (System.identityHashCode(object) == objects.get(i)) {
9535                        return true;
9536                    }
9537                }
9538            }
9539            if (strings != null) {
9540                String flat = comp.flattenToString();
9541                for (int i=0; i<strings.size(); i++) {
9542                    if (flat.contains(strings.get(i))) {
9543                        return true;
9544                    }
9545                }
9546            }
9547            return false;
9548        }
9549    }
9550
9551    /**
9552     * There are three things that cmd can be:
9553     *  - a flattened component name that matches an existing activity
9554     *  - the cmd arg isn't the flattened component name of an existing activity:
9555     *    dump all activity whose component contains the cmd as a substring
9556     *  - A hex number of the ActivityRecord object instance.
9557     */
9558    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9559            int opti, boolean dumpAll) {
9560        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9561
9562        if ("all".equals(name)) {
9563            synchronized (this) {
9564                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9565                    activities.add(r1);
9566                }
9567            }
9568        } else if ("top".equals(name)) {
9569            synchronized (this) {
9570                final int N = mMainStack.mHistory.size();
9571                if (N > 0) {
9572                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9573                }
9574            }
9575        } else {
9576            ItemMatcher matcher = new ItemMatcher();
9577            matcher.build(name);
9578
9579            synchronized (this) {
9580                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9581                    if (matcher.match(r1, r1.intent.getComponent())) {
9582                        activities.add(r1);
9583                    }
9584                }
9585            }
9586        }
9587
9588        if (activities.size() <= 0) {
9589            return false;
9590        }
9591
9592        String[] newArgs = new String[args.length - opti];
9593        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9594
9595        TaskRecord lastTask = null;
9596        boolean needSep = false;
9597        for (int i=activities.size()-1; i>=0; i--) {
9598            ActivityRecord r = (ActivityRecord)activities.get(i);
9599            if (needSep) {
9600                pw.println();
9601            }
9602            needSep = true;
9603            synchronized (this) {
9604                if (lastTask != r.task) {
9605                    lastTask = r.task;
9606                    pw.print("TASK "); pw.print(lastTask.affinity);
9607                            pw.print(" id="); pw.println(lastTask.taskId);
9608                    if (dumpAll) {
9609                        lastTask.dump(pw, "  ");
9610                    }
9611                }
9612            }
9613            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9614        }
9615        return true;
9616    }
9617
9618    /**
9619     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9620     * there is a thread associated with the activity.
9621     */
9622    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9623            final ActivityRecord r, String[] args, boolean dumpAll) {
9624        String innerPrefix = prefix + "  ";
9625        synchronized (this) {
9626            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9627                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9628                    pw.print(" pid=");
9629                    if (r.app != null) pw.println(r.app.pid);
9630                    else pw.println("(not running)");
9631            if (dumpAll) {
9632                r.dump(pw, innerPrefix);
9633            }
9634        }
9635        if (r.app != null && r.app.thread != null) {
9636            // flush anything that is already in the PrintWriter since the thread is going
9637            // to write to the file descriptor directly
9638            pw.flush();
9639            try {
9640                TransferPipe tp = new TransferPipe();
9641                try {
9642                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9643                            r.appToken, innerPrefix, args);
9644                    tp.go(fd);
9645                } finally {
9646                    tp.kill();
9647                }
9648            } catch (IOException e) {
9649                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9650            } catch (RemoteException e) {
9651                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9652            }
9653        }
9654    }
9655
9656    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9657            int opti, boolean dumpAll, String dumpPackage) {
9658        boolean needSep = false;
9659        boolean onlyHistory = false;
9660
9661        if ("history".equals(dumpPackage)) {
9662            onlyHistory = true;
9663            dumpPackage = null;
9664        }
9665
9666        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9667        if (!onlyHistory && dumpAll) {
9668            if (mRegisteredReceivers.size() > 0) {
9669                boolean printed = false;
9670                Iterator it = mRegisteredReceivers.values().iterator();
9671                while (it.hasNext()) {
9672                    ReceiverList r = (ReceiverList)it.next();
9673                    if (dumpPackage != null && (r.app == null ||
9674                            !dumpPackage.equals(r.app.info.packageName))) {
9675                        continue;
9676                    }
9677                    if (!printed) {
9678                        pw.println("  Registered Receivers:");
9679                        needSep = true;
9680                        printed = true;
9681                    }
9682                    pw.print("  * "); pw.println(r);
9683                    r.dump(pw, "    ");
9684                }
9685            }
9686
9687            if (mReceiverResolver.dump(pw, needSep ?
9688                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9689                    "    ", dumpPackage, false)) {
9690                needSep = true;
9691            }
9692        }
9693
9694        for (BroadcastQueue q : mBroadcastQueues) {
9695            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9696        }
9697
9698        needSep = true;
9699
9700        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9701            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9702                if (needSep) {
9703                    pw.println();
9704                }
9705                needSep = true;
9706                pw.print("  Sticky broadcasts for user ");
9707                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9708                StringBuilder sb = new StringBuilder(128);
9709                for (Map.Entry<String, ArrayList<Intent>> ent
9710                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9711                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9712                    if (dumpAll) {
9713                        pw.println(":");
9714                        ArrayList<Intent> intents = ent.getValue();
9715                        final int N = intents.size();
9716                        for (int i=0; i<N; i++) {
9717                            sb.setLength(0);
9718                            sb.append("    Intent: ");
9719                            intents.get(i).toShortString(sb, false, true, false, false);
9720                            pw.println(sb.toString());
9721                            Bundle bundle = intents.get(i).getExtras();
9722                            if (bundle != null) {
9723                                pw.print("      ");
9724                                pw.println(bundle.toString());
9725                            }
9726                        }
9727                    } else {
9728                        pw.println("");
9729                    }
9730                }
9731            }
9732        }
9733
9734        if (!onlyHistory && dumpAll) {
9735            pw.println();
9736            for (BroadcastQueue queue : mBroadcastQueues) {
9737                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9738                        + queue.mBroadcastsScheduled);
9739            }
9740            pw.println("  mHandler:");
9741            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9742            needSep = true;
9743        }
9744
9745        return needSep;
9746    }
9747
9748    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9749            int opti, boolean dumpAll, String dumpPackage) {
9750        boolean needSep = true;
9751
9752        ItemMatcher matcher = new ItemMatcher();
9753        matcher.build(args, opti);
9754
9755        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9756
9757        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9758
9759        if (mLaunchingProviders.size() > 0) {
9760            boolean printed = false;
9761            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9762                ContentProviderRecord r = mLaunchingProviders.get(i);
9763                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9764                    continue;
9765                }
9766                if (!printed) {
9767                    if (needSep) pw.println(" ");
9768                    needSep = true;
9769                    pw.println("  Launching content providers:");
9770                    printed = true;
9771                }
9772                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9773                        pw.println(r);
9774            }
9775        }
9776
9777        if (mGrantedUriPermissions.size() > 0) {
9778            if (needSep) pw.println();
9779            needSep = true;
9780            pw.println("Granted Uri Permissions:");
9781            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9782                int uid = mGrantedUriPermissions.keyAt(i);
9783                HashMap<Uri, UriPermission> perms
9784                        = mGrantedUriPermissions.valueAt(i);
9785                pw.print("  * UID "); pw.print(uid);
9786                        pw.println(" holds:");
9787                for (UriPermission perm : perms.values()) {
9788                    pw.print("    "); pw.println(perm);
9789                    if (dumpAll) {
9790                        perm.dump(pw, "      ");
9791                    }
9792                }
9793            }
9794            needSep = true;
9795        }
9796
9797        return needSep;
9798    }
9799
9800    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9801            int opti, boolean dumpAll, String dumpPackage) {
9802        boolean needSep = false;
9803
9804        if (mIntentSenderRecords.size() > 0) {
9805            boolean printed = false;
9806            Iterator<WeakReference<PendingIntentRecord>> it
9807                    = mIntentSenderRecords.values().iterator();
9808            while (it.hasNext()) {
9809                WeakReference<PendingIntentRecord> ref = it.next();
9810                PendingIntentRecord rec = ref != null ? ref.get(): null;
9811                if (dumpPackage != null && (rec == null
9812                        || !dumpPackage.equals(rec.key.packageName))) {
9813                    continue;
9814                }
9815                if (!printed) {
9816                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9817                    printed = true;
9818                }
9819                needSep = true;
9820                if (rec != null) {
9821                    pw.print("  * "); pw.println(rec);
9822                    if (dumpAll) {
9823                        rec.dump(pw, "    ");
9824                    }
9825                } else {
9826                    pw.print("  * "); pw.println(ref);
9827                }
9828            }
9829        }
9830
9831        return needSep;
9832    }
9833
9834    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9835            String prefix, String label, boolean complete, boolean brief, boolean client,
9836            String dumpPackage) {
9837        TaskRecord lastTask = null;
9838        boolean needNL = false;
9839        final String innerPrefix = prefix + "      ";
9840        final String[] args = new String[0];
9841        for (int i=list.size()-1; i>=0; i--) {
9842            final ActivityRecord r = (ActivityRecord)list.get(i);
9843            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9844                continue;
9845            }
9846            final boolean full = !brief && (complete || !r.isInHistory());
9847            if (needNL) {
9848                pw.println(" ");
9849                needNL = false;
9850            }
9851            if (lastTask != r.task) {
9852                lastTask = r.task;
9853                pw.print(prefix);
9854                pw.print(full ? "* " : "  ");
9855                pw.println(lastTask);
9856                if (full) {
9857                    lastTask.dump(pw, prefix + "  ");
9858                } else if (complete) {
9859                    // Complete + brief == give a summary.  Isn't that obvious?!?
9860                    if (lastTask.intent != null) {
9861                        pw.print(prefix); pw.print("  ");
9862                                pw.println(lastTask.intent.toInsecureStringWithClip());
9863                    }
9864                }
9865            }
9866            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9867            pw.print(" #"); pw.print(i); pw.print(": ");
9868            pw.println(r);
9869            if (full) {
9870                r.dump(pw, innerPrefix);
9871            } else if (complete) {
9872                // Complete + brief == give a summary.  Isn't that obvious?!?
9873                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9874                if (r.app != null) {
9875                    pw.print(innerPrefix); pw.println(r.app);
9876                }
9877            }
9878            if (client && r.app != null && r.app.thread != null) {
9879                // flush anything that is already in the PrintWriter since the thread is going
9880                // to write to the file descriptor directly
9881                pw.flush();
9882                try {
9883                    TransferPipe tp = new TransferPipe();
9884                    try {
9885                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9886                                r.appToken, innerPrefix, args);
9887                        // Short timeout, since blocking here can
9888                        // deadlock with the application.
9889                        tp.go(fd, 2000);
9890                    } finally {
9891                        tp.kill();
9892                    }
9893                } catch (IOException e) {
9894                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9895                } catch (RemoteException e) {
9896                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9897                }
9898                needNL = true;
9899            }
9900        }
9901    }
9902
9903    private static String buildOomTag(String prefix, String space, int val, int base) {
9904        if (val == base) {
9905            if (space == null) return prefix;
9906            return prefix + "  ";
9907        }
9908        return prefix + "+" + Integer.toString(val-base);
9909    }
9910
9911    private static final int dumpProcessList(PrintWriter pw,
9912            ActivityManagerService service, List list,
9913            String prefix, String normalLabel, String persistentLabel,
9914            String dumpPackage) {
9915        int numPers = 0;
9916        final int N = list.size()-1;
9917        for (int i=N; i>=0; i--) {
9918            ProcessRecord r = (ProcessRecord)list.get(i);
9919            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9920                continue;
9921            }
9922            pw.println(String.format("%s%s #%2d: %s",
9923                    prefix, (r.persistent ? persistentLabel : normalLabel),
9924                    i, r.toString()));
9925            if (r.persistent) {
9926                numPers++;
9927            }
9928        }
9929        return numPers;
9930    }
9931
9932    private static final boolean dumpProcessOomList(PrintWriter pw,
9933            ActivityManagerService service, List<ProcessRecord> origList,
9934            String prefix, String normalLabel, String persistentLabel,
9935            boolean inclDetails, String dumpPackage) {
9936
9937        ArrayList<Pair<ProcessRecord, Integer>> list
9938                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9939        for (int i=0; i<origList.size(); i++) {
9940            ProcessRecord r = origList.get(i);
9941            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9942                continue;
9943            }
9944            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9945        }
9946
9947        if (list.size() <= 0) {
9948            return false;
9949        }
9950
9951        Comparator<Pair<ProcessRecord, Integer>> comparator
9952                = new Comparator<Pair<ProcessRecord, Integer>>() {
9953            @Override
9954            public int compare(Pair<ProcessRecord, Integer> object1,
9955                    Pair<ProcessRecord, Integer> object2) {
9956                if (object1.first.setAdj != object2.first.setAdj) {
9957                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9958                }
9959                if (object1.second.intValue() != object2.second.intValue()) {
9960                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9961                }
9962                return 0;
9963            }
9964        };
9965
9966        Collections.sort(list, comparator);
9967
9968        final long curRealtime = SystemClock.elapsedRealtime();
9969        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9970        final long curUptime = SystemClock.uptimeMillis();
9971        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9972
9973        for (int i=list.size()-1; i>=0; i--) {
9974            ProcessRecord r = list.get(i).first;
9975            String oomAdj;
9976            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9977                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9978            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9979                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9980            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9981                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9982            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9983                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9984            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9985                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9986            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9987                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9988            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9989                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9990            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9991                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9992            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9993                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9994            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9995                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9996            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9997                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9998            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9999                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10000            } else {
10001                oomAdj = Integer.toString(r.setAdj);
10002            }
10003            String schedGroup;
10004            switch (r.setSchedGroup) {
10005                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10006                    schedGroup = "B";
10007                    break;
10008                case Process.THREAD_GROUP_DEFAULT:
10009                    schedGroup = "F";
10010                    break;
10011                default:
10012                    schedGroup = Integer.toString(r.setSchedGroup);
10013                    break;
10014            }
10015            String foreground;
10016            if (r.foregroundActivities) {
10017                foreground = "A";
10018            } else if (r.foregroundServices) {
10019                foreground = "S";
10020            } else {
10021                foreground = " ";
10022            }
10023            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10024                    prefix, (r.persistent ? persistentLabel : normalLabel),
10025                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10026                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10027            if (r.adjSource != null || r.adjTarget != null) {
10028                pw.print(prefix);
10029                pw.print("    ");
10030                if (r.adjTarget instanceof ComponentName) {
10031                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10032                } else if (r.adjTarget != null) {
10033                    pw.print(r.adjTarget.toString());
10034                } else {
10035                    pw.print("{null}");
10036                }
10037                pw.print("<=");
10038                if (r.adjSource instanceof ProcessRecord) {
10039                    pw.print("Proc{");
10040                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10041                    pw.println("}");
10042                } else if (r.adjSource != null) {
10043                    pw.println(r.adjSource.toString());
10044                } else {
10045                    pw.println("{null}");
10046                }
10047            }
10048            if (inclDetails) {
10049                pw.print(prefix);
10050                pw.print("    ");
10051                pw.print("oom: max="); pw.print(r.maxAdj);
10052                pw.print(" hidden="); pw.print(r.hiddenAdj);
10053                pw.print(" client="); pw.print(r.clientHiddenAdj);
10054                pw.print(" empty="); pw.print(r.emptyAdj);
10055                pw.print(" curRaw="); pw.print(r.curRawAdj);
10056                pw.print(" setRaw="); pw.print(r.setRawAdj);
10057                pw.print(" cur="); pw.print(r.curAdj);
10058                pw.print(" set="); pw.println(r.setAdj);
10059                pw.print(prefix);
10060                pw.print("    ");
10061                pw.print("keeping="); pw.print(r.keeping);
10062                pw.print(" hidden="); pw.print(r.hidden);
10063                pw.print(" empty="); pw.print(r.empty);
10064                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10065
10066                if (!r.keeping) {
10067                    if (r.lastWakeTime != 0) {
10068                        long wtime;
10069                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10070                        synchronized (stats) {
10071                            wtime = stats.getProcessWakeTime(r.info.uid,
10072                                    r.pid, curRealtime);
10073                        }
10074                        long timeUsed = wtime - r.lastWakeTime;
10075                        pw.print(prefix);
10076                        pw.print("    ");
10077                        pw.print("keep awake over ");
10078                        TimeUtils.formatDuration(realtimeSince, pw);
10079                        pw.print(" used ");
10080                        TimeUtils.formatDuration(timeUsed, pw);
10081                        pw.print(" (");
10082                        pw.print((timeUsed*100)/realtimeSince);
10083                        pw.println("%)");
10084                    }
10085                    if (r.lastCpuTime != 0) {
10086                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10087                        pw.print(prefix);
10088                        pw.print("    ");
10089                        pw.print("run cpu over ");
10090                        TimeUtils.formatDuration(uptimeSince, pw);
10091                        pw.print(" used ");
10092                        TimeUtils.formatDuration(timeUsed, pw);
10093                        pw.print(" (");
10094                        pw.print((timeUsed*100)/uptimeSince);
10095                        pw.println("%)");
10096                    }
10097                }
10098            }
10099        }
10100        return true;
10101    }
10102
10103    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10104        ArrayList<ProcessRecord> procs;
10105        synchronized (this) {
10106            if (args != null && args.length > start
10107                    && args[start].charAt(0) != '-') {
10108                procs = new ArrayList<ProcessRecord>();
10109                int pid = -1;
10110                try {
10111                    pid = Integer.parseInt(args[start]);
10112                } catch (NumberFormatException e) {
10113
10114                }
10115                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10116                    ProcessRecord proc = mLruProcesses.get(i);
10117                    if (proc.pid == pid) {
10118                        procs.add(proc);
10119                    } else if (proc.processName.equals(args[start])) {
10120                        procs.add(proc);
10121                    }
10122                }
10123                if (procs.size() <= 0) {
10124                    pw.println("No process found for: " + args[start]);
10125                    return null;
10126                }
10127            } else {
10128                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10129            }
10130        }
10131        return procs;
10132    }
10133
10134    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10135            PrintWriter pw, String[] args) {
10136        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10137        if (procs == null) {
10138            return;
10139        }
10140
10141        long uptime = SystemClock.uptimeMillis();
10142        long realtime = SystemClock.elapsedRealtime();
10143        pw.println("Applications Graphics Acceleration Info:");
10144        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10145
10146        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10147            ProcessRecord r = procs.get(i);
10148            if (r.thread != null) {
10149                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10150                pw.flush();
10151                try {
10152                    TransferPipe tp = new TransferPipe();
10153                    try {
10154                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10155                        tp.go(fd);
10156                    } finally {
10157                        tp.kill();
10158                    }
10159                } catch (IOException e) {
10160                    pw.println("Failure while dumping the app: " + r);
10161                    pw.flush();
10162                } catch (RemoteException e) {
10163                    pw.println("Got a RemoteException while dumping the app " + r);
10164                    pw.flush();
10165                }
10166            }
10167        }
10168    }
10169
10170    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10171        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10172        if (procs == null) {
10173            return;
10174        }
10175
10176        pw.println("Applications Database Info:");
10177
10178        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10179            ProcessRecord r = procs.get(i);
10180            if (r.thread != null) {
10181                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10182                pw.flush();
10183                try {
10184                    TransferPipe tp = new TransferPipe();
10185                    try {
10186                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10187                        tp.go(fd);
10188                    } finally {
10189                        tp.kill();
10190                    }
10191                } catch (IOException e) {
10192                    pw.println("Failure while dumping the app: " + r);
10193                    pw.flush();
10194                } catch (RemoteException e) {
10195                    pw.println("Got a RemoteException while dumping the app " + r);
10196                    pw.flush();
10197                }
10198            }
10199        }
10200    }
10201
10202    final static class MemItem {
10203        final String label;
10204        final String shortLabel;
10205        final long pss;
10206        final int id;
10207        ArrayList<MemItem> subitems;
10208
10209        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10210            label = _label;
10211            shortLabel = _shortLabel;
10212            pss = _pss;
10213            id = _id;
10214        }
10215    }
10216
10217    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10218            boolean sort) {
10219        if (sort) {
10220            Collections.sort(items, new Comparator<MemItem>() {
10221                @Override
10222                public int compare(MemItem lhs, MemItem rhs) {
10223                    if (lhs.pss < rhs.pss) {
10224                        return 1;
10225                    } else if (lhs.pss > rhs.pss) {
10226                        return -1;
10227                    }
10228                    return 0;
10229                }
10230            });
10231        }
10232
10233        for (int i=0; i<items.size(); i++) {
10234            MemItem mi = items.get(i);
10235            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10236            if (mi.subitems != null) {
10237                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10238            }
10239        }
10240    }
10241
10242    // These are in KB.
10243    static final long[] DUMP_MEM_BUCKETS = new long[] {
10244        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10245        120*1024, 160*1024, 200*1024,
10246        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10247        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10248    };
10249
10250    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10251            boolean stackLike) {
10252        int start = label.lastIndexOf('.');
10253        if (start >= 0) start++;
10254        else start = 0;
10255        int end = label.length();
10256        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10257            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10258                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10259                out.append(bucket);
10260                out.append(stackLike ? "MB." : "MB ");
10261                out.append(label, start, end);
10262                return;
10263            }
10264        }
10265        out.append(memKB/1024);
10266        out.append(stackLike ? "MB." : "MB ");
10267        out.append(label, start, end);
10268    }
10269
10270    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10271            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10272            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10273            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10274            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10275    };
10276    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10277            "System", "Persistent", "Foreground",
10278            "Visible", "Perceptible", "Heavy Weight",
10279            "Backup", "A Services", "Home", "Previous",
10280            "B Services", "Background"
10281    };
10282
10283    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10284            PrintWriter pw, String prefix, String[] args, boolean brief,
10285            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10286        boolean dumpAll = false;
10287        boolean oomOnly = false;
10288
10289        int opti = 0;
10290        while (opti < args.length) {
10291            String opt = args[opti];
10292            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10293                break;
10294            }
10295            opti++;
10296            if ("-a".equals(opt)) {
10297                dumpAll = true;
10298            } else if ("--oom".equals(opt)) {
10299                oomOnly = true;
10300            } else if ("-h".equals(opt)) {
10301                pw.println("meminfo dump options: [-a] [--oom] [process]");
10302                pw.println("  -a: include all available information for each process.");
10303                pw.println("  --oom: only show processes organized by oom adj.");
10304                pw.println("If [process] is specified it can be the name or ");
10305                pw.println("pid of a specific process to dump.");
10306                return;
10307            } else {
10308                pw.println("Unknown argument: " + opt + "; use -h for help");
10309            }
10310        }
10311
10312        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10313        if (procs == null) {
10314            return;
10315        }
10316
10317        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10318        long uptime = SystemClock.uptimeMillis();
10319        long realtime = SystemClock.elapsedRealtime();
10320
10321        if (procs.size() == 1 || isCheckinRequest) {
10322            dumpAll = true;
10323        }
10324
10325        if (isCheckinRequest) {
10326            // short checkin version
10327            pw.println(uptime + "," + realtime);
10328            pw.flush();
10329        } else {
10330            pw.println("Applications Memory Usage (kB):");
10331            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10332        }
10333
10334        String[] innerArgs = new String[args.length-opti];
10335        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10336
10337        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10338        long nativePss=0, dalvikPss=0, otherPss=0;
10339        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10340
10341        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10342        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10343                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10344
10345        long totalPss = 0;
10346
10347        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10348            ProcessRecord r = procs.get(i);
10349            if (r.thread != null) {
10350                if (!isCheckinRequest && dumpAll) {
10351                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10352                    pw.flush();
10353                }
10354                Debug.MemoryInfo mi = null;
10355                if (dumpAll) {
10356                    try {
10357                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10358                    } catch (RemoteException e) {
10359                        if (!isCheckinRequest) {
10360                            pw.println("Got RemoteException!");
10361                            pw.flush();
10362                        }
10363                    }
10364                } else {
10365                    mi = new Debug.MemoryInfo();
10366                    Debug.getMemoryInfo(r.pid, mi);
10367                }
10368
10369                if (!isCheckinRequest && mi != null) {
10370                    long myTotalPss = mi.getTotalPss();
10371                    totalPss += myTotalPss;
10372                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10373                            r.processName, myTotalPss, 0);
10374                    procMems.add(pssItem);
10375
10376                    nativePss += mi.nativePss;
10377                    dalvikPss += mi.dalvikPss;
10378                    otherPss += mi.otherPss;
10379                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10380                        long mem = mi.getOtherPss(j);
10381                        miscPss[j] += mem;
10382                        otherPss -= mem;
10383                    }
10384
10385                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10386                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10387                                || oomIndex == (oomPss.length-1)) {
10388                            oomPss[oomIndex] += myTotalPss;
10389                            if (oomProcs[oomIndex] == null) {
10390                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10391                            }
10392                            oomProcs[oomIndex].add(pssItem);
10393                            break;
10394                        }
10395                    }
10396                }
10397            }
10398        }
10399
10400        if (!isCheckinRequest && procs.size() > 1) {
10401            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10402
10403            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10404            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10405            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10406            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10407                String label = Debug.MemoryInfo.getOtherLabel(j);
10408                catMems.add(new MemItem(label, label, miscPss[j], j));
10409            }
10410
10411            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10412            for (int j=0; j<oomPss.length; j++) {
10413                if (oomPss[j] != 0) {
10414                    String label = DUMP_MEM_OOM_LABEL[j];
10415                    MemItem item = new MemItem(label, label, oomPss[j],
10416                            DUMP_MEM_OOM_ADJ[j]);
10417                    item.subitems = oomProcs[j];
10418                    oomMems.add(item);
10419                }
10420            }
10421
10422            if (outTag != null || outStack != null) {
10423                if (outTag != null) {
10424                    appendMemBucket(outTag, totalPss, "total", false);
10425                }
10426                if (outStack != null) {
10427                    appendMemBucket(outStack, totalPss, "total", true);
10428                }
10429                boolean firstLine = true;
10430                for (int i=0; i<oomMems.size(); i++) {
10431                    MemItem miCat = oomMems.get(i);
10432                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10433                        continue;
10434                    }
10435                    if (miCat.id < ProcessList.SERVICE_ADJ
10436                            || miCat.id == ProcessList.HOME_APP_ADJ
10437                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10438                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10439                            outTag.append(" / ");
10440                        }
10441                        if (outStack != null) {
10442                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10443                                if (firstLine) {
10444                                    outStack.append(":");
10445                                    firstLine = false;
10446                                }
10447                                outStack.append("\n\t at ");
10448                            } else {
10449                                outStack.append("$");
10450                            }
10451                        }
10452                        for (int j=0; j<miCat.subitems.size(); j++) {
10453                            MemItem mi = miCat.subitems.get(j);
10454                            if (j > 0) {
10455                                if (outTag != null) {
10456                                    outTag.append(" ");
10457                                }
10458                                if (outStack != null) {
10459                                    outStack.append("$");
10460                                }
10461                            }
10462                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10463                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10464                            }
10465                            if (outStack != null) {
10466                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10467                            }
10468                        }
10469                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10470                            outStack.append("(");
10471                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10472                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10473                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10474                                    outStack.append(":");
10475                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10476                                }
10477                            }
10478                            outStack.append(")");
10479                        }
10480                    }
10481                }
10482            }
10483
10484            if (!brief && !oomOnly) {
10485                pw.println();
10486                pw.println("Total PSS by process:");
10487                dumpMemItems(pw, "  ", procMems, true);
10488                pw.println();
10489            }
10490            pw.println("Total PSS by OOM adjustment:");
10491            dumpMemItems(pw, "  ", oomMems, false);
10492            if (!oomOnly) {
10493                PrintWriter out = categoryPw != null ? categoryPw : pw;
10494                out.println();
10495                out.println("Total PSS by category:");
10496                dumpMemItems(out, "  ", catMems, true);
10497            }
10498            pw.println();
10499            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10500            final int[] SINGLE_LONG_FORMAT = new int[] {
10501                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10502            };
10503            long[] longOut = new long[1];
10504            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10505                    SINGLE_LONG_FORMAT, null, longOut, null);
10506            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10507            longOut[0] = 0;
10508            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10509                    SINGLE_LONG_FORMAT, null, longOut, null);
10510            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10511            longOut[0] = 0;
10512            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10513                    SINGLE_LONG_FORMAT, null, longOut, null);
10514            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10515            longOut[0] = 0;
10516            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10517                    SINGLE_LONG_FORMAT, null, longOut, null);
10518            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10519            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10520                    pw.print(shared); pw.println(" kB");
10521            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10522                    pw.print(voltile); pw.println(" kB volatile");
10523        }
10524    }
10525
10526    /**
10527     * Searches array of arguments for the specified string
10528     * @param args array of argument strings
10529     * @param value value to search for
10530     * @return true if the value is contained in the array
10531     */
10532    private static boolean scanArgs(String[] args, String value) {
10533        if (args != null) {
10534            for (String arg : args) {
10535                if (value.equals(arg)) {
10536                    return true;
10537                }
10538            }
10539        }
10540        return false;
10541    }
10542
10543    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10544            ContentProviderRecord cpr, boolean always) {
10545        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10546
10547        if (!inLaunching || always) {
10548            synchronized (cpr) {
10549                cpr.launchingApp = null;
10550                cpr.notifyAll();
10551            }
10552            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10553            String names[] = cpr.info.authority.split(";");
10554            for (int j = 0; j < names.length; j++) {
10555                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10556            }
10557        }
10558
10559        for (int i=0; i<cpr.connections.size(); i++) {
10560            ContentProviderConnection conn = cpr.connections.get(i);
10561            if (conn.waiting) {
10562                // If this connection is waiting for the provider, then we don't
10563                // need to mess with its process unless we are always removing
10564                // or for some reason the provider is not currently launching.
10565                if (inLaunching && !always) {
10566                    continue;
10567                }
10568            }
10569            ProcessRecord capp = conn.client;
10570            conn.dead = true;
10571            if (conn.stableCount > 0) {
10572                if (!capp.persistent && capp.thread != null
10573                        && capp.pid != 0
10574                        && capp.pid != MY_PID) {
10575                    Slog.i(TAG, "Kill " + capp.processName
10576                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10577                            + " in dying process " + (proc != null ? proc.processName : "??"));
10578                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10579                            capp.processName, capp.setAdj, "dying provider "
10580                                    + cpr.name.toShortString());
10581                    Process.killProcessQuiet(capp.pid);
10582                }
10583            } else if (capp.thread != null && conn.provider.provider != null) {
10584                try {
10585                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10586                } catch (RemoteException e) {
10587                }
10588                // In the protocol here, we don't expect the client to correctly
10589                // clean up this connection, we'll just remove it.
10590                cpr.connections.remove(i);
10591                conn.client.conProviders.remove(conn);
10592            }
10593        }
10594
10595        if (inLaunching && always) {
10596            mLaunchingProviders.remove(cpr);
10597        }
10598        return inLaunching;
10599    }
10600
10601    /**
10602     * Main code for cleaning up a process when it has gone away.  This is
10603     * called both as a result of the process dying, or directly when stopping
10604     * a process when running in single process mode.
10605     */
10606    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10607            boolean restarting, boolean allowRestart, int index) {
10608        if (index >= 0) {
10609            mLruProcesses.remove(index);
10610        }
10611
10612        mProcessesToGc.remove(app);
10613
10614        // Dismiss any open dialogs.
10615        if (app.crashDialog != null) {
10616            app.crashDialog.dismiss();
10617            app.crashDialog = null;
10618        }
10619        if (app.anrDialog != null) {
10620            app.anrDialog.dismiss();
10621            app.anrDialog = null;
10622        }
10623        if (app.waitDialog != null) {
10624            app.waitDialog.dismiss();
10625            app.waitDialog = null;
10626        }
10627
10628        app.crashing = false;
10629        app.notResponding = false;
10630
10631        app.resetPackageList();
10632        app.unlinkDeathRecipient();
10633        app.thread = null;
10634        app.forcingToForeground = null;
10635        app.foregroundServices = false;
10636        app.foregroundActivities = false;
10637        app.hasShownUi = false;
10638        app.hasAboveClient = false;
10639
10640        mServices.killServicesLocked(app, allowRestart);
10641
10642        boolean restart = false;
10643
10644        // Remove published content providers.
10645        if (!app.pubProviders.isEmpty()) {
10646            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10647            while (it.hasNext()) {
10648                ContentProviderRecord cpr = it.next();
10649
10650                final boolean always = app.bad || !allowRestart;
10651                if (removeDyingProviderLocked(app, cpr, always) || always) {
10652                    // We left the provider in the launching list, need to
10653                    // restart it.
10654                    restart = true;
10655                }
10656
10657                cpr.provider = null;
10658                cpr.proc = null;
10659            }
10660            app.pubProviders.clear();
10661        }
10662
10663        // Take care of any launching providers waiting for this process.
10664        if (checkAppInLaunchingProvidersLocked(app, false)) {
10665            restart = true;
10666        }
10667
10668        // Unregister from connected content providers.
10669        if (!app.conProviders.isEmpty()) {
10670            for (int i=0; i<app.conProviders.size(); i++) {
10671                ContentProviderConnection conn = app.conProviders.get(i);
10672                conn.provider.connections.remove(conn);
10673            }
10674            app.conProviders.clear();
10675        }
10676
10677        // At this point there may be remaining entries in mLaunchingProviders
10678        // where we were the only one waiting, so they are no longer of use.
10679        // Look for these and clean up if found.
10680        // XXX Commented out for now.  Trying to figure out a way to reproduce
10681        // the actual situation to identify what is actually going on.
10682        if (false) {
10683            for (int i=0; i<mLaunchingProviders.size(); i++) {
10684                ContentProviderRecord cpr = (ContentProviderRecord)
10685                        mLaunchingProviders.get(i);
10686                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10687                    synchronized (cpr) {
10688                        cpr.launchingApp = null;
10689                        cpr.notifyAll();
10690                    }
10691                }
10692            }
10693        }
10694
10695        skipCurrentReceiverLocked(app);
10696
10697        // Unregister any receivers.
10698        if (app.receivers.size() > 0) {
10699            Iterator<ReceiverList> it = app.receivers.iterator();
10700            while (it.hasNext()) {
10701                removeReceiverLocked(it.next());
10702            }
10703            app.receivers.clear();
10704        }
10705
10706        // If the app is undergoing backup, tell the backup manager about it
10707        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10708            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10709                    + mBackupTarget.appInfo + " died during backup");
10710            try {
10711                IBackupManager bm = IBackupManager.Stub.asInterface(
10712                        ServiceManager.getService(Context.BACKUP_SERVICE));
10713                bm.agentDisconnected(app.info.packageName);
10714            } catch (RemoteException e) {
10715                // can't happen; backup manager is local
10716            }
10717        }
10718
10719        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10720            ProcessChangeItem item = mPendingProcessChanges.get(i);
10721            if (item.pid == app.pid) {
10722                mPendingProcessChanges.remove(i);
10723                mAvailProcessChanges.add(item);
10724            }
10725        }
10726        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10727
10728        // If the caller is restarting this app, then leave it in its
10729        // current lists and let the caller take care of it.
10730        if (restarting) {
10731            return;
10732        }
10733
10734        if (!app.persistent || app.isolated) {
10735            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10736                    "Removing non-persistent process during cleanup: " + app);
10737            mProcessNames.remove(app.processName, app.uid);
10738            mIsolatedProcesses.remove(app.uid);
10739            if (mHeavyWeightProcess == app) {
10740                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10741                        mHeavyWeightProcess.userId, 0));
10742                mHeavyWeightProcess = null;
10743            }
10744        } else if (!app.removed) {
10745            // This app is persistent, so we need to keep its record around.
10746            // If it is not already on the pending app list, add it there
10747            // and start a new process for it.
10748            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10749                mPersistentStartingProcesses.add(app);
10750                restart = true;
10751            }
10752        }
10753        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10754                "Clean-up removing on hold: " + app);
10755        mProcessesOnHold.remove(app);
10756
10757        if (app == mHomeProcess) {
10758            mHomeProcess = null;
10759        }
10760        if (app == mPreviousProcess) {
10761            mPreviousProcess = null;
10762        }
10763
10764        if (restart && !app.isolated) {
10765            // We have components that still need to be running in the
10766            // process, so re-launch it.
10767            mProcessNames.put(app.processName, app.uid, app);
10768            startProcessLocked(app, "restart", app.processName);
10769        } else if (app.pid > 0 && app.pid != MY_PID) {
10770            // Goodbye!
10771            synchronized (mPidsSelfLocked) {
10772                mPidsSelfLocked.remove(app.pid);
10773                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10774            }
10775            app.setPid(0);
10776        }
10777    }
10778
10779    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10780        // Look through the content providers we are waiting to have launched,
10781        // and if any run in this process then either schedule a restart of
10782        // the process or kill the client waiting for it if this process has
10783        // gone bad.
10784        int NL = mLaunchingProviders.size();
10785        boolean restart = false;
10786        for (int i=0; i<NL; i++) {
10787            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10788            if (cpr.launchingApp == app) {
10789                if (!alwaysBad && !app.bad) {
10790                    restart = true;
10791                } else {
10792                    removeDyingProviderLocked(app, cpr, true);
10793                    // cpr should have been removed from mLaunchingProviders
10794                    NL = mLaunchingProviders.size();
10795                    i--;
10796                }
10797            }
10798        }
10799        return restart;
10800    }
10801
10802    // =========================================================
10803    // SERVICES
10804    // =========================================================
10805
10806    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10807            int flags) {
10808        enforceNotIsolatedCaller("getServices");
10809        synchronized (this) {
10810            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10811        }
10812    }
10813
10814    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10815        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10816        synchronized (this) {
10817            return mServices.getRunningServiceControlPanelLocked(name);
10818        }
10819    }
10820
10821    public ComponentName startService(IApplicationThread caller, Intent service,
10822            String resolvedType, int userId) {
10823        enforceNotIsolatedCaller("startService");
10824        // Refuse possible leaked file descriptors
10825        if (service != null && service.hasFileDescriptors() == true) {
10826            throw new IllegalArgumentException("File descriptors passed in Intent");
10827        }
10828
10829        if (DEBUG_SERVICE)
10830            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10831        synchronized(this) {
10832            final int callingPid = Binder.getCallingPid();
10833            final int callingUid = Binder.getCallingUid();
10834            checkValidCaller(callingUid, userId);
10835            final long origId = Binder.clearCallingIdentity();
10836            ComponentName res = mServices.startServiceLocked(caller, service,
10837                    resolvedType, callingPid, callingUid, userId);
10838            Binder.restoreCallingIdentity(origId);
10839            return res;
10840        }
10841    }
10842
10843    ComponentName startServiceInPackage(int uid,
10844            Intent service, String resolvedType, int userId) {
10845        synchronized(this) {
10846            if (DEBUG_SERVICE)
10847                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10848            final long origId = Binder.clearCallingIdentity();
10849            ComponentName res = mServices.startServiceLocked(null, service,
10850                    resolvedType, -1, uid, userId);
10851            Binder.restoreCallingIdentity(origId);
10852            return res;
10853        }
10854    }
10855
10856    public int stopService(IApplicationThread caller, Intent service,
10857            String resolvedType, int userId) {
10858        enforceNotIsolatedCaller("stopService");
10859        // Refuse possible leaked file descriptors
10860        if (service != null && service.hasFileDescriptors() == true) {
10861            throw new IllegalArgumentException("File descriptors passed in Intent");
10862        }
10863
10864        checkValidCaller(Binder.getCallingUid(), userId);
10865
10866        synchronized(this) {
10867            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10868        }
10869    }
10870
10871    public IBinder peekService(Intent service, String resolvedType) {
10872        enforceNotIsolatedCaller("peekService");
10873        // Refuse possible leaked file descriptors
10874        if (service != null && service.hasFileDescriptors() == true) {
10875            throw new IllegalArgumentException("File descriptors passed in Intent");
10876        }
10877        synchronized(this) {
10878            return mServices.peekServiceLocked(service, resolvedType);
10879        }
10880    }
10881
10882    public boolean stopServiceToken(ComponentName className, IBinder token,
10883            int startId) {
10884        synchronized(this) {
10885            return mServices.stopServiceTokenLocked(className, token, startId);
10886        }
10887    }
10888
10889    public void setServiceForeground(ComponentName className, IBinder token,
10890            int id, Notification notification, boolean removeNotification) {
10891        synchronized(this) {
10892            mServices.setServiceForegroundLocked(className, token, id, notification,
10893                    removeNotification);
10894        }
10895    }
10896
10897    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10898            boolean requireFull, String name, String callerPackage) {
10899        final int callingUserId = UserHandle.getUserId(callingUid);
10900        if (callingUserId != userId) {
10901            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10902                if ((requireFull || checkComponentPermission(
10903                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10904                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10905                        && checkComponentPermission(
10906                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10907                                callingPid, callingUid, -1, true)
10908                                != PackageManager.PERMISSION_GRANTED) {
10909                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10910                        // In this case, they would like to just execute as their
10911                        // owner user instead of failing.
10912                        userId = callingUserId;
10913                    } else {
10914                        StringBuilder builder = new StringBuilder(128);
10915                        builder.append("Permission Denial: ");
10916                        builder.append(name);
10917                        if (callerPackage != null) {
10918                            builder.append(" from ");
10919                            builder.append(callerPackage);
10920                        }
10921                        builder.append(" asks to run as user ");
10922                        builder.append(userId);
10923                        builder.append(" but is calling from user ");
10924                        builder.append(UserHandle.getUserId(callingUid));
10925                        builder.append("; this requires ");
10926                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10927                        if (!requireFull) {
10928                            builder.append(" or ");
10929                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10930                        }
10931                        String msg = builder.toString();
10932                        Slog.w(TAG, msg);
10933                        throw new SecurityException(msg);
10934                    }
10935                }
10936            }
10937            if (userId == UserHandle.USER_CURRENT
10938                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10939                // Note that we may be accessing this outside of a lock...
10940                // shouldn't be a big deal, if this is being called outside
10941                // of a locked context there is intrinsically a race with
10942                // the value the caller will receive and someone else changing it.
10943                userId = mCurrentUserId;
10944            }
10945            if (!allowAll && userId < 0) {
10946                throw new IllegalArgumentException(
10947                        "Call does not support special user #" + userId);
10948            }
10949        }
10950        return userId;
10951    }
10952
10953    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10954            String className, int flags) {
10955        boolean result = false;
10956        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10957            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10958                if (ActivityManager.checkUidPermission(
10959                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10960                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10961                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10962                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10963                            + " requests FLAG_SINGLE_USER, but app does not hold "
10964                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10965                    Slog.w(TAG, msg);
10966                    throw new SecurityException(msg);
10967                }
10968                result = true;
10969            }
10970        } else if (componentProcessName == aInfo.packageName) {
10971            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10972        } else if ("system".equals(componentProcessName)) {
10973            result = true;
10974        }
10975        if (DEBUG_MU) {
10976            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10977                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10978        }
10979        return result;
10980    }
10981
10982    public int bindService(IApplicationThread caller, IBinder token,
10983            Intent service, String resolvedType,
10984            IServiceConnection connection, int flags, int userId) {
10985        enforceNotIsolatedCaller("bindService");
10986        // Refuse possible leaked file descriptors
10987        if (service != null && service.hasFileDescriptors() == true) {
10988            throw new IllegalArgumentException("File descriptors passed in Intent");
10989        }
10990
10991        synchronized(this) {
10992            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10993                    connection, flags, userId);
10994        }
10995    }
10996
10997    public boolean unbindService(IServiceConnection connection) {
10998        synchronized (this) {
10999            return mServices.unbindServiceLocked(connection);
11000        }
11001    }
11002
11003    public void publishService(IBinder token, Intent intent, IBinder service) {
11004        // Refuse possible leaked file descriptors
11005        if (intent != null && intent.hasFileDescriptors() == true) {
11006            throw new IllegalArgumentException("File descriptors passed in Intent");
11007        }
11008
11009        synchronized(this) {
11010            if (!(token instanceof ServiceRecord)) {
11011                throw new IllegalArgumentException("Invalid service token");
11012            }
11013            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11014        }
11015    }
11016
11017    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11018        // Refuse possible leaked file descriptors
11019        if (intent != null && intent.hasFileDescriptors() == true) {
11020            throw new IllegalArgumentException("File descriptors passed in Intent");
11021        }
11022
11023        synchronized(this) {
11024            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11025        }
11026    }
11027
11028    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11029        synchronized(this) {
11030            if (!(token instanceof ServiceRecord)) {
11031                throw new IllegalArgumentException("Invalid service token");
11032            }
11033            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11034        }
11035    }
11036
11037    // =========================================================
11038    // BACKUP AND RESTORE
11039    // =========================================================
11040
11041    // Cause the target app to be launched if necessary and its backup agent
11042    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11043    // activity manager to announce its creation.
11044    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11045        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11046        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11047
11048        synchronized(this) {
11049            // !!! TODO: currently no check here that we're already bound
11050            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11051            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11052            synchronized (stats) {
11053                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11054            }
11055
11056            // Backup agent is now in use, its package can't be stopped.
11057            try {
11058                AppGlobals.getPackageManager().setPackageStoppedState(
11059                        app.packageName, false, UserHandle.getUserId(app.uid));
11060            } catch (RemoteException e) {
11061            } catch (IllegalArgumentException e) {
11062                Slog.w(TAG, "Failed trying to unstop package "
11063                        + app.packageName + ": " + e);
11064            }
11065
11066            BackupRecord r = new BackupRecord(ss, app, backupMode);
11067            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11068                    ? new ComponentName(app.packageName, app.backupAgentName)
11069                    : new ComponentName("android", "FullBackupAgent");
11070            // startProcessLocked() returns existing proc's record if it's already running
11071            ProcessRecord proc = startProcessLocked(app.processName, app,
11072                    false, 0, "backup", hostingName, false, false);
11073            if (proc == null) {
11074                Slog.e(TAG, "Unable to start backup agent process " + r);
11075                return false;
11076            }
11077
11078            r.app = proc;
11079            mBackupTarget = r;
11080            mBackupAppName = app.packageName;
11081
11082            // Try not to kill the process during backup
11083            updateOomAdjLocked(proc);
11084
11085            // If the process is already attached, schedule the creation of the backup agent now.
11086            // If it is not yet live, this will be done when it attaches to the framework.
11087            if (proc.thread != null) {
11088                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11089                try {
11090                    proc.thread.scheduleCreateBackupAgent(app,
11091                            compatibilityInfoForPackageLocked(app), backupMode);
11092                } catch (RemoteException e) {
11093                    // Will time out on the backup manager side
11094                }
11095            } else {
11096                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11097            }
11098            // Invariants: at this point, the target app process exists and the application
11099            // is either already running or in the process of coming up.  mBackupTarget and
11100            // mBackupAppName describe the app, so that when it binds back to the AM we
11101            // know that it's scheduled for a backup-agent operation.
11102        }
11103
11104        return true;
11105    }
11106
11107    // A backup agent has just come up
11108    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11109        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11110                + " = " + agent);
11111
11112        synchronized(this) {
11113            if (!agentPackageName.equals(mBackupAppName)) {
11114                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11115                return;
11116            }
11117        }
11118
11119        long oldIdent = Binder.clearCallingIdentity();
11120        try {
11121            IBackupManager bm = IBackupManager.Stub.asInterface(
11122                    ServiceManager.getService(Context.BACKUP_SERVICE));
11123            bm.agentConnected(agentPackageName, agent);
11124        } catch (RemoteException e) {
11125            // can't happen; the backup manager service is local
11126        } catch (Exception e) {
11127            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11128            e.printStackTrace();
11129        } finally {
11130            Binder.restoreCallingIdentity(oldIdent);
11131        }
11132    }
11133
11134    // done with this agent
11135    public void unbindBackupAgent(ApplicationInfo appInfo) {
11136        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11137        if (appInfo == null) {
11138            Slog.w(TAG, "unbind backup agent for null app");
11139            return;
11140        }
11141
11142        synchronized(this) {
11143            if (mBackupAppName == null) {
11144                Slog.w(TAG, "Unbinding backup agent with no active backup");
11145                return;
11146            }
11147
11148            if (!mBackupAppName.equals(appInfo.packageName)) {
11149                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11150                return;
11151            }
11152
11153            ProcessRecord proc = mBackupTarget.app;
11154            mBackupTarget = null;
11155            mBackupAppName = null;
11156
11157            // Not backing this app up any more; reset its OOM adjustment
11158            updateOomAdjLocked(proc);
11159
11160            // If the app crashed during backup, 'thread' will be null here
11161            if (proc.thread != null) {
11162                try {
11163                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11164                            compatibilityInfoForPackageLocked(appInfo));
11165                } catch (Exception e) {
11166                    Slog.e(TAG, "Exception when unbinding backup agent:");
11167                    e.printStackTrace();
11168                }
11169            }
11170        }
11171    }
11172    // =========================================================
11173    // BROADCASTS
11174    // =========================================================
11175
11176    private final List getStickiesLocked(String action, IntentFilter filter,
11177            List cur, int userId) {
11178        final ContentResolver resolver = mContext.getContentResolver();
11179        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11180        if (stickies == null) {
11181            return cur;
11182        }
11183        final ArrayList<Intent> list = stickies.get(action);
11184        if (list == null) {
11185            return cur;
11186        }
11187        int N = list.size();
11188        for (int i=0; i<N; i++) {
11189            Intent intent = list.get(i);
11190            if (filter.match(resolver, intent, true, TAG) >= 0) {
11191                if (cur == null) {
11192                    cur = new ArrayList<Intent>();
11193                }
11194                cur.add(intent);
11195            }
11196        }
11197        return cur;
11198    }
11199
11200    boolean isPendingBroadcastProcessLocked(int pid) {
11201        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11202                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11203    }
11204
11205    void skipPendingBroadcastLocked(int pid) {
11206            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11207            for (BroadcastQueue queue : mBroadcastQueues) {
11208                queue.skipPendingBroadcastLocked(pid);
11209            }
11210    }
11211
11212    // The app just attached; send any pending broadcasts that it should receive
11213    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11214        boolean didSomething = false;
11215        for (BroadcastQueue queue : mBroadcastQueues) {
11216            didSomething |= queue.sendPendingBroadcastsLocked(app);
11217        }
11218        return didSomething;
11219    }
11220
11221    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11222            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11223        enforceNotIsolatedCaller("registerReceiver");
11224        int callingUid;
11225        int callingPid;
11226        synchronized(this) {
11227            ProcessRecord callerApp = null;
11228            if (caller != null) {
11229                callerApp = getRecordForAppLocked(caller);
11230                if (callerApp == null) {
11231                    throw new SecurityException(
11232                            "Unable to find app for caller " + caller
11233                            + " (pid=" + Binder.getCallingPid()
11234                            + ") when registering receiver " + receiver);
11235                }
11236                if (callerApp.info.uid != Process.SYSTEM_UID &&
11237                        !callerApp.pkgList.contains(callerPackage)) {
11238                    throw new SecurityException("Given caller package " + callerPackage
11239                            + " is not running in process " + callerApp);
11240                }
11241                callingUid = callerApp.info.uid;
11242                callingPid = callerApp.pid;
11243            } else {
11244                callerPackage = null;
11245                callingUid = Binder.getCallingUid();
11246                callingPid = Binder.getCallingPid();
11247            }
11248
11249            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11250                    true, true, "registerReceiver", callerPackage);
11251
11252            List allSticky = null;
11253
11254            // Look for any matching sticky broadcasts...
11255            Iterator actions = filter.actionsIterator();
11256            if (actions != null) {
11257                while (actions.hasNext()) {
11258                    String action = (String)actions.next();
11259                    allSticky = getStickiesLocked(action, filter, allSticky,
11260                            UserHandle.USER_ALL);
11261                    allSticky = getStickiesLocked(action, filter, allSticky,
11262                            UserHandle.getUserId(callingUid));
11263                }
11264            } else {
11265                allSticky = getStickiesLocked(null, filter, allSticky,
11266                        UserHandle.USER_ALL);
11267                allSticky = getStickiesLocked(null, filter, allSticky,
11268                        UserHandle.getUserId(callingUid));
11269            }
11270
11271            // The first sticky in the list is returned directly back to
11272            // the client.
11273            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11274
11275            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11276                    + ": " + sticky);
11277
11278            if (receiver == null) {
11279                return sticky;
11280            }
11281
11282            ReceiverList rl
11283                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11284            if (rl == null) {
11285                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11286                        userId, receiver);
11287                if (rl.app != null) {
11288                    rl.app.receivers.add(rl);
11289                } else {
11290                    try {
11291                        receiver.asBinder().linkToDeath(rl, 0);
11292                    } catch (RemoteException e) {
11293                        return sticky;
11294                    }
11295                    rl.linkedToDeath = true;
11296                }
11297                mRegisteredReceivers.put(receiver.asBinder(), rl);
11298            } else if (rl.uid != callingUid) {
11299                throw new IllegalArgumentException(
11300                        "Receiver requested to register for uid " + callingUid
11301                        + " was previously registered for uid " + rl.uid);
11302            } else if (rl.pid != callingPid) {
11303                throw new IllegalArgumentException(
11304                        "Receiver requested to register for pid " + callingPid
11305                        + " was previously registered for pid " + rl.pid);
11306            } else if (rl.userId != userId) {
11307                throw new IllegalArgumentException(
11308                        "Receiver requested to register for user " + userId
11309                        + " was previously registered for user " + rl.userId);
11310            }
11311            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11312                    permission, callingUid, userId);
11313            rl.add(bf);
11314            if (!bf.debugCheck()) {
11315                Slog.w(TAG, "==> For Dynamic broadast");
11316            }
11317            mReceiverResolver.addFilter(bf);
11318
11319            // Enqueue broadcasts for all existing stickies that match
11320            // this filter.
11321            if (allSticky != null) {
11322                ArrayList receivers = new ArrayList();
11323                receivers.add(bf);
11324
11325                int N = allSticky.size();
11326                for (int i=0; i<N; i++) {
11327                    Intent intent = (Intent)allSticky.get(i);
11328                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11329                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11330                            null, -1, -1, null, receivers, null, 0, null, null,
11331                            false, true, true, -1);
11332                    queue.enqueueParallelBroadcastLocked(r);
11333                    queue.scheduleBroadcastsLocked();
11334                }
11335            }
11336
11337            return sticky;
11338        }
11339    }
11340
11341    public void unregisterReceiver(IIntentReceiver receiver) {
11342        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11343
11344        final long origId = Binder.clearCallingIdentity();
11345        try {
11346            boolean doTrim = false;
11347
11348            synchronized(this) {
11349                ReceiverList rl
11350                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11351                if (rl != null) {
11352                    if (rl.curBroadcast != null) {
11353                        BroadcastRecord r = rl.curBroadcast;
11354                        final boolean doNext = finishReceiverLocked(
11355                                receiver.asBinder(), r.resultCode, r.resultData,
11356                                r.resultExtras, r.resultAbort, true);
11357                        if (doNext) {
11358                            doTrim = true;
11359                            r.queue.processNextBroadcast(false);
11360                        }
11361                    }
11362
11363                    if (rl.app != null) {
11364                        rl.app.receivers.remove(rl);
11365                    }
11366                    removeReceiverLocked(rl);
11367                    if (rl.linkedToDeath) {
11368                        rl.linkedToDeath = false;
11369                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11370                    }
11371                }
11372            }
11373
11374            // If we actually concluded any broadcasts, we might now be able
11375            // to trim the recipients' apps from our working set
11376            if (doTrim) {
11377                trimApplications();
11378                return;
11379            }
11380
11381        } finally {
11382            Binder.restoreCallingIdentity(origId);
11383        }
11384    }
11385
11386    void removeReceiverLocked(ReceiverList rl) {
11387        mRegisteredReceivers.remove(rl.receiver.asBinder());
11388        int N = rl.size();
11389        for (int i=0; i<N; i++) {
11390            mReceiverResolver.removeFilter(rl.get(i));
11391        }
11392    }
11393
11394    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11395        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11396            ProcessRecord r = mLruProcesses.get(i);
11397            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11398                try {
11399                    r.thread.dispatchPackageBroadcast(cmd, packages);
11400                } catch (RemoteException ex) {
11401                }
11402            }
11403        }
11404    }
11405
11406    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11407            int[] users) {
11408        List<ResolveInfo> receivers = null;
11409        try {
11410            HashSet<ComponentName> singleUserReceivers = null;
11411            boolean scannedFirstReceivers = false;
11412            for (int user : users) {
11413                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11414                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11415                if (user != 0 && newReceivers != null) {
11416                    // If this is not the primary user, we need to check for
11417                    // any receivers that should be filtered out.
11418                    for (int i=0; i<newReceivers.size(); i++) {
11419                        ResolveInfo ri = newReceivers.get(i);
11420                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11421                            newReceivers.remove(i);
11422                            i--;
11423                        }
11424                    }
11425                }
11426                if (newReceivers != null && newReceivers.size() == 0) {
11427                    newReceivers = null;
11428                }
11429                if (receivers == null) {
11430                    receivers = newReceivers;
11431                } else if (newReceivers != null) {
11432                    // We need to concatenate the additional receivers
11433                    // found with what we have do far.  This would be easy,
11434                    // but we also need to de-dup any receivers that are
11435                    // singleUser.
11436                    if (!scannedFirstReceivers) {
11437                        // Collect any single user receivers we had already retrieved.
11438                        scannedFirstReceivers = true;
11439                        for (int i=0; i<receivers.size(); i++) {
11440                            ResolveInfo ri = receivers.get(i);
11441                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11442                                ComponentName cn = new ComponentName(
11443                                        ri.activityInfo.packageName, ri.activityInfo.name);
11444                                if (singleUserReceivers == null) {
11445                                    singleUserReceivers = new HashSet<ComponentName>();
11446                                }
11447                                singleUserReceivers.add(cn);
11448                            }
11449                        }
11450                    }
11451                    // Add the new results to the existing results, tracking
11452                    // and de-dupping single user receivers.
11453                    for (int i=0; i<newReceivers.size(); i++) {
11454                        ResolveInfo ri = newReceivers.get(i);
11455                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11456                            ComponentName cn = new ComponentName(
11457                                    ri.activityInfo.packageName, ri.activityInfo.name);
11458                            if (singleUserReceivers == null) {
11459                                singleUserReceivers = new HashSet<ComponentName>();
11460                            }
11461                            if (!singleUserReceivers.contains(cn)) {
11462                                singleUserReceivers.add(cn);
11463                                receivers.add(ri);
11464                            }
11465                        } else {
11466                            receivers.add(ri);
11467                        }
11468                    }
11469                }
11470            }
11471        } catch (RemoteException ex) {
11472            // pm is in same process, this will never happen.
11473        }
11474        return receivers;
11475    }
11476
11477    private final int broadcastIntentLocked(ProcessRecord callerApp,
11478            String callerPackage, Intent intent, String resolvedType,
11479            IIntentReceiver resultTo, int resultCode, String resultData,
11480            Bundle map, String requiredPermission,
11481            boolean ordered, boolean sticky, int callingPid, int callingUid,
11482            int userId) {
11483        intent = new Intent(intent);
11484
11485        // By default broadcasts do not go to stopped apps.
11486        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11487
11488        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11489            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11490            + " ordered=" + ordered + " userid=" + userId);
11491        if ((resultTo != null) && !ordered) {
11492            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11493        }
11494
11495        userId = handleIncomingUser(callingPid, callingUid, userId,
11496                true, false, "broadcast", callerPackage);
11497
11498        // Make sure that the user who is receiving this broadcast is started.
11499        // If not, we will just skip it.
11500        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11501            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11502                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11503                Slog.w(TAG, "Skipping broadcast of " + intent
11504                        + ": user " + userId + " is stopped");
11505                return ActivityManager.BROADCAST_SUCCESS;
11506            }
11507        }
11508
11509        /*
11510         * Prevent non-system code (defined here to be non-persistent
11511         * processes) from sending protected broadcasts.
11512         */
11513        int callingAppId = UserHandle.getAppId(callingUid);
11514        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11515            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11516            callingUid == 0) {
11517            // Always okay.
11518        } else if (callerApp == null || !callerApp.persistent) {
11519            try {
11520                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11521                        intent.getAction())) {
11522                    String msg = "Permission Denial: not allowed to send broadcast "
11523                            + intent.getAction() + " from pid="
11524                            + callingPid + ", uid=" + callingUid;
11525                    Slog.w(TAG, msg);
11526                    throw new SecurityException(msg);
11527                }
11528            } catch (RemoteException e) {
11529                Slog.w(TAG, "Remote exception", e);
11530                return ActivityManager.BROADCAST_SUCCESS;
11531            }
11532        }
11533
11534        // Handle special intents: if this broadcast is from the package
11535        // manager about a package being removed, we need to remove all of
11536        // its activities from the history stack.
11537        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11538                intent.getAction());
11539        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11540                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11541                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11542                || uidRemoved) {
11543            if (checkComponentPermission(
11544                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11545                    callingPid, callingUid, -1, true)
11546                    == PackageManager.PERMISSION_GRANTED) {
11547                if (uidRemoved) {
11548                    final Bundle intentExtras = intent.getExtras();
11549                    final int uid = intentExtras != null
11550                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11551                    if (uid >= 0) {
11552                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11553                        synchronized (bs) {
11554                            bs.removeUidStatsLocked(uid);
11555                        }
11556                    }
11557                } else {
11558                    // If resources are unavailable just force stop all
11559                    // those packages and flush the attribute cache as well.
11560                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11561                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11562                        if (list != null && (list.length > 0)) {
11563                            for (String pkg : list) {
11564                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11565                            }
11566                            sendPackageBroadcastLocked(
11567                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11568                        }
11569                    } else {
11570                        Uri data = intent.getData();
11571                        String ssp;
11572                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11573                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11574                                forceStopPackageLocked(ssp,
11575                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11576                                        false, userId);
11577                            }
11578                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11579                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11580                                        new String[] {ssp}, userId);
11581                            }
11582                        }
11583                    }
11584                }
11585            } else {
11586                String msg = "Permission Denial: " + intent.getAction()
11587                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11588                        + ", uid=" + callingUid + ")"
11589                        + " requires "
11590                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11591                Slog.w(TAG, msg);
11592                throw new SecurityException(msg);
11593            }
11594
11595        // Special case for adding a package: by default turn on compatibility
11596        // mode.
11597        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11598            Uri data = intent.getData();
11599            String ssp;
11600            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11601                mCompatModePackages.handlePackageAddedLocked(ssp,
11602                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11603            }
11604        }
11605
11606        /*
11607         * If this is the time zone changed action, queue up a message that will reset the timezone
11608         * of all currently running processes. This message will get queued up before the broadcast
11609         * happens.
11610         */
11611        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11612            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11613        }
11614
11615        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11616            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11617        }
11618
11619        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11620            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11621            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11622        }
11623
11624        // Add to the sticky list if requested.
11625        if (sticky) {
11626            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11627                    callingPid, callingUid)
11628                    != PackageManager.PERMISSION_GRANTED) {
11629                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11630                        + callingPid + ", uid=" + callingUid
11631                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11632                Slog.w(TAG, msg);
11633                throw new SecurityException(msg);
11634            }
11635            if (requiredPermission != null) {
11636                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11637                        + " and enforce permission " + requiredPermission);
11638                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11639            }
11640            if (intent.getComponent() != null) {
11641                throw new SecurityException(
11642                        "Sticky broadcasts can't target a specific component");
11643            }
11644            // We use userId directly here, since the "all" target is maintained
11645            // as a separate set of sticky broadcasts.
11646            if (userId != UserHandle.USER_ALL) {
11647                // But first, if this is not a broadcast to all users, then
11648                // make sure it doesn't conflict with an existing broadcast to
11649                // all users.
11650                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11651                        UserHandle.USER_ALL);
11652                if (stickies != null) {
11653                    ArrayList<Intent> list = stickies.get(intent.getAction());
11654                    if (list != null) {
11655                        int N = list.size();
11656                        int i;
11657                        for (i=0; i<N; i++) {
11658                            if (intent.filterEquals(list.get(i))) {
11659                                throw new IllegalArgumentException(
11660                                        "Sticky broadcast " + intent + " for user "
11661                                        + userId + " conflicts with existing global broadcast");
11662                            }
11663                        }
11664                    }
11665                }
11666            }
11667            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11668            if (stickies == null) {
11669                stickies = new HashMap<String, ArrayList<Intent>>();
11670                mStickyBroadcasts.put(userId, stickies);
11671            }
11672            ArrayList<Intent> list = stickies.get(intent.getAction());
11673            if (list == null) {
11674                list = new ArrayList<Intent>();
11675                stickies.put(intent.getAction(), list);
11676            }
11677            int N = list.size();
11678            int i;
11679            for (i=0; i<N; i++) {
11680                if (intent.filterEquals(list.get(i))) {
11681                    // This sticky already exists, replace it.
11682                    list.set(i, new Intent(intent));
11683                    break;
11684                }
11685            }
11686            if (i >= N) {
11687                list.add(new Intent(intent));
11688            }
11689        }
11690
11691        int[] users;
11692        if (userId == UserHandle.USER_ALL) {
11693            // Caller wants broadcast to go to all started users.
11694            users = mStartedUserArray;
11695        } else {
11696            // Caller wants broadcast to go to one specific user.
11697            users = mCurrentUserArray;
11698        }
11699
11700        // Figure out who all will receive this broadcast.
11701        List receivers = null;
11702        List<BroadcastFilter> registeredReceivers = null;
11703        // Need to resolve the intent to interested receivers...
11704        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11705                 == 0) {
11706            receivers = collectReceiverComponents(intent, resolvedType, users);
11707        }
11708        if (intent.getComponent() == null) {
11709            registeredReceivers = mReceiverResolver.queryIntent(intent,
11710                    resolvedType, false, userId);
11711        }
11712
11713        final boolean replacePending =
11714                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11715
11716        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11717                + " replacePending=" + replacePending);
11718
11719        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11720        if (!ordered && NR > 0) {
11721            // If we are not serializing this broadcast, then send the
11722            // registered receivers separately so they don't wait for the
11723            // components to be launched.
11724            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11725            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11726                    callerPackage, callingPid, callingUid, requiredPermission,
11727                    registeredReceivers, resultTo, resultCode, resultData, map,
11728                    ordered, sticky, false, userId);
11729            if (DEBUG_BROADCAST) Slog.v(
11730                    TAG, "Enqueueing parallel broadcast " + r);
11731            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11732            if (!replaced) {
11733                queue.enqueueParallelBroadcastLocked(r);
11734                queue.scheduleBroadcastsLocked();
11735            }
11736            registeredReceivers = null;
11737            NR = 0;
11738        }
11739
11740        // Merge into one list.
11741        int ir = 0;
11742        if (receivers != null) {
11743            // A special case for PACKAGE_ADDED: do not allow the package
11744            // being added to see this broadcast.  This prevents them from
11745            // using this as a back door to get run as soon as they are
11746            // installed.  Maybe in the future we want to have a special install
11747            // broadcast or such for apps, but we'd like to deliberately make
11748            // this decision.
11749            String skipPackages[] = null;
11750            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11751                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11752                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11753                Uri data = intent.getData();
11754                if (data != null) {
11755                    String pkgName = data.getSchemeSpecificPart();
11756                    if (pkgName != null) {
11757                        skipPackages = new String[] { pkgName };
11758                    }
11759                }
11760            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11761                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11762            }
11763            if (skipPackages != null && (skipPackages.length > 0)) {
11764                for (String skipPackage : skipPackages) {
11765                    if (skipPackage != null) {
11766                        int NT = receivers.size();
11767                        for (int it=0; it<NT; it++) {
11768                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11769                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11770                                receivers.remove(it);
11771                                it--;
11772                                NT--;
11773                            }
11774                        }
11775                    }
11776                }
11777            }
11778
11779            int NT = receivers != null ? receivers.size() : 0;
11780            int it = 0;
11781            ResolveInfo curt = null;
11782            BroadcastFilter curr = null;
11783            while (it < NT && ir < NR) {
11784                if (curt == null) {
11785                    curt = (ResolveInfo)receivers.get(it);
11786                }
11787                if (curr == null) {
11788                    curr = registeredReceivers.get(ir);
11789                }
11790                if (curr.getPriority() >= curt.priority) {
11791                    // Insert this broadcast record into the final list.
11792                    receivers.add(it, curr);
11793                    ir++;
11794                    curr = null;
11795                    it++;
11796                    NT++;
11797                } else {
11798                    // Skip to the next ResolveInfo in the final list.
11799                    it++;
11800                    curt = null;
11801                }
11802            }
11803        }
11804        while (ir < NR) {
11805            if (receivers == null) {
11806                receivers = new ArrayList();
11807            }
11808            receivers.add(registeredReceivers.get(ir));
11809            ir++;
11810        }
11811
11812        if ((receivers != null && receivers.size() > 0)
11813                || resultTo != null) {
11814            BroadcastQueue queue = broadcastQueueForIntent(intent);
11815            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11816                    callerPackage, callingPid, callingUid, requiredPermission,
11817                    receivers, resultTo, resultCode, resultData, map, ordered,
11818                    sticky, false, userId);
11819            if (DEBUG_BROADCAST) Slog.v(
11820                    TAG, "Enqueueing ordered broadcast " + r
11821                    + ": prev had " + queue.mOrderedBroadcasts.size());
11822            if (DEBUG_BROADCAST) {
11823                int seq = r.intent.getIntExtra("seq", -1);
11824                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11825            }
11826            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11827            if (!replaced) {
11828                queue.enqueueOrderedBroadcastLocked(r);
11829                queue.scheduleBroadcastsLocked();
11830            }
11831        }
11832
11833        return ActivityManager.BROADCAST_SUCCESS;
11834    }
11835
11836    final Intent verifyBroadcastLocked(Intent intent) {
11837        // Refuse possible leaked file descriptors
11838        if (intent != null && intent.hasFileDescriptors() == true) {
11839            throw new IllegalArgumentException("File descriptors passed in Intent");
11840        }
11841
11842        int flags = intent.getFlags();
11843
11844        if (!mProcessesReady) {
11845            // if the caller really truly claims to know what they're doing, go
11846            // ahead and allow the broadcast without launching any receivers
11847            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11848                intent = new Intent(intent);
11849                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11850            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11851                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11852                        + " before boot completion");
11853                throw new IllegalStateException("Cannot broadcast before boot completed");
11854            }
11855        }
11856
11857        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11858            throw new IllegalArgumentException(
11859                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11860        }
11861
11862        return intent;
11863    }
11864
11865    public final int broadcastIntent(IApplicationThread caller,
11866            Intent intent, String resolvedType, IIntentReceiver resultTo,
11867            int resultCode, String resultData, Bundle map,
11868            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11869        enforceNotIsolatedCaller("broadcastIntent");
11870        synchronized(this) {
11871            intent = verifyBroadcastLocked(intent);
11872
11873            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11874            final int callingPid = Binder.getCallingPid();
11875            final int callingUid = Binder.getCallingUid();
11876            final long origId = Binder.clearCallingIdentity();
11877            int res = broadcastIntentLocked(callerApp,
11878                    callerApp != null ? callerApp.info.packageName : null,
11879                    intent, resolvedType, resultTo,
11880                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11881                    callingPid, callingUid, userId);
11882            Binder.restoreCallingIdentity(origId);
11883            return res;
11884        }
11885    }
11886
11887    int broadcastIntentInPackage(String packageName, int uid,
11888            Intent intent, String resolvedType, IIntentReceiver resultTo,
11889            int resultCode, String resultData, Bundle map,
11890            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11891        synchronized(this) {
11892            intent = verifyBroadcastLocked(intent);
11893
11894            final long origId = Binder.clearCallingIdentity();
11895            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11896                    resultTo, resultCode, resultData, map, requiredPermission,
11897                    serialized, sticky, -1, uid, userId);
11898            Binder.restoreCallingIdentity(origId);
11899            return res;
11900        }
11901    }
11902
11903    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11904        // Refuse possible leaked file descriptors
11905        if (intent != null && intent.hasFileDescriptors() == true) {
11906            throw new IllegalArgumentException("File descriptors passed in Intent");
11907        }
11908
11909        userId = handleIncomingUser(Binder.getCallingPid(),
11910                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11911
11912        synchronized(this) {
11913            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11914                    != PackageManager.PERMISSION_GRANTED) {
11915                String msg = "Permission Denial: unbroadcastIntent() from pid="
11916                        + Binder.getCallingPid()
11917                        + ", uid=" + Binder.getCallingUid()
11918                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11919                Slog.w(TAG, msg);
11920                throw new SecurityException(msg);
11921            }
11922            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11923            if (stickies != null) {
11924                ArrayList<Intent> list = stickies.get(intent.getAction());
11925                if (list != null) {
11926                    int N = list.size();
11927                    int i;
11928                    for (i=0; i<N; i++) {
11929                        if (intent.filterEquals(list.get(i))) {
11930                            list.remove(i);
11931                            break;
11932                        }
11933                    }
11934                    if (list.size() <= 0) {
11935                        stickies.remove(intent.getAction());
11936                    }
11937                }
11938                if (stickies.size() <= 0) {
11939                    mStickyBroadcasts.remove(userId);
11940                }
11941            }
11942        }
11943    }
11944
11945    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11946            String resultData, Bundle resultExtras, boolean resultAbort,
11947            boolean explicit) {
11948        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11949        if (r == null) {
11950            Slog.w(TAG, "finishReceiver called but not found on queue");
11951            return false;
11952        }
11953
11954        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11955                explicit);
11956    }
11957
11958    public void finishReceiver(IBinder who, int resultCode, String resultData,
11959            Bundle resultExtras, boolean resultAbort) {
11960        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11961
11962        // Refuse possible leaked file descriptors
11963        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11964            throw new IllegalArgumentException("File descriptors passed in Bundle");
11965        }
11966
11967        final long origId = Binder.clearCallingIdentity();
11968        try {
11969            boolean doNext = false;
11970            BroadcastRecord r = null;
11971
11972            synchronized(this) {
11973                r = broadcastRecordForReceiverLocked(who);
11974                if (r != null) {
11975                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11976                        resultData, resultExtras, resultAbort, true);
11977                }
11978            }
11979
11980            if (doNext) {
11981                r.queue.processNextBroadcast(false);
11982            }
11983            trimApplications();
11984        } finally {
11985            Binder.restoreCallingIdentity(origId);
11986        }
11987    }
11988
11989    // =========================================================
11990    // INSTRUMENTATION
11991    // =========================================================
11992
11993    public boolean startInstrumentation(ComponentName className,
11994            String profileFile, int flags, Bundle arguments,
11995            IInstrumentationWatcher watcher, int userId) {
11996        enforceNotIsolatedCaller("startInstrumentation");
11997        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11998                userId, false, true, "startInstrumentation", null);
11999        // Refuse possible leaked file descriptors
12000        if (arguments != null && arguments.hasFileDescriptors()) {
12001            throw new IllegalArgumentException("File descriptors passed in Bundle");
12002        }
12003
12004        synchronized(this) {
12005            InstrumentationInfo ii = null;
12006            ApplicationInfo ai = null;
12007            try {
12008                ii = mContext.getPackageManager().getInstrumentationInfo(
12009                    className, STOCK_PM_FLAGS);
12010                ai = AppGlobals.getPackageManager().getApplicationInfo(
12011                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12012            } catch (PackageManager.NameNotFoundException e) {
12013            } catch (RemoteException e) {
12014            }
12015            if (ii == null) {
12016                reportStartInstrumentationFailure(watcher, className,
12017                        "Unable to find instrumentation info for: " + className);
12018                return false;
12019            }
12020            if (ai == null) {
12021                reportStartInstrumentationFailure(watcher, className,
12022                        "Unable to find instrumentation target package: " + ii.targetPackage);
12023                return false;
12024            }
12025
12026            int match = mContext.getPackageManager().checkSignatures(
12027                    ii.targetPackage, ii.packageName);
12028            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12029                String msg = "Permission Denial: starting instrumentation "
12030                        + className + " from pid="
12031                        + Binder.getCallingPid()
12032                        + ", uid=" + Binder.getCallingPid()
12033                        + " not allowed because package " + ii.packageName
12034                        + " does not have a signature matching the target "
12035                        + ii.targetPackage;
12036                reportStartInstrumentationFailure(watcher, className, msg);
12037                throw new SecurityException(msg);
12038            }
12039
12040            final long origId = Binder.clearCallingIdentity();
12041            // Instrumentation can kill and relaunch even persistent processes
12042            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12043            ProcessRecord app = addAppLocked(ai, false);
12044            app.instrumentationClass = className;
12045            app.instrumentationInfo = ai;
12046            app.instrumentationProfileFile = profileFile;
12047            app.instrumentationArguments = arguments;
12048            app.instrumentationWatcher = watcher;
12049            app.instrumentationResultClass = className;
12050            Binder.restoreCallingIdentity(origId);
12051        }
12052
12053        return true;
12054    }
12055
12056    /**
12057     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12058     * error to the logs, but if somebody is watching, send the report there too.  This enables
12059     * the "am" command to report errors with more information.
12060     *
12061     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12062     * @param cn The component name of the instrumentation.
12063     * @param report The error report.
12064     */
12065    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12066            ComponentName cn, String report) {
12067        Slog.w(TAG, report);
12068        try {
12069            if (watcher != null) {
12070                Bundle results = new Bundle();
12071                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12072                results.putString("Error", report);
12073                watcher.instrumentationStatus(cn, -1, results);
12074            }
12075        } catch (RemoteException e) {
12076            Slog.w(TAG, e);
12077        }
12078    }
12079
12080    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12081        if (app.instrumentationWatcher != null) {
12082            try {
12083                // NOTE:  IInstrumentationWatcher *must* be oneway here
12084                app.instrumentationWatcher.instrumentationFinished(
12085                    app.instrumentationClass,
12086                    resultCode,
12087                    results);
12088            } catch (RemoteException e) {
12089            }
12090        }
12091        app.instrumentationWatcher = null;
12092        app.instrumentationClass = null;
12093        app.instrumentationInfo = null;
12094        app.instrumentationProfileFile = null;
12095        app.instrumentationArguments = null;
12096
12097        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12098    }
12099
12100    public void finishInstrumentation(IApplicationThread target,
12101            int resultCode, Bundle results) {
12102        int userId = UserHandle.getCallingUserId();
12103        // Refuse possible leaked file descriptors
12104        if (results != null && results.hasFileDescriptors()) {
12105            throw new IllegalArgumentException("File descriptors passed in Intent");
12106        }
12107
12108        synchronized(this) {
12109            ProcessRecord app = getRecordForAppLocked(target);
12110            if (app == null) {
12111                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12112                return;
12113            }
12114            final long origId = Binder.clearCallingIdentity();
12115            finishInstrumentationLocked(app, resultCode, results);
12116            Binder.restoreCallingIdentity(origId);
12117        }
12118    }
12119
12120    // =========================================================
12121    // CONFIGURATION
12122    // =========================================================
12123
12124    public ConfigurationInfo getDeviceConfigurationInfo() {
12125        ConfigurationInfo config = new ConfigurationInfo();
12126        synchronized (this) {
12127            config.reqTouchScreen = mConfiguration.touchscreen;
12128            config.reqKeyboardType = mConfiguration.keyboard;
12129            config.reqNavigation = mConfiguration.navigation;
12130            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12131                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12132                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12133            }
12134            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12135                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12136                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12137            }
12138            config.reqGlEsVersion = GL_ES_VERSION;
12139        }
12140        return config;
12141    }
12142
12143    public Configuration getConfiguration() {
12144        Configuration ci;
12145        synchronized(this) {
12146            ci = new Configuration(mConfiguration);
12147        }
12148        return ci;
12149    }
12150
12151    public void updatePersistentConfiguration(Configuration values) {
12152        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12153                "updateConfiguration()");
12154        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12155                "updateConfiguration()");
12156        if (values == null) {
12157            throw new NullPointerException("Configuration must not be null");
12158        }
12159
12160        synchronized(this) {
12161            final long origId = Binder.clearCallingIdentity();
12162            updateConfigurationLocked(values, null, true, false);
12163            Binder.restoreCallingIdentity(origId);
12164        }
12165    }
12166
12167    public void updateConfiguration(Configuration values) {
12168        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12169                "updateConfiguration()");
12170
12171        synchronized(this) {
12172            if (values == null && mWindowManager != null) {
12173                // sentinel: fetch the current configuration from the window manager
12174                values = mWindowManager.computeNewConfiguration();
12175            }
12176
12177            if (mWindowManager != null) {
12178                mProcessList.applyDisplaySize(mWindowManager);
12179            }
12180
12181            final long origId = Binder.clearCallingIdentity();
12182            if (values != null) {
12183                Settings.System.clearConfiguration(values);
12184            }
12185            updateConfigurationLocked(values, null, false, false);
12186            Binder.restoreCallingIdentity(origId);
12187        }
12188    }
12189
12190    /**
12191     * Do either or both things: (1) change the current configuration, and (2)
12192     * make sure the given activity is running with the (now) current
12193     * configuration.  Returns true if the activity has been left running, or
12194     * false if <var>starting</var> is being destroyed to match the new
12195     * configuration.
12196     * @param persistent TODO
12197     */
12198    boolean updateConfigurationLocked(Configuration values,
12199            ActivityRecord starting, boolean persistent, boolean initLocale) {
12200        // do nothing if we are headless
12201        if (mHeadless) return true;
12202
12203        int changes = 0;
12204
12205        boolean kept = true;
12206
12207        if (values != null) {
12208            Configuration newConfig = new Configuration(mConfiguration);
12209            changes = newConfig.updateFrom(values);
12210            if (changes != 0) {
12211                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12212                    Slog.i(TAG, "Updating configuration to: " + values);
12213                }
12214
12215                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12216
12217                if (values.locale != null && !initLocale) {
12218                    saveLocaleLocked(values.locale,
12219                                     !values.locale.equals(mConfiguration.locale),
12220                                     values.userSetLocale);
12221                }
12222
12223                mConfigurationSeq++;
12224                if (mConfigurationSeq <= 0) {
12225                    mConfigurationSeq = 1;
12226                }
12227                newConfig.seq = mConfigurationSeq;
12228                mConfiguration = newConfig;
12229                Slog.i(TAG, "Config changed: " + newConfig);
12230
12231                final Configuration configCopy = new Configuration(mConfiguration);
12232
12233                // TODO: If our config changes, should we auto dismiss any currently
12234                // showing dialogs?
12235                mShowDialogs = shouldShowDialogs(newConfig);
12236
12237                AttributeCache ac = AttributeCache.instance();
12238                if (ac != null) {
12239                    ac.updateConfiguration(configCopy);
12240                }
12241
12242                // Make sure all resources in our process are updated
12243                // right now, so that anyone who is going to retrieve
12244                // resource values after we return will be sure to get
12245                // the new ones.  This is especially important during
12246                // boot, where the first config change needs to guarantee
12247                // all resources have that config before following boot
12248                // code is executed.
12249                mSystemThread.applyConfigurationToResources(configCopy);
12250
12251                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12252                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12253                    msg.obj = new Configuration(configCopy);
12254                    mHandler.sendMessage(msg);
12255                }
12256
12257                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12258                    ProcessRecord app = mLruProcesses.get(i);
12259                    try {
12260                        if (app.thread != null) {
12261                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12262                                    + app.processName + " new config " + mConfiguration);
12263                            app.thread.scheduleConfigurationChanged(configCopy);
12264                        }
12265                    } catch (Exception e) {
12266                    }
12267                }
12268                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12269                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12270                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
12271                        | Intent.FLAG_RECEIVER_FOREGROUND);
12272                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12273                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12274                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12275                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12276                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12277                    broadcastIntentLocked(null, null, intent,
12278                            null, null, 0, null, null,
12279                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12280                }
12281            }
12282        }
12283
12284        if (changes != 0 && starting == null) {
12285            // If the configuration changed, and the caller is not already
12286            // in the process of starting an activity, then find the top
12287            // activity to check if its configuration needs to change.
12288            starting = mMainStack.topRunningActivityLocked(null);
12289        }
12290
12291        if (starting != null) {
12292            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12293            // And we need to make sure at this point that all other activities
12294            // are made visible with the correct configuration.
12295            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12296        }
12297
12298        if (values != null && mWindowManager != null) {
12299            mWindowManager.setNewConfiguration(mConfiguration);
12300        }
12301
12302        return kept;
12303    }
12304
12305    /**
12306     * Decide based on the configuration whether we should shouw the ANR,
12307     * crash, etc dialogs.  The idea is that if there is no affordnace to
12308     * press the on-screen buttons, we shouldn't show the dialog.
12309     *
12310     * A thought: SystemUI might also want to get told about this, the Power
12311     * dialog / global actions also might want different behaviors.
12312     */
12313    private static final boolean shouldShowDialogs(Configuration config) {
12314        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12315                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12316    }
12317
12318    /**
12319     * Save the locale.  You must be inside a synchronized (this) block.
12320     */
12321    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12322        if(isDiff) {
12323            SystemProperties.set("user.language", l.getLanguage());
12324            SystemProperties.set("user.region", l.getCountry());
12325        }
12326
12327        if(isPersist) {
12328            SystemProperties.set("persist.sys.language", l.getLanguage());
12329            SystemProperties.set("persist.sys.country", l.getCountry());
12330            SystemProperties.set("persist.sys.localevar", l.getVariant());
12331        }
12332    }
12333
12334    @Override
12335    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12336        ActivityRecord srec = ActivityRecord.forToken(token);
12337        return srec != null && srec.task.affinity != null &&
12338                srec.task.affinity.equals(destAffinity);
12339    }
12340
12341    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12342            Intent resultData) {
12343        ComponentName dest = destIntent.getComponent();
12344
12345        synchronized (this) {
12346            ActivityRecord srec = ActivityRecord.forToken(token);
12347            if (srec == null) {
12348                return false;
12349            }
12350            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12351            final int start = history.indexOf(srec);
12352            if (start < 0) {
12353                // Current activity is not in history stack; do nothing.
12354                return false;
12355            }
12356            int finishTo = start - 1;
12357            ActivityRecord parent = null;
12358            boolean foundParentInTask = false;
12359            if (dest != null) {
12360                TaskRecord tr = srec.task;
12361                for (int i = start - 1; i >= 0; i--) {
12362                    ActivityRecord r = history.get(i);
12363                    if (tr != r.task) {
12364                        // Couldn't find parent in the same task; stop at the one above this.
12365                        // (Root of current task; in-app "home" behavior)
12366                        // Always at least finish the current activity.
12367                        finishTo = Math.min(start - 1, i + 1);
12368                        parent = history.get(finishTo);
12369                        break;
12370                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12371                            r.info.name.equals(dest.getClassName())) {
12372                        finishTo = i;
12373                        parent = r;
12374                        foundParentInTask = true;
12375                        break;
12376                    }
12377                }
12378            }
12379
12380            if (mController != null) {
12381                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12382                if (next != null) {
12383                    // ask watcher if this is allowed
12384                    boolean resumeOK = true;
12385                    try {
12386                        resumeOK = mController.activityResuming(next.packageName);
12387                    } catch (RemoteException e) {
12388                        mController = null;
12389                    }
12390
12391                    if (!resumeOK) {
12392                        return false;
12393                    }
12394                }
12395            }
12396            final long origId = Binder.clearCallingIdentity();
12397            for (int i = start; i > finishTo; i--) {
12398                ActivityRecord r = history.get(i);
12399                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12400                        "navigate-up", true);
12401                // Only return the supplied result for the first activity finished
12402                resultCode = Activity.RESULT_CANCELED;
12403                resultData = null;
12404            }
12405
12406            if (parent != null && foundParentInTask) {
12407                final int parentLaunchMode = parent.info.launchMode;
12408                final int destIntentFlags = destIntent.getFlags();
12409                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12410                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12411                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12412                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12413                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12414                } else {
12415                    try {
12416                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12417                                destIntent.getComponent(), 0, srec.userId);
12418                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12419                                null, aInfo, parent.appToken, null,
12420                                0, -1, parent.launchedFromUid, 0, null, true, null);
12421                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12422                    } catch (RemoteException e) {
12423                        foundParentInTask = false;
12424                    }
12425                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12426                            resultData, "navigate-up", true);
12427                }
12428            }
12429            Binder.restoreCallingIdentity(origId);
12430            return foundParentInTask;
12431        }
12432    }
12433
12434    public int getLaunchedFromUid(IBinder activityToken) {
12435        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12436        if (srec == null) {
12437            return -1;
12438        }
12439        return srec.launchedFromUid;
12440    }
12441
12442    // =========================================================
12443    // LIFETIME MANAGEMENT
12444    // =========================================================
12445
12446    // Returns which broadcast queue the app is the current [or imminent] receiver
12447    // on, or 'null' if the app is not an active broadcast recipient.
12448    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12449        BroadcastRecord r = app.curReceiver;
12450        if (r != null) {
12451            return r.queue;
12452        }
12453
12454        // It's not the current receiver, but it might be starting up to become one
12455        synchronized (this) {
12456            for (BroadcastQueue queue : mBroadcastQueues) {
12457                r = queue.mPendingBroadcast;
12458                if (r != null && r.curApp == app) {
12459                    // found it; report which queue it's in
12460                    return queue;
12461                }
12462            }
12463        }
12464
12465        return null;
12466    }
12467
12468    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12469            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12470        if (mAdjSeq == app.adjSeq) {
12471            // This adjustment has already been computed.  If we are calling
12472            // from the top, we may have already computed our adjustment with
12473            // an earlier hidden adjustment that isn't really for us... if
12474            // so, use the new hidden adjustment.
12475            if (!recursed && app.hidden) {
12476                if (app.hasActivities) {
12477                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12478                } else if (app.hasClientActivities) {
12479                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12480                } else {
12481                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12482                }
12483            }
12484            return app.curRawAdj;
12485        }
12486
12487        if (app.thread == null) {
12488            app.adjSeq = mAdjSeq;
12489            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12490            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12491        }
12492
12493        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12494        app.adjSource = null;
12495        app.adjTarget = null;
12496        app.empty = false;
12497        app.hidden = false;
12498        app.hasClientActivities = false;
12499
12500        final int activitiesSize = app.activities.size();
12501
12502        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12503            // The max adjustment doesn't allow this app to be anything
12504            // below foreground, so it is not worth doing work for it.
12505            app.adjType = "fixed";
12506            app.adjSeq = mAdjSeq;
12507            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12508            app.hasActivities = false;
12509            app.foregroundActivities = false;
12510            app.keeping = true;
12511            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12512            // System process can do UI, and when they do we want to have
12513            // them trim their memory after the user leaves the UI.  To
12514            // facilitate this, here we need to determine whether or not it
12515            // is currently showing UI.
12516            app.systemNoUi = true;
12517            if (app == TOP_APP) {
12518                app.systemNoUi = false;
12519                app.hasActivities = true;
12520            } else if (activitiesSize > 0) {
12521                for (int j = 0; j < activitiesSize; j++) {
12522                    final ActivityRecord r = app.activities.get(j);
12523                    if (r.visible) {
12524                        app.systemNoUi = false;
12525                    }
12526                    if (r.app == app) {
12527                        app.hasActivities = true;
12528                    }
12529                }
12530            }
12531            return (app.curAdj=app.maxAdj);
12532        }
12533
12534        app.keeping = false;
12535        app.systemNoUi = false;
12536        app.hasActivities = false;
12537
12538        // Determine the importance of the process, starting with most
12539        // important to least, and assign an appropriate OOM adjustment.
12540        int adj;
12541        int schedGroup;
12542        boolean foregroundActivities = false;
12543        boolean interesting = false;
12544        BroadcastQueue queue;
12545        if (app == TOP_APP) {
12546            // The last app on the list is the foreground app.
12547            adj = ProcessList.FOREGROUND_APP_ADJ;
12548            schedGroup = Process.THREAD_GROUP_DEFAULT;
12549            app.adjType = "top-activity";
12550            foregroundActivities = true;
12551            interesting = true;
12552            app.hasActivities = true;
12553        } else if (app.instrumentationClass != null) {
12554            // Don't want to kill running instrumentation.
12555            adj = ProcessList.FOREGROUND_APP_ADJ;
12556            schedGroup = Process.THREAD_GROUP_DEFAULT;
12557            app.adjType = "instrumentation";
12558            interesting = true;
12559        } else if ((queue = isReceivingBroadcast(app)) != null) {
12560            // An app that is currently receiving a broadcast also
12561            // counts as being in the foreground for OOM killer purposes.
12562            // It's placed in a sched group based on the nature of the
12563            // broadcast as reflected by which queue it's active in.
12564            adj = ProcessList.FOREGROUND_APP_ADJ;
12565            schedGroup = (queue == mFgBroadcastQueue)
12566                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12567            app.adjType = "broadcast";
12568        } else if (app.executingServices.size() > 0) {
12569            // An app that is currently executing a service callback also
12570            // counts as being in the foreground.
12571            adj = ProcessList.FOREGROUND_APP_ADJ;
12572            schedGroup = Process.THREAD_GROUP_DEFAULT;
12573            app.adjType = "exec-service";
12574        } else {
12575            // Assume process is hidden (has activities); we will correct
12576            // later if this is not the case.
12577            adj = hiddenAdj;
12578            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12579            app.hidden = true;
12580            app.adjType = "bg-act";
12581        }
12582
12583        boolean hasStoppingActivities = false;
12584
12585        // Examine all activities if not already foreground.
12586        if (!foregroundActivities && activitiesSize > 0) {
12587            for (int j = 0; j < activitiesSize; j++) {
12588                final ActivityRecord r = app.activities.get(j);
12589                if (r.visible) {
12590                    // App has a visible activity; only upgrade adjustment.
12591                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12592                        adj = ProcessList.VISIBLE_APP_ADJ;
12593                        app.adjType = "visible";
12594                    }
12595                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12596                    app.hidden = false;
12597                    app.hasActivities = true;
12598                    foregroundActivities = true;
12599                    break;
12600                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12601                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12602                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12603                        app.adjType = "pausing";
12604                    }
12605                    app.hidden = false;
12606                    foregroundActivities = true;
12607                } else if (r.state == ActivityState.STOPPING) {
12608                    // We will apply the actual adjustment later, because
12609                    // we want to allow this process to immediately go through
12610                    // any memory trimming that is in effect.
12611                    app.hidden = false;
12612                    foregroundActivities = true;
12613                    hasStoppingActivities = true;
12614                }
12615                if (r.app == app) {
12616                    app.hasActivities = true;
12617                }
12618            }
12619        }
12620
12621        if (adj == hiddenAdj && !app.hasActivities) {
12622            if (app.hasClientActivities) {
12623                adj = clientHiddenAdj;
12624                app.adjType = "bg-client-act";
12625            } else {
12626                // Whoops, this process is completely empty as far as we know
12627                // at this point.
12628                adj = emptyAdj;
12629                app.empty = true;
12630                app.adjType = "bg-empty";
12631            }
12632        }
12633
12634        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12635            if (app.foregroundServices) {
12636                // The user is aware of this app, so make it visible.
12637                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12638                app.hidden = false;
12639                app.adjType = "fg-service";
12640                schedGroup = Process.THREAD_GROUP_DEFAULT;
12641            } else if (app.forcingToForeground != null) {
12642                // The user is aware of this app, so make it visible.
12643                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12644                app.hidden = false;
12645                app.adjType = "force-fg";
12646                app.adjSource = app.forcingToForeground;
12647                schedGroup = Process.THREAD_GROUP_DEFAULT;
12648            }
12649        }
12650
12651        if (app.foregroundServices) {
12652            interesting = true;
12653        }
12654
12655        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12656            // We don't want to kill the current heavy-weight process.
12657            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12658            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12659            app.hidden = false;
12660            app.adjType = "heavy";
12661        }
12662
12663        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12664            // This process is hosting what we currently consider to be the
12665            // home app, so we don't want to let it go into the background.
12666            adj = ProcessList.HOME_APP_ADJ;
12667            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12668            app.hidden = false;
12669            app.adjType = "home";
12670        }
12671
12672        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12673                && app.activities.size() > 0) {
12674            // This was the previous process that showed UI to the user.
12675            // We want to try to keep it around more aggressively, to give
12676            // a good experience around switching between two apps.
12677            adj = ProcessList.PREVIOUS_APP_ADJ;
12678            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12679            app.hidden = false;
12680            app.adjType = "previous";
12681        }
12682
12683        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12684                + " reason=" + app.adjType);
12685
12686        // By default, we use the computed adjustment.  It may be changed if
12687        // there are applications dependent on our services or providers, but
12688        // this gives us a baseline and makes sure we don't get into an
12689        // infinite recursion.
12690        app.adjSeq = mAdjSeq;
12691        app.curRawAdj = app.nonStoppingAdj = adj;
12692
12693        if (mBackupTarget != null && app == mBackupTarget.app) {
12694            // If possible we want to avoid killing apps while they're being backed up
12695            if (adj > ProcessList.BACKUP_APP_ADJ) {
12696                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12697                adj = ProcessList.BACKUP_APP_ADJ;
12698                app.adjType = "backup";
12699                app.hidden = false;
12700            }
12701        }
12702
12703        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12704                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12705            final long now = SystemClock.uptimeMillis();
12706            // This process is more important if the top activity is
12707            // bound to the service.
12708            Iterator<ServiceRecord> jt = app.services.iterator();
12709            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12710                ServiceRecord s = jt.next();
12711                if (s.startRequested) {
12712                    if (app.hasShownUi && app != mHomeProcess) {
12713                        // If this process has shown some UI, let it immediately
12714                        // go to the LRU list because it may be pretty heavy with
12715                        // UI stuff.  We'll tag it with a label just to help
12716                        // debug and understand what is going on.
12717                        if (adj > ProcessList.SERVICE_ADJ) {
12718                            app.adjType = "started-bg-ui-services";
12719                        }
12720                    } else {
12721                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12722                            // This service has seen some activity within
12723                            // recent memory, so we will keep its process ahead
12724                            // of the background processes.
12725                            if (adj > ProcessList.SERVICE_ADJ) {
12726                                adj = ProcessList.SERVICE_ADJ;
12727                                app.adjType = "started-services";
12728                                app.hidden = false;
12729                            }
12730                        }
12731                        // If we have let the service slide into the background
12732                        // state, still have some text describing what it is doing
12733                        // even though the service no longer has an impact.
12734                        if (adj > ProcessList.SERVICE_ADJ) {
12735                            app.adjType = "started-bg-services";
12736                        }
12737                    }
12738                    // Don't kill this process because it is doing work; it
12739                    // has said it is doing work.
12740                    app.keeping = true;
12741                }
12742                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12743                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12744                    Iterator<ArrayList<ConnectionRecord>> kt
12745                            = s.connections.values().iterator();
12746                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12747                        ArrayList<ConnectionRecord> clist = kt.next();
12748                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12749                            // XXX should compute this based on the max of
12750                            // all connected clients.
12751                            ConnectionRecord cr = clist.get(i);
12752                            if (cr.binding.client == app) {
12753                                // Binding to ourself is not interesting.
12754                                continue;
12755                            }
12756                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12757                                ProcessRecord client = cr.binding.client;
12758                                int clientAdj = adj;
12759                                int myHiddenAdj = hiddenAdj;
12760                                if (myHiddenAdj > client.hiddenAdj) {
12761                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12762                                        myHiddenAdj = client.hiddenAdj;
12763                                    } else {
12764                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12765                                    }
12766                                }
12767                                int myClientHiddenAdj = clientHiddenAdj;
12768                                if (myClientHiddenAdj > client.clientHiddenAdj) {
12769                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12770                                        myClientHiddenAdj = client.clientHiddenAdj;
12771                                    } else {
12772                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12773                                    }
12774                                }
12775                                int myEmptyAdj = emptyAdj;
12776                                if (myEmptyAdj > client.emptyAdj) {
12777                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12778                                        myEmptyAdj = client.emptyAdj;
12779                                    } else {
12780                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12781                                    }
12782                                }
12783                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12784                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12785                                String adjType = null;
12786                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12787                                    // Not doing bind OOM management, so treat
12788                                    // this guy more like a started service.
12789                                    if (app.hasShownUi && app != mHomeProcess) {
12790                                        // If this process has shown some UI, let it immediately
12791                                        // go to the LRU list because it may be pretty heavy with
12792                                        // UI stuff.  We'll tag it with a label just to help
12793                                        // debug and understand what is going on.
12794                                        if (adj > clientAdj) {
12795                                            adjType = "bound-bg-ui-services";
12796                                        }
12797                                        app.hidden = false;
12798                                        clientAdj = adj;
12799                                    } else {
12800                                        if (now >= (s.lastActivity
12801                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12802                                            // This service has not seen activity within
12803                                            // recent memory, so allow it to drop to the
12804                                            // LRU list if there is no other reason to keep
12805                                            // it around.  We'll also tag it with a label just
12806                                            // to help debug and undertand what is going on.
12807                                            if (adj > clientAdj) {
12808                                                adjType = "bound-bg-services";
12809                                            }
12810                                            clientAdj = adj;
12811                                        }
12812                                    }
12813                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12814                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12815                                        // If this connection is keeping the service
12816                                        // created, then we want to try to better follow
12817                                        // its memory management semantics for activities.
12818                                        // That is, if it is sitting in the background
12819                                        // LRU list as a hidden process (with activities),
12820                                        // we don't want the service it is connected to
12821                                        // to go into the empty LRU and quickly get killed,
12822                                        // because I'll we'll do is just end up restarting
12823                                        // the service.
12824                                        app.hasClientActivities |= client.hasActivities;
12825                                    }
12826                                }
12827                                if (adj > clientAdj) {
12828                                    // If this process has recently shown UI, and
12829                                    // the process that is binding to it is less
12830                                    // important than being visible, then we don't
12831                                    // care about the binding as much as we care
12832                                    // about letting this process get into the LRU
12833                                    // list to be killed and restarted if needed for
12834                                    // memory.
12835                                    if (app.hasShownUi && app != mHomeProcess
12836                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12837                                        adjType = "bound-bg-ui-services";
12838                                    } else {
12839                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12840                                                |Context.BIND_IMPORTANT)) != 0) {
12841                                            adj = clientAdj;
12842                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12843                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12844                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12845                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12846                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12847                                            adj = clientAdj;
12848                                        } else {
12849                                            app.pendingUiClean = true;
12850                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12851                                                adj = ProcessList.VISIBLE_APP_ADJ;
12852                                            }
12853                                        }
12854                                        if (!client.hidden) {
12855                                            app.hidden = false;
12856                                        }
12857                                        if (client.keeping) {
12858                                            app.keeping = true;
12859                                        }
12860                                        adjType = "service";
12861                                    }
12862                                }
12863                                if (adjType != null) {
12864                                    app.adjType = adjType;
12865                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12866                                            .REASON_SERVICE_IN_USE;
12867                                    app.adjSource = cr.binding.client;
12868                                    app.adjSourceOom = clientAdj;
12869                                    app.adjTarget = s.name;
12870                                }
12871                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12872                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12873                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12874                                    }
12875                                }
12876                            }
12877                            final ActivityRecord a = cr.activity;
12878                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12879                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12880                                        (a.visible || a.state == ActivityState.RESUMED
12881                                         || a.state == ActivityState.PAUSING)) {
12882                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12883                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12884                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12885                                    }
12886                                    app.hidden = false;
12887                                    app.adjType = "service";
12888                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12889                                            .REASON_SERVICE_IN_USE;
12890                                    app.adjSource = a;
12891                                    app.adjSourceOom = adj;
12892                                    app.adjTarget = s.name;
12893                                }
12894                            }
12895                        }
12896                    }
12897                }
12898            }
12899
12900            // Finally, if this process has active services running in it, we
12901            // would like to avoid killing it unless it would prevent the current
12902            // application from running.  By default we put the process in
12903            // with the rest of the background processes; as we scan through
12904            // its services we may bump it up from there.
12905            if (adj > hiddenAdj) {
12906                adj = hiddenAdj;
12907                app.hidden = false;
12908                app.adjType = "bg-services";
12909            }
12910        }
12911
12912        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12913                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12914            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12915            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12916                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12917                ContentProviderRecord cpr = jt.next();
12918                for (int i = cpr.connections.size()-1;
12919                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12920                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12921                        i--) {
12922                    ContentProviderConnection conn = cpr.connections.get(i);
12923                    ProcessRecord client = conn.client;
12924                    if (client == app) {
12925                        // Being our own client is not interesting.
12926                        continue;
12927                    }
12928                    int myHiddenAdj = hiddenAdj;
12929                    if (myHiddenAdj > client.hiddenAdj) {
12930                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12931                            myHiddenAdj = client.hiddenAdj;
12932                        } else {
12933                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12934                        }
12935                    }
12936                    int myClientHiddenAdj = clientHiddenAdj;
12937                    if (myClientHiddenAdj > client.clientHiddenAdj) {
12938                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
12939                            myClientHiddenAdj = client.clientHiddenAdj;
12940                        } else {
12941                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12942                        }
12943                    }
12944                    int myEmptyAdj = emptyAdj;
12945                    if (myEmptyAdj > client.emptyAdj) {
12946                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12947                            myEmptyAdj = client.emptyAdj;
12948                        } else {
12949                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12950                        }
12951                    }
12952                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12953                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12954                    if (adj > clientAdj) {
12955                        if (app.hasShownUi && app != mHomeProcess
12956                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12957                            app.adjType = "bg-ui-provider";
12958                        } else {
12959                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12960                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12961                            app.adjType = "provider";
12962                        }
12963                        if (!client.hidden) {
12964                            app.hidden = false;
12965                        }
12966                        if (client.keeping) {
12967                            app.keeping = true;
12968                        }
12969                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12970                                .REASON_PROVIDER_IN_USE;
12971                        app.adjSource = client;
12972                        app.adjSourceOom = clientAdj;
12973                        app.adjTarget = cpr.name;
12974                    }
12975                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12976                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12977                    }
12978                }
12979                // If the provider has external (non-framework) process
12980                // dependencies, ensure that its adjustment is at least
12981                // FOREGROUND_APP_ADJ.
12982                if (cpr.hasExternalProcessHandles()) {
12983                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12984                        adj = ProcessList.FOREGROUND_APP_ADJ;
12985                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12986                        app.hidden = false;
12987                        app.keeping = true;
12988                        app.adjType = "provider";
12989                        app.adjTarget = cpr.name;
12990                    }
12991                }
12992            }
12993        }
12994
12995        if (adj == ProcessList.SERVICE_ADJ) {
12996            if (doingAll) {
12997                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12998                mNewNumServiceProcs++;
12999            }
13000            if (app.serviceb) {
13001                adj = ProcessList.SERVICE_B_ADJ;
13002            }
13003        } else {
13004            app.serviceb = false;
13005        }
13006
13007        app.nonStoppingAdj = adj;
13008
13009        if (hasStoppingActivities) {
13010            // Only upgrade adjustment.
13011            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13012                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13013                app.adjType = "stopping";
13014            }
13015        }
13016
13017        app.curRawAdj = adj;
13018
13019        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13020        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13021        if (adj > app.maxAdj) {
13022            adj = app.maxAdj;
13023            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13024                schedGroup = Process.THREAD_GROUP_DEFAULT;
13025            }
13026        }
13027        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13028            app.keeping = true;
13029        }
13030
13031        if (app.hasAboveClient) {
13032            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13033            // then we need to drop its adjustment to be lower than the service's
13034            // in order to honor the request.  We want to drop it by one adjustment
13035            // level...  but there is special meaning applied to various levels so
13036            // we will skip some of them.
13037            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13038                // System process will not get dropped, ever
13039            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13040                adj = ProcessList.VISIBLE_APP_ADJ;
13041            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13042                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13043            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13044                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13045            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13046                adj++;
13047            }
13048        }
13049
13050        int importance = app.memImportance;
13051        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13052            app.curAdj = adj;
13053            app.curSchedGroup = schedGroup;
13054            if (!interesting) {
13055                // For this reporting, if there is not something explicitly
13056                // interesting in this process then we will push it to the
13057                // background importance.
13058                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13059            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13060                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13061            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13062                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13063            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13064                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13065            } else if (adj >= ProcessList.SERVICE_ADJ) {
13066                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13067            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13068                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13069            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13070                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13071            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13072                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13073            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13074                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13075            } else {
13076                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13077            }
13078        }
13079
13080        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13081        if (foregroundActivities != app.foregroundActivities) {
13082            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13083        }
13084        if (changes != 0) {
13085            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13086            app.memImportance = importance;
13087            app.foregroundActivities = foregroundActivities;
13088            int i = mPendingProcessChanges.size()-1;
13089            ProcessChangeItem item = null;
13090            while (i >= 0) {
13091                item = mPendingProcessChanges.get(i);
13092                if (item.pid == app.pid) {
13093                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13094                    break;
13095                }
13096                i--;
13097            }
13098            if (i < 0) {
13099                // No existing item in pending changes; need a new one.
13100                final int NA = mAvailProcessChanges.size();
13101                if (NA > 0) {
13102                    item = mAvailProcessChanges.remove(NA-1);
13103                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13104                } else {
13105                    item = new ProcessChangeItem();
13106                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13107                }
13108                item.changes = 0;
13109                item.pid = app.pid;
13110                item.uid = app.info.uid;
13111                if (mPendingProcessChanges.size() == 0) {
13112                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13113                            "*** Enqueueing dispatch processes changed!");
13114                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13115                }
13116                mPendingProcessChanges.add(item);
13117            }
13118            item.changes |= changes;
13119            item.importance = importance;
13120            item.foregroundActivities = foregroundActivities;
13121            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13122                    + Integer.toHexString(System.identityHashCode(item))
13123                    + " " + app.toShortString() + ": changes=" + item.changes
13124                    + " importance=" + item.importance
13125                    + " foreground=" + item.foregroundActivities
13126                    + " type=" + app.adjType + " source=" + app.adjSource
13127                    + " target=" + app.adjTarget);
13128        }
13129
13130        return app.curRawAdj;
13131    }
13132
13133    /**
13134     * Ask a given process to GC right now.
13135     */
13136    final void performAppGcLocked(ProcessRecord app) {
13137        try {
13138            app.lastRequestedGc = SystemClock.uptimeMillis();
13139            if (app.thread != null) {
13140                if (app.reportLowMemory) {
13141                    app.reportLowMemory = false;
13142                    app.thread.scheduleLowMemory();
13143                } else {
13144                    app.thread.processInBackground();
13145                }
13146            }
13147        } catch (Exception e) {
13148            // whatever.
13149        }
13150    }
13151
13152    /**
13153     * Returns true if things are idle enough to perform GCs.
13154     */
13155    private final boolean canGcNowLocked() {
13156        boolean processingBroadcasts = false;
13157        for (BroadcastQueue q : mBroadcastQueues) {
13158            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13159                processingBroadcasts = true;
13160            }
13161        }
13162        return !processingBroadcasts
13163                && (mSleeping || (mMainStack.mResumedActivity != null &&
13164                        mMainStack.mResumedActivity.idle));
13165    }
13166
13167    /**
13168     * Perform GCs on all processes that are waiting for it, but only
13169     * if things are idle.
13170     */
13171    final void performAppGcsLocked() {
13172        final int N = mProcessesToGc.size();
13173        if (N <= 0) {
13174            return;
13175        }
13176        if (canGcNowLocked()) {
13177            while (mProcessesToGc.size() > 0) {
13178                ProcessRecord proc = mProcessesToGc.remove(0);
13179                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13180                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13181                            <= SystemClock.uptimeMillis()) {
13182                        // To avoid spamming the system, we will GC processes one
13183                        // at a time, waiting a few seconds between each.
13184                        performAppGcLocked(proc);
13185                        scheduleAppGcsLocked();
13186                        return;
13187                    } else {
13188                        // It hasn't been long enough since we last GCed this
13189                        // process...  put it in the list to wait for its time.
13190                        addProcessToGcListLocked(proc);
13191                        break;
13192                    }
13193                }
13194            }
13195
13196            scheduleAppGcsLocked();
13197        }
13198    }
13199
13200    /**
13201     * If all looks good, perform GCs on all processes waiting for them.
13202     */
13203    final void performAppGcsIfAppropriateLocked() {
13204        if (canGcNowLocked()) {
13205            performAppGcsLocked();
13206            return;
13207        }
13208        // Still not idle, wait some more.
13209        scheduleAppGcsLocked();
13210    }
13211
13212    /**
13213     * Schedule the execution of all pending app GCs.
13214     */
13215    final void scheduleAppGcsLocked() {
13216        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13217
13218        if (mProcessesToGc.size() > 0) {
13219            // Schedule a GC for the time to the next process.
13220            ProcessRecord proc = mProcessesToGc.get(0);
13221            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13222
13223            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13224            long now = SystemClock.uptimeMillis();
13225            if (when < (now+GC_TIMEOUT)) {
13226                when = now + GC_TIMEOUT;
13227            }
13228            mHandler.sendMessageAtTime(msg, when);
13229        }
13230    }
13231
13232    /**
13233     * Add a process to the array of processes waiting to be GCed.  Keeps the
13234     * list in sorted order by the last GC time.  The process can't already be
13235     * on the list.
13236     */
13237    final void addProcessToGcListLocked(ProcessRecord proc) {
13238        boolean added = false;
13239        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13240            if (mProcessesToGc.get(i).lastRequestedGc <
13241                    proc.lastRequestedGc) {
13242                added = true;
13243                mProcessesToGc.add(i+1, proc);
13244                break;
13245            }
13246        }
13247        if (!added) {
13248            mProcessesToGc.add(0, proc);
13249        }
13250    }
13251
13252    /**
13253     * Set up to ask a process to GC itself.  This will either do it
13254     * immediately, or put it on the list of processes to gc the next
13255     * time things are idle.
13256     */
13257    final void scheduleAppGcLocked(ProcessRecord app) {
13258        long now = SystemClock.uptimeMillis();
13259        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13260            return;
13261        }
13262        if (!mProcessesToGc.contains(app)) {
13263            addProcessToGcListLocked(app);
13264            scheduleAppGcsLocked();
13265        }
13266    }
13267
13268    final void checkExcessivePowerUsageLocked(boolean doKills) {
13269        updateCpuStatsNow();
13270
13271        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13272        boolean doWakeKills = doKills;
13273        boolean doCpuKills = doKills;
13274        if (mLastPowerCheckRealtime == 0) {
13275            doWakeKills = false;
13276        }
13277        if (mLastPowerCheckUptime == 0) {
13278            doCpuKills = false;
13279        }
13280        if (stats.isScreenOn()) {
13281            doWakeKills = false;
13282        }
13283        final long curRealtime = SystemClock.elapsedRealtime();
13284        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13285        final long curUptime = SystemClock.uptimeMillis();
13286        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13287        mLastPowerCheckRealtime = curRealtime;
13288        mLastPowerCheckUptime = curUptime;
13289        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13290            doWakeKills = false;
13291        }
13292        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13293            doCpuKills = false;
13294        }
13295        int i = mLruProcesses.size();
13296        while (i > 0) {
13297            i--;
13298            ProcessRecord app = mLruProcesses.get(i);
13299            if (!app.keeping) {
13300                long wtime;
13301                synchronized (stats) {
13302                    wtime = stats.getProcessWakeTime(app.info.uid,
13303                            app.pid, curRealtime);
13304                }
13305                long wtimeUsed = wtime - app.lastWakeTime;
13306                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13307                if (DEBUG_POWER) {
13308                    StringBuilder sb = new StringBuilder(128);
13309                    sb.append("Wake for ");
13310                    app.toShortString(sb);
13311                    sb.append(": over ");
13312                    TimeUtils.formatDuration(realtimeSince, sb);
13313                    sb.append(" used ");
13314                    TimeUtils.formatDuration(wtimeUsed, sb);
13315                    sb.append(" (");
13316                    sb.append((wtimeUsed*100)/realtimeSince);
13317                    sb.append("%)");
13318                    Slog.i(TAG, sb.toString());
13319                    sb.setLength(0);
13320                    sb.append("CPU for ");
13321                    app.toShortString(sb);
13322                    sb.append(": over ");
13323                    TimeUtils.formatDuration(uptimeSince, sb);
13324                    sb.append(" used ");
13325                    TimeUtils.formatDuration(cputimeUsed, sb);
13326                    sb.append(" (");
13327                    sb.append((cputimeUsed*100)/uptimeSince);
13328                    sb.append("%)");
13329                    Slog.i(TAG, sb.toString());
13330                }
13331                // If a process has held a wake lock for more
13332                // than 50% of the time during this period,
13333                // that sounds bad.  Kill!
13334                if (doWakeKills && realtimeSince > 0
13335                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13336                    synchronized (stats) {
13337                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13338                                realtimeSince, wtimeUsed);
13339                    }
13340                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13341                            + " (pid " + app.pid + "): held " + wtimeUsed
13342                            + " during " + realtimeSince);
13343                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13344                            app.processName, app.setAdj, "excessive wake lock");
13345                    Process.killProcessQuiet(app.pid);
13346                } else if (doCpuKills && uptimeSince > 0
13347                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13348                    synchronized (stats) {
13349                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13350                                uptimeSince, cputimeUsed);
13351                    }
13352                    Slog.w(TAG, "Excessive CPU in " + app.processName
13353                            + " (pid " + app.pid + "): used " + cputimeUsed
13354                            + " during " + uptimeSince);
13355                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13356                            app.processName, app.setAdj, "excessive cpu");
13357                    Process.killProcessQuiet(app.pid);
13358                } else {
13359                    app.lastWakeTime = wtime;
13360                    app.lastCpuTime = app.curCpuTime;
13361                }
13362            }
13363        }
13364    }
13365
13366    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13367            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13368        app.hiddenAdj = hiddenAdj;
13369        app.clientHiddenAdj = clientHiddenAdj;
13370        app.emptyAdj = emptyAdj;
13371
13372        if (app.thread == null) {
13373            return false;
13374        }
13375
13376        final boolean wasKeeping = app.keeping;
13377
13378        boolean success = true;
13379
13380        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13381
13382        if (app.curRawAdj != app.setRawAdj) {
13383            if (wasKeeping && !app.keeping) {
13384                // This app is no longer something we want to keep.  Note
13385                // its current wake lock time to later know to kill it if
13386                // it is not behaving well.
13387                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13388                synchronized (stats) {
13389                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13390                            app.pid, SystemClock.elapsedRealtime());
13391                }
13392                app.lastCpuTime = app.curCpuTime;
13393            }
13394
13395            app.setRawAdj = app.curRawAdj;
13396        }
13397
13398        if (app.curAdj != app.setAdj) {
13399            if (Process.setOomAdj(app.pid, app.curAdj)) {
13400                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13401                    TAG, "Set " + app.pid + " " + app.processName +
13402                    " adj " + app.curAdj + ": " + app.adjType);
13403                app.setAdj = app.curAdj;
13404            } else {
13405                success = false;
13406                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13407            }
13408        }
13409        if (app.setSchedGroup != app.curSchedGroup) {
13410            app.setSchedGroup = app.curSchedGroup;
13411            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13412                    "Setting process group of " + app.processName
13413                    + " to " + app.curSchedGroup);
13414            if (app.waitingToKill != null &&
13415                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13416                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13417                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13418                        app.processName, app.setAdj, app.waitingToKill);
13419                app.killedBackground = true;
13420                Process.killProcessQuiet(app.pid);
13421                success = false;
13422            } else {
13423                if (true) {
13424                    long oldId = Binder.clearCallingIdentity();
13425                    try {
13426                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13427                    } catch (Exception e) {
13428                        Slog.w(TAG, "Failed setting process group of " + app.pid
13429                                + " to " + app.curSchedGroup);
13430                        e.printStackTrace();
13431                    } finally {
13432                        Binder.restoreCallingIdentity(oldId);
13433                    }
13434                } else {
13435                    if (app.thread != null) {
13436                        try {
13437                            app.thread.setSchedulingGroup(app.curSchedGroup);
13438                        } catch (RemoteException e) {
13439                        }
13440                    }
13441                }
13442            }
13443        }
13444        return success;
13445    }
13446
13447    private final ActivityRecord resumedAppLocked() {
13448        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13449        if (resumedActivity == null || resumedActivity.app == null) {
13450            resumedActivity = mMainStack.mPausingActivity;
13451            if (resumedActivity == null || resumedActivity.app == null) {
13452                resumedActivity = mMainStack.topRunningActivityLocked(null);
13453            }
13454        }
13455        return resumedActivity;
13456    }
13457
13458    final boolean updateOomAdjLocked(ProcessRecord app) {
13459        final ActivityRecord TOP_ACT = resumedAppLocked();
13460        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13461        int curAdj = app.curAdj;
13462        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13463            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13464
13465        mAdjSeq++;
13466
13467        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13468                app.emptyAdj, TOP_APP, false);
13469        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13470            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13471        if (nowHidden != wasHidden) {
13472            // Changed to/from hidden state, so apps after it in the LRU
13473            // list may also be changed.
13474            updateOomAdjLocked();
13475        }
13476        return success;
13477    }
13478
13479    final void updateOomAdjLocked() {
13480        final ActivityRecord TOP_ACT = resumedAppLocked();
13481        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13482        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13483
13484        if (false) {
13485            RuntimeException e = new RuntimeException();
13486            e.fillInStackTrace();
13487            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13488        }
13489
13490        mAdjSeq++;
13491        mNewNumServiceProcs = 0;
13492
13493        final int emptyProcessLimit;
13494        final int hiddenProcessLimit;
13495        if (mProcessLimit <= 0) {
13496            emptyProcessLimit = hiddenProcessLimit = 0;
13497        } else if (mProcessLimit == 1) {
13498            emptyProcessLimit = 1;
13499            hiddenProcessLimit = 0;
13500        } else {
13501            emptyProcessLimit = (mProcessLimit*2)/3;
13502            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13503        }
13504
13505        // Let's determine how many processes we have running vs.
13506        // how many slots we have for background processes; we may want
13507        // to put multiple processes in a slot of there are enough of
13508        // them.
13509        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13510                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13511        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13512        if (numEmptyProcs > hiddenProcessLimit) {
13513            // If there are more empty processes than our limit on hidden
13514            // processes, then use the hidden process limit for the factor.
13515            // This ensures that the really old empty processes get pushed
13516            // down to the bottom, so if we are running low on memory we will
13517            // have a better chance at keeping around more hidden processes
13518            // instead of a gazillion empty processes.
13519            numEmptyProcs = hiddenProcessLimit;
13520        }
13521        int emptyFactor = numEmptyProcs/numSlots;
13522        if (emptyFactor < 1) emptyFactor = 1;
13523        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13524        if (hiddenFactor < 1) hiddenFactor = 1;
13525        int stepHidden = 0;
13526        int stepEmpty = 0;
13527        int numHidden = 0;
13528        int numEmpty = 0;
13529        int numTrimming = 0;
13530
13531        mNumNonHiddenProcs = 0;
13532        mNumHiddenProcs = 0;
13533
13534        // First update the OOM adjustment for each of the
13535        // application processes based on their current state.
13536        int i = mLruProcesses.size();
13537        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13538        int nextHiddenAdj = curHiddenAdj+1;
13539        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13540        int nextEmptyAdj = curEmptyAdj+2;
13541        int curClientHiddenAdj = curEmptyAdj;
13542        while (i > 0) {
13543            i--;
13544            ProcessRecord app = mLruProcesses.get(i);
13545            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13546            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13547            if (!app.killedBackground) {
13548                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13549                    // This process was assigned as a hidden process...  step the
13550                    // hidden level.
13551                    mNumHiddenProcs++;
13552                    if (curHiddenAdj != nextHiddenAdj) {
13553                        stepHidden++;
13554                        if (stepHidden >= hiddenFactor) {
13555                            stepHidden = 0;
13556                            curHiddenAdj = nextHiddenAdj;
13557                            nextHiddenAdj += 2;
13558                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13559                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13560                            }
13561                            if (curClientHiddenAdj <= curHiddenAdj) {
13562                                curClientHiddenAdj = curHiddenAdj + 1;
13563                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13564                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13565                                }
13566                            }
13567                        }
13568                    }
13569                    numHidden++;
13570                    if (numHidden > hiddenProcessLimit) {
13571                        Slog.i(TAG, "No longer want " + app.processName
13572                                + " (pid " + app.pid + "): hidden #" + numHidden);
13573                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13574                                app.processName, app.setAdj, "too many background");
13575                        app.killedBackground = true;
13576                        Process.killProcessQuiet(app.pid);
13577                    }
13578                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13579                    // This process has a client that has activities.  We will have
13580                    // given it the current hidden adj; here we will just leave it
13581                    // without stepping the hidden adj.
13582                    curClientHiddenAdj++;
13583                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13584                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13585                    }
13586                } else {
13587                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13588                        // This process was assigned as an empty process...  step the
13589                        // empty level.
13590                        if (curEmptyAdj != nextEmptyAdj) {
13591                            stepEmpty++;
13592                            if (stepEmpty >= emptyFactor) {
13593                                stepEmpty = 0;
13594                                curEmptyAdj = nextEmptyAdj;
13595                                nextEmptyAdj += 2;
13596                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13597                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13598                                }
13599                            }
13600                        }
13601                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13602                        mNumNonHiddenProcs++;
13603                    }
13604                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13605                            && !app.hasClientActivities) {
13606                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13607                                && app.lastActivityTime < oldTime) {
13608                            Slog.i(TAG, "No longer want " + app.processName
13609                                    + " (pid " + app.pid + "): empty for "
13610                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13611                                            / 1000) + "s");
13612                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13613                                    app.processName, app.setAdj, "old background process");
13614                            app.killedBackground = true;
13615                            Process.killProcessQuiet(app.pid);
13616                        } else {
13617                            numEmpty++;
13618                            if (numEmpty > emptyProcessLimit) {
13619                                Slog.i(TAG, "No longer want " + app.processName
13620                                        + " (pid " + app.pid + "): empty #" + numEmpty);
13621                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13622                                        app.processName, app.setAdj, "too many background");
13623                                app.killedBackground = true;
13624                                Process.killProcessQuiet(app.pid);
13625                            }
13626                        }
13627                    }
13628                }
13629                if (app.isolated && app.services.size() <= 0) {
13630                    // If this is an isolated process, and there are no
13631                    // services running in it, then the process is no longer
13632                    // needed.  We agressively kill these because we can by
13633                    // definition not re-use the same process again, and it is
13634                    // good to avoid having whatever code was running in them
13635                    // left sitting around after no longer needed.
13636                    Slog.i(TAG, "Isolated process " + app.processName
13637                            + " (pid " + app.pid + ") no longer needed");
13638                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13639                            app.processName, app.setAdj, "isolated not needed");
13640                    app.killedBackground = true;
13641                    Process.killProcessQuiet(app.pid);
13642                }
13643                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13644                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13645                        && !app.killedBackground) {
13646                    numTrimming++;
13647                }
13648            }
13649        }
13650
13651        mNumServiceProcs = mNewNumServiceProcs;
13652
13653        // Now determine the memory trimming level of background processes.
13654        // Unfortunately we need to start at the back of the list to do this
13655        // properly.  We only do this if the number of background apps we
13656        // are managing to keep around is less than half the maximum we desire;
13657        // if we are keeping a good number around, we'll let them use whatever
13658        // memory they want.
13659        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13660                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13661            final int numHiddenAndEmpty = numHidden + numEmpty;
13662            final int N = mLruProcesses.size();
13663            int factor = numTrimming/3;
13664            int minFactor = 2;
13665            if (mHomeProcess != null) minFactor++;
13666            if (mPreviousProcess != null) minFactor++;
13667            if (factor < minFactor) factor = minFactor;
13668            int step = 0;
13669            int fgTrimLevel;
13670            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13671                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13672            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13673                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13674            } else {
13675                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13676            }
13677            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13678            for (i=0; i<N; i++) {
13679                ProcessRecord app = mLruProcesses.get(i);
13680                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13681                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13682                        && !app.killedBackground) {
13683                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13684                        try {
13685                            app.thread.scheduleTrimMemory(curLevel);
13686                        } catch (RemoteException e) {
13687                        }
13688                        if (false) {
13689                            // For now we won't do this; our memory trimming seems
13690                            // to be good enough at this point that destroying
13691                            // activities causes more harm than good.
13692                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13693                                    && app != mHomeProcess && app != mPreviousProcess) {
13694                                // Need to do this on its own message because the stack may not
13695                                // be in a consistent state at this point.
13696                                // For these apps we will also finish their activities
13697                                // to help them free memory.
13698                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13699                            }
13700                        }
13701                    }
13702                    app.trimMemoryLevel = curLevel;
13703                    step++;
13704                    if (step >= factor) {
13705                        step = 0;
13706                        switch (curLevel) {
13707                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13708                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13709                                break;
13710                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13711                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13712                                break;
13713                        }
13714                    }
13715                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13716                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13717                            && app.thread != null) {
13718                        try {
13719                            app.thread.scheduleTrimMemory(
13720                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13721                        } catch (RemoteException e) {
13722                        }
13723                    }
13724                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13725                } else {
13726                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13727                            && app.pendingUiClean) {
13728                        // If this application is now in the background and it
13729                        // had done UI, then give it the special trim level to
13730                        // have it free UI resources.
13731                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13732                        if (app.trimMemoryLevel < level && app.thread != null) {
13733                            try {
13734                                app.thread.scheduleTrimMemory(level);
13735                            } catch (RemoteException e) {
13736                            }
13737                        }
13738                        app.pendingUiClean = false;
13739                    }
13740                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13741                        try {
13742                            app.thread.scheduleTrimMemory(fgTrimLevel);
13743                        } catch (RemoteException e) {
13744                        }
13745                    }
13746                    app.trimMemoryLevel = fgTrimLevel;
13747                }
13748            }
13749        } else {
13750            final int N = mLruProcesses.size();
13751            for (i=0; i<N; i++) {
13752                ProcessRecord app = mLruProcesses.get(i);
13753                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13754                        && app.pendingUiClean) {
13755                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13756                            && app.thread != null) {
13757                        try {
13758                            app.thread.scheduleTrimMemory(
13759                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13760                        } catch (RemoteException e) {
13761                        }
13762                    }
13763                    app.pendingUiClean = false;
13764                }
13765                app.trimMemoryLevel = 0;
13766            }
13767        }
13768
13769        if (mAlwaysFinishActivities) {
13770            // Need to do this on its own message because the stack may not
13771            // be in a consistent state at this point.
13772            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13773        }
13774    }
13775
13776    final void trimApplications() {
13777        synchronized (this) {
13778            int i;
13779
13780            // First remove any unused application processes whose package
13781            // has been removed.
13782            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13783                final ProcessRecord app = mRemovedProcesses.get(i);
13784                if (app.activities.size() == 0
13785                        && app.curReceiver == null && app.services.size() == 0) {
13786                    Slog.i(
13787                        TAG, "Exiting empty application process "
13788                        + app.processName + " ("
13789                        + (app.thread != null ? app.thread.asBinder() : null)
13790                        + ")\n");
13791                    if (app.pid > 0 && app.pid != MY_PID) {
13792                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13793                                app.processName, app.setAdj, "empty");
13794                        Process.killProcessQuiet(app.pid);
13795                    } else {
13796                        try {
13797                            app.thread.scheduleExit();
13798                        } catch (Exception e) {
13799                            // Ignore exceptions.
13800                        }
13801                    }
13802                    cleanUpApplicationRecordLocked(app, false, true, -1);
13803                    mRemovedProcesses.remove(i);
13804
13805                    if (app.persistent) {
13806                        if (app.persistent) {
13807                            addAppLocked(app.info, false);
13808                        }
13809                    }
13810                }
13811            }
13812
13813            // Now update the oom adj for all processes.
13814            updateOomAdjLocked();
13815        }
13816    }
13817
13818    /** This method sends the specified signal to each of the persistent apps */
13819    public void signalPersistentProcesses(int sig) throws RemoteException {
13820        if (sig != Process.SIGNAL_USR1) {
13821            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13822        }
13823
13824        synchronized (this) {
13825            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13826                    != PackageManager.PERMISSION_GRANTED) {
13827                throw new SecurityException("Requires permission "
13828                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13829            }
13830
13831            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13832                ProcessRecord r = mLruProcesses.get(i);
13833                if (r.thread != null && r.persistent) {
13834                    Process.sendSignal(r.pid, sig);
13835                }
13836            }
13837        }
13838    }
13839
13840    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13841        if (proc == null || proc == mProfileProc) {
13842            proc = mProfileProc;
13843            path = mProfileFile;
13844            profileType = mProfileType;
13845            clearProfilerLocked();
13846        }
13847        if (proc == null) {
13848            return;
13849        }
13850        try {
13851            proc.thread.profilerControl(false, path, null, profileType);
13852        } catch (RemoteException e) {
13853            throw new IllegalStateException("Process disappeared");
13854        }
13855    }
13856
13857    private void clearProfilerLocked() {
13858        if (mProfileFd != null) {
13859            try {
13860                mProfileFd.close();
13861            } catch (IOException e) {
13862            }
13863        }
13864        mProfileApp = null;
13865        mProfileProc = null;
13866        mProfileFile = null;
13867        mProfileType = 0;
13868        mAutoStopProfiler = false;
13869    }
13870
13871    public boolean profileControl(String process, int userId, boolean start,
13872            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13873
13874        try {
13875            synchronized (this) {
13876                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13877                // its own permission.
13878                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13879                        != PackageManager.PERMISSION_GRANTED) {
13880                    throw new SecurityException("Requires permission "
13881                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13882                }
13883
13884                if (start && fd == null) {
13885                    throw new IllegalArgumentException("null fd");
13886                }
13887
13888                ProcessRecord proc = null;
13889                if (process != null) {
13890                    proc = findProcessLocked(process, userId, "profileControl");
13891                }
13892
13893                if (start && (proc == null || proc.thread == null)) {
13894                    throw new IllegalArgumentException("Unknown process: " + process);
13895                }
13896
13897                if (start) {
13898                    stopProfilerLocked(null, null, 0);
13899                    setProfileApp(proc.info, proc.processName, path, fd, false);
13900                    mProfileProc = proc;
13901                    mProfileType = profileType;
13902                    try {
13903                        fd = fd.dup();
13904                    } catch (IOException e) {
13905                        fd = null;
13906                    }
13907                    proc.thread.profilerControl(start, path, fd, profileType);
13908                    fd = null;
13909                    mProfileFd = null;
13910                } else {
13911                    stopProfilerLocked(proc, path, profileType);
13912                    if (fd != null) {
13913                        try {
13914                            fd.close();
13915                        } catch (IOException e) {
13916                        }
13917                    }
13918                }
13919
13920                return true;
13921            }
13922        } catch (RemoteException e) {
13923            throw new IllegalStateException("Process disappeared");
13924        } finally {
13925            if (fd != null) {
13926                try {
13927                    fd.close();
13928                } catch (IOException e) {
13929                }
13930            }
13931        }
13932    }
13933
13934    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13935        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13936                userId, true, true, callName, null);
13937        ProcessRecord proc = null;
13938        try {
13939            int pid = Integer.parseInt(process);
13940            synchronized (mPidsSelfLocked) {
13941                proc = mPidsSelfLocked.get(pid);
13942            }
13943        } catch (NumberFormatException e) {
13944        }
13945
13946        if (proc == null) {
13947            HashMap<String, SparseArray<ProcessRecord>> all
13948                    = mProcessNames.getMap();
13949            SparseArray<ProcessRecord> procs = all.get(process);
13950            if (procs != null && procs.size() > 0) {
13951                proc = procs.valueAt(0);
13952                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13953                    for (int i=1; i<procs.size(); i++) {
13954                        ProcessRecord thisProc = procs.valueAt(i);
13955                        if (thisProc.userId == userId) {
13956                            proc = thisProc;
13957                            break;
13958                        }
13959                    }
13960                }
13961            }
13962        }
13963
13964        return proc;
13965    }
13966
13967    public boolean dumpHeap(String process, int userId, boolean managed,
13968            String path, ParcelFileDescriptor fd) throws RemoteException {
13969
13970        try {
13971            synchronized (this) {
13972                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13973                // its own permission (same as profileControl).
13974                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13975                        != PackageManager.PERMISSION_GRANTED) {
13976                    throw new SecurityException("Requires permission "
13977                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13978                }
13979
13980                if (fd == null) {
13981                    throw new IllegalArgumentException("null fd");
13982                }
13983
13984                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13985                if (proc == null || proc.thread == null) {
13986                    throw new IllegalArgumentException("Unknown process: " + process);
13987                }
13988
13989                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13990                if (!isDebuggable) {
13991                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13992                        throw new SecurityException("Process not debuggable: " + proc);
13993                    }
13994                }
13995
13996                proc.thread.dumpHeap(managed, path, fd);
13997                fd = null;
13998                return true;
13999            }
14000        } catch (RemoteException e) {
14001            throw new IllegalStateException("Process disappeared");
14002        } finally {
14003            if (fd != null) {
14004                try {
14005                    fd.close();
14006                } catch (IOException e) {
14007                }
14008            }
14009        }
14010    }
14011
14012    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14013    public void monitor() {
14014        synchronized (this) { }
14015    }
14016
14017    void onCoreSettingsChange(Bundle settings) {
14018        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14019            ProcessRecord processRecord = mLruProcesses.get(i);
14020            try {
14021                if (processRecord.thread != null) {
14022                    processRecord.thread.setCoreSettings(settings);
14023                }
14024            } catch (RemoteException re) {
14025                /* ignore */
14026            }
14027        }
14028    }
14029
14030    // Multi-user methods
14031
14032    @Override
14033    public boolean switchUser(int userId) {
14034        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14035                != PackageManager.PERMISSION_GRANTED) {
14036            String msg = "Permission Denial: switchUser() from pid="
14037                    + Binder.getCallingPid()
14038                    + ", uid=" + Binder.getCallingUid()
14039                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14040            Slog.w(TAG, msg);
14041            throw new SecurityException(msg);
14042        }
14043
14044        final long ident = Binder.clearCallingIdentity();
14045        try {
14046            synchronized (this) {
14047                final int oldUserId = mCurrentUserId;
14048                if (oldUserId == userId) {
14049                    return true;
14050                }
14051
14052                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14053                if (userInfo == null) {
14054                    Slog.w(TAG, "No user info for user #" + userId);
14055                    return false;
14056                }
14057
14058                mWindowManager.lockNow();
14059                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14060                        R.anim.screen_user_enter);
14061
14062                // If the user we are switching to is not currently started, then
14063                // we need to start it now.
14064                if (mStartedUsers.get(userId) == null) {
14065                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14066                    updateStartedUserArrayLocked();
14067                }
14068
14069                mCurrentUserId = userId;
14070                mCurrentUserArray = new int[] { userId };
14071                final Integer userIdInt = Integer.valueOf(userId);
14072                mUserLru.remove(userIdInt);
14073                mUserLru.add(userIdInt);
14074
14075                mWindowManager.setCurrentUser(userId);
14076
14077                final UserStartedState uss = mStartedUsers.get(userId);
14078
14079                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14080                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14081                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14082                        oldUserId, userId, uss));
14083                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14084                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14085                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14086                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14087                        | Intent.FLAG_RECEIVER_FOREGROUND);
14088                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14089                broadcastIntentLocked(null, null, intent,
14090                        null, null, 0, null, null, null,
14091                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14092
14093                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14094                    if (userId != 0) {
14095                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14096                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14097                        broadcastIntentLocked(null, null, intent, null,
14098                                new IIntentReceiver.Stub() {
14099                                    public void performReceive(Intent intent, int resultCode,
14100                                            String data, Bundle extras, boolean ordered,
14101                                            boolean sticky, int sendingUser) {
14102                                        userInitialized(uss);
14103                                    }
14104                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14105                                userId);
14106                        uss.initializing = true;
14107                    } else {
14108                        getUserManagerLocked().makeInitialized(userInfo.id);
14109                    }
14110                }
14111
14112                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14113                if (!haveActivities) {
14114                    startHomeActivityLocked(userId);
14115                }
14116
14117                getUserManagerLocked().userForeground(userId);
14118                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14119            }
14120        } finally {
14121            Binder.restoreCallingIdentity(ident);
14122        }
14123
14124        return true;
14125    }
14126
14127    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14128        long ident = Binder.clearCallingIdentity();
14129        try {
14130            Intent intent;
14131            if (oldUserId >= 0) {
14132                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14133                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14134                        | Intent.FLAG_RECEIVER_FOREGROUND);
14135                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14136                broadcastIntentLocked(null, null, intent,
14137                        null, null, 0, null, null, null,
14138                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14139            }
14140            if (newUserId >= 0) {
14141                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14142                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14143                        | Intent.FLAG_RECEIVER_FOREGROUND);
14144                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14145                broadcastIntentLocked(null, null, intent,
14146                        null, null, 0, null, null, null,
14147                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14148                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14149                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14150                        | Intent.FLAG_RECEIVER_FOREGROUND);
14151                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14152                broadcastIntentLocked(null, null, intent,
14153                        null, null, 0, null, null,
14154                        android.Manifest.permission.MANAGE_USERS,
14155                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14156            }
14157        } finally {
14158            Binder.restoreCallingIdentity(ident);
14159        }
14160    }
14161
14162    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14163            final int newUserId) {
14164        final int N = mUserSwitchObservers.beginBroadcast();
14165        if (N > 0) {
14166            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14167                int mCount = 0;
14168                @Override
14169                public void sendResult(Bundle data) throws RemoteException {
14170                    synchronized (ActivityManagerService.this) {
14171                        if (mCurUserSwitchCallback == this) {
14172                            mCount++;
14173                            if (mCount == N) {
14174                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14175                            }
14176                        }
14177                    }
14178                }
14179            };
14180            synchronized (this) {
14181                uss.switching = true;
14182                mCurUserSwitchCallback = callback;
14183            }
14184            for (int i=0; i<N; i++) {
14185                try {
14186                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14187                            newUserId, callback);
14188                } catch (RemoteException e) {
14189                }
14190            }
14191        } else {
14192            synchronized (this) {
14193                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14194            }
14195        }
14196        mUserSwitchObservers.finishBroadcast();
14197    }
14198
14199    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14200        synchronized (this) {
14201            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14202            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14203        }
14204    }
14205
14206    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14207        mCurUserSwitchCallback = null;
14208        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14209        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14210                oldUserId, newUserId, uss));
14211    }
14212
14213    void userInitialized(UserStartedState uss) {
14214        synchronized (ActivityManagerService.this) {
14215            getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14216            uss.initializing = false;
14217            completeSwitchAndInitalizeLocked(uss);
14218        }
14219    }
14220
14221    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14222        final int N = mUserSwitchObservers.beginBroadcast();
14223        for (int i=0; i<N; i++) {
14224            try {
14225                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14226            } catch (RemoteException e) {
14227            }
14228        }
14229        mUserSwitchObservers.finishBroadcast();
14230        synchronized (this) {
14231            uss.switching = false;
14232            completeSwitchAndInitalizeLocked(uss);
14233        }
14234    }
14235
14236    void completeSwitchAndInitalizeLocked(UserStartedState uss) {
14237        if (!uss.switching && !uss.initializing) {
14238            mWindowManager.stopFreezingScreen();
14239        }
14240    }
14241
14242    void finishUserSwitch(UserStartedState uss) {
14243        synchronized (this) {
14244            if (uss.mState == UserStartedState.STATE_BOOTING
14245                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14246                uss.mState = UserStartedState.STATE_RUNNING;
14247                final int userId = uss.mHandle.getIdentifier();
14248                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14249                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14250                broadcastIntentLocked(null, null, intent,
14251                        null, null, 0, null, null,
14252                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14253                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14254            }
14255            int num = mUserLru.size();
14256            int i = 0;
14257            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14258                Integer oldUserId = mUserLru.get(i);
14259                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14260                if (oldUss == null) {
14261                    // Shouldn't happen, but be sane if it does.
14262                    mUserLru.remove(i);
14263                    num--;
14264                    continue;
14265                }
14266                if (oldUss.mState == UserStartedState.STATE_STOPPING) {
14267                    // This user is already stopping, doesn't count.
14268                    num--;
14269                    i++;
14270                    continue;
14271                }
14272                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14273                    // Owner and current can't be stopped, but count as running.
14274                    i++;
14275                    continue;
14276                }
14277                // This is a user to be stopped.
14278                stopUserLocked(oldUserId, null);
14279                num--;
14280                i++;
14281            }
14282        }
14283    }
14284
14285    @Override
14286    public int stopUser(final int userId, final IStopUserCallback callback) {
14287        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14288                != PackageManager.PERMISSION_GRANTED) {
14289            String msg = "Permission Denial: switchUser() from pid="
14290                    + Binder.getCallingPid()
14291                    + ", uid=" + Binder.getCallingUid()
14292                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14293            Slog.w(TAG, msg);
14294            throw new SecurityException(msg);
14295        }
14296        if (userId <= 0) {
14297            throw new IllegalArgumentException("Can't stop primary user " + userId);
14298        }
14299        synchronized (this) {
14300            return stopUserLocked(userId, callback);
14301        }
14302    }
14303
14304    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14305        if (mCurrentUserId == userId) {
14306            return ActivityManager.USER_OP_IS_CURRENT;
14307        }
14308
14309        final UserStartedState uss = mStartedUsers.get(userId);
14310        if (uss == null) {
14311            // User is not started, nothing to do...  but we do need to
14312            // callback if requested.
14313            if (callback != null) {
14314                mHandler.post(new Runnable() {
14315                    @Override
14316                    public void run() {
14317                        try {
14318                            callback.userStopped(userId);
14319                        } catch (RemoteException e) {
14320                        }
14321                    }
14322                });
14323            }
14324            return ActivityManager.USER_OP_SUCCESS;
14325        }
14326
14327        if (callback != null) {
14328            uss.mStopCallbacks.add(callback);
14329        }
14330
14331        if (uss.mState != UserStartedState.STATE_STOPPING) {
14332            uss.mState = UserStartedState.STATE_STOPPING;
14333
14334            long ident = Binder.clearCallingIdentity();
14335            try {
14336                // Inform of user switch
14337                Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14338                final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14339                    @Override
14340                    public void performReceive(Intent intent, int resultCode, String data,
14341                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14342                        finishUserStop(uss);
14343                    }
14344                };
14345                broadcastIntentLocked(null, null, intent,
14346                        null, resultReceiver, 0, null, null, null,
14347                        true, false, MY_PID, Process.SYSTEM_UID, userId);
14348            } finally {
14349                Binder.restoreCallingIdentity(ident);
14350            }
14351        }
14352
14353        return ActivityManager.USER_OP_SUCCESS;
14354    }
14355
14356    void finishUserStop(UserStartedState uss) {
14357        final int userId = uss.mHandle.getIdentifier();
14358        boolean stopped;
14359        ArrayList<IStopUserCallback> callbacks;
14360        synchronized (this) {
14361            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14362            if (uss.mState != UserStartedState.STATE_STOPPING
14363                    || mStartedUsers.get(userId) != uss) {
14364                stopped = false;
14365            } else {
14366                stopped = true;
14367                // User can no longer run.
14368                mStartedUsers.remove(userId);
14369                mUserLru.remove(Integer.valueOf(userId));
14370                updateStartedUserArrayLocked();
14371
14372                // Clean up all state and processes associated with the user.
14373                // Kill all the processes for the user.
14374                forceStopUserLocked(userId);
14375            }
14376        }
14377
14378        for (int i=0; i<callbacks.size(); i++) {
14379            try {
14380                if (stopped) callbacks.get(i).userStopped(userId);
14381                else callbacks.get(i).userStopAborted(userId);
14382            } catch (RemoteException e) {
14383            }
14384        }
14385    }
14386
14387    @Override
14388    public UserInfo getCurrentUser() {
14389        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14390                != PackageManager.PERMISSION_GRANTED) && (
14391                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14392                != PackageManager.PERMISSION_GRANTED)) {
14393            String msg = "Permission Denial: getCurrentUser() from pid="
14394                    + Binder.getCallingPid()
14395                    + ", uid=" + Binder.getCallingUid()
14396                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14397            Slog.w(TAG, msg);
14398            throw new SecurityException(msg);
14399        }
14400        synchronized (this) {
14401            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14402        }
14403    }
14404
14405    int getCurrentUserIdLocked() {
14406        return mCurrentUserId;
14407    }
14408
14409    @Override
14410    public boolean isUserRunning(int userId) {
14411        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14412                != PackageManager.PERMISSION_GRANTED) {
14413            String msg = "Permission Denial: isUserRunning() from pid="
14414                    + Binder.getCallingPid()
14415                    + ", uid=" + Binder.getCallingUid()
14416                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14417            Slog.w(TAG, msg);
14418            throw new SecurityException(msg);
14419        }
14420        synchronized (this) {
14421            return isUserRunningLocked(userId);
14422        }
14423    }
14424
14425    boolean isUserRunningLocked(int userId) {
14426        UserStartedState state = mStartedUsers.get(userId);
14427        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14428    }
14429
14430    @Override
14431    public int[] getRunningUserIds() {
14432        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14433                != PackageManager.PERMISSION_GRANTED) {
14434            String msg = "Permission Denial: isUserRunning() from pid="
14435                    + Binder.getCallingPid()
14436                    + ", uid=" + Binder.getCallingUid()
14437                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14438            Slog.w(TAG, msg);
14439            throw new SecurityException(msg);
14440        }
14441        synchronized (this) {
14442            return mStartedUserArray;
14443        }
14444    }
14445
14446    private void updateStartedUserArrayLocked() {
14447        mStartedUserArray = new int[mStartedUsers.size()];
14448        for (int i=0; i<mStartedUsers.size();  i++) {
14449            mStartedUserArray[i] = mStartedUsers.keyAt(i);
14450        }
14451    }
14452
14453    @Override
14454    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14455        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14456                != PackageManager.PERMISSION_GRANTED) {
14457            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14458                    + Binder.getCallingPid()
14459                    + ", uid=" + Binder.getCallingUid()
14460                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14461            Slog.w(TAG, msg);
14462            throw new SecurityException(msg);
14463        }
14464
14465        mUserSwitchObservers.register(observer);
14466    }
14467
14468    @Override
14469    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14470        mUserSwitchObservers.unregister(observer);
14471    }
14472
14473    private boolean userExists(int userId) {
14474        if (userId == 0) {
14475            return true;
14476        }
14477        UserManagerService ums = getUserManagerLocked();
14478        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14479    }
14480
14481    int[] getUsersLocked() {
14482        UserManagerService ums = getUserManagerLocked();
14483        return ums != null ? ums.getUserIds() : new int[] { 0 };
14484    }
14485
14486    UserManagerService getUserManagerLocked() {
14487        if (mUserManager == null) {
14488            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14489            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14490        }
14491        return mUserManager;
14492    }
14493
14494    private void checkValidCaller(int uid, int userId) {
14495        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14496
14497        throw new SecurityException("Caller uid=" + uid
14498                + " is not privileged to communicate with user=" + userId);
14499    }
14500
14501    private int applyUserId(int uid, int userId) {
14502        return UserHandle.getUid(userId, uid);
14503    }
14504
14505    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14506        if (info == null) return null;
14507        ApplicationInfo newInfo = new ApplicationInfo(info);
14508        newInfo.uid = applyUserId(info.uid, userId);
14509        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14510                + info.packageName;
14511        return newInfo;
14512    }
14513
14514    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14515        if (aInfo == null
14516                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14517            return aInfo;
14518        }
14519
14520        ActivityInfo info = new ActivityInfo(aInfo);
14521        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14522        return info;
14523    }
14524}
14525