ActivityManagerService.java revision bc4ba82335c091cebaaee8b20987a61fb54c1727
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_PROVIDER = localLOGV || false;
185    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
186    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
187    static final boolean DEBUG_RESULTS = localLOGV || false;
188    static final boolean DEBUG_BACKUP = localLOGV || false;
189    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
190    static final boolean DEBUG_POWER = localLOGV || false;
191    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
192    static final boolean DEBUG_MU = localLOGV || false;
193    static final boolean VALIDATE_TOKENS = false;
194    static final boolean SHOW_ACTIVITY_START_TIME = true;
195
196    // Control over CPU and battery monitoring.
197    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
198    static final boolean MONITOR_CPU_USAGE = true;
199    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
200    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
201    static final boolean MONITOR_THREAD_CPU_USAGE = false;
202
203    // The flags that are set for all calls we make to the package manager.
204    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
205
206    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
207
208    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
209
210    // Maximum number of recent tasks that we can remember.
211    static final int MAX_RECENT_TASKS = 20;
212
213    // Amount of time after a call to stopAppSwitches() during which we will
214    // prevent further untrusted switches from happening.
215    static final long APP_SWITCH_DELAY_TIME = 5*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real.
219    static final int PROC_START_TIMEOUT = 10*1000;
220
221    // How long we wait for a launched process to attach to the activity manager
222    // before we decide it's never going to come up for real, when the process was
223    // started with a wrapper for instrumentation (such as Valgrind) because it
224    // could take much longer than usual.
225    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
226
227    // How long to wait after going idle before forcing apps to GC.
228    static final int GC_TIMEOUT = 5*1000;
229
230    // The minimum amount of time between successive GC requests for a process.
231    static final int GC_MIN_INTERVAL = 60*1000;
232
233    // The rate at which we check for apps using excessive power -- 15 mins.
234    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on wake locks to start killing things.
238    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // The minimum sample duration we will allow before deciding we have
241    // enough data on CPU usage to start killing things.
242    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
243
244    // How long we allow a receiver to run before giving up on it.
245    static final int BROADCAST_FG_TIMEOUT = 10*1000;
246    static final int BROADCAST_BG_TIMEOUT = 60*1000;
247
248    // How long we wait until we timeout on key dispatching.
249    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
250
251    // How long we wait until we timeout on key dispatching during instrumentation.
252    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
253
254    // Amount of time we wait for observers to handle a user switch before
255    // giving up on them and unfreezing the screen.
256    static final int USER_SWITCH_TIMEOUT = 2*1000;
257
258    // Maximum number of users we allow to be running at a time.
259    static final int MAX_RUNNING_USERS = 3;
260
261    static final int MY_PID = Process.myPid();
262
263    static final String[] EMPTY_STRING_ARRAY = new String[0];
264
265    public ActivityStack mMainStack;
266
267    private final boolean mHeadless;
268
269    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
270    // default actuion automatically.  Important for devices without direct input
271    // devices.
272    private boolean mShowDialogs = true;
273
274    /**
275     * Description of a request to start a new activity, which has been held
276     * due to app switches being disabled.
277     */
278    static class PendingActivityLaunch {
279        ActivityRecord r;
280        ActivityRecord sourceRecord;
281        int startFlags;
282    }
283
284    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
285            = new ArrayList<PendingActivityLaunch>();
286
287
288    BroadcastQueue mFgBroadcastQueue;
289    BroadcastQueue mBgBroadcastQueue;
290    // Convenient for easy iteration over the queues. Foreground is first
291    // so that dispatch of foreground broadcasts gets precedence.
292    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
293
294    BroadcastQueue broadcastQueueForIntent(Intent intent) {
295        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
296        if (DEBUG_BACKGROUND_BROADCAST) {
297            Slog.i(TAG, "Broadcast intent " + intent + " on "
298                    + (isFg ? "foreground" : "background")
299                    + " queue");
300        }
301        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
302    }
303
304    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
305        for (BroadcastQueue queue : mBroadcastQueues) {
306            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
307            if (r != null) {
308                return r;
309            }
310        }
311        return null;
312    }
313
314    /**
315     * Activity we have told the window manager to have key focus.
316     */
317    ActivityRecord mFocusedActivity = null;
318    /**
319     * List of intents that were used to start the most recent tasks.
320     */
321    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
322
323    /**
324     * Process management.
325     */
326    final ProcessList mProcessList = new ProcessList();
327
328    /**
329     * All of the applications we currently have running organized by name.
330     * The keys are strings of the application package name (as
331     * returned by the package manager), and the keys are ApplicationRecord
332     * objects.
333     */
334    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
335
336    /**
337     * The currently running isolated processes.
338     */
339    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
340
341    /**
342     * Counter for assigning isolated process uids, to avoid frequently reusing the
343     * same ones.
344     */
345    int mNextIsolatedProcessUid = 0;
346
347    /**
348     * The currently running heavy-weight process, if any.
349     */
350    ProcessRecord mHeavyWeightProcess = null;
351
352    /**
353     * The last time that various processes have crashed.
354     */
355    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
356
357    /**
358     * Set of applications that we consider to be bad, and will reject
359     * incoming broadcasts from (which the user has no control over).
360     * Processes are added to this set when they have crashed twice within
361     * a minimum amount of time; they are removed from it when they are
362     * later restarted (hopefully due to some user action).  The value is the
363     * time it was added to the list.
364     */
365    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
366
367    /**
368     * All of the processes we currently have running organized by pid.
369     * The keys are the pid running the application.
370     *
371     * <p>NOTE: This object is protected by its own lock, NOT the global
372     * activity manager lock!
373     */
374    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
375
376    /**
377     * All of the processes that have been forced to be foreground.  The key
378     * is the pid of the caller who requested it (we hold a death
379     * link on it).
380     */
381    abstract class ForegroundToken implements IBinder.DeathRecipient {
382        int pid;
383        IBinder token;
384    }
385    final SparseArray<ForegroundToken> mForegroundProcesses
386            = new SparseArray<ForegroundToken>();
387
388    /**
389     * List of records for processes that someone had tried to start before the
390     * system was ready.  We don't start them at that point, but ensure they
391     * are started by the time booting is complete.
392     */
393    final ArrayList<ProcessRecord> mProcessesOnHold
394            = new ArrayList<ProcessRecord>();
395
396    /**
397     * List of persistent applications that are in the process
398     * of being started.
399     */
400    final ArrayList<ProcessRecord> mPersistentStartingProcesses
401            = new ArrayList<ProcessRecord>();
402
403    /**
404     * Processes that are being forcibly torn down.
405     */
406    final ArrayList<ProcessRecord> mRemovedProcesses
407            = new ArrayList<ProcessRecord>();
408
409    /**
410     * List of running applications, sorted by recent usage.
411     * The first entry in the list is the least recently used.
412     * It contains ApplicationRecord objects.  This list does NOT include
413     * any persistent application records (since we never want to exit them).
414     */
415    final ArrayList<ProcessRecord> mLruProcesses
416            = new ArrayList<ProcessRecord>();
417
418    /**
419     * List of processes that should gc as soon as things are idle.
420     */
421    final ArrayList<ProcessRecord> mProcessesToGc
422            = new ArrayList<ProcessRecord>();
423
424    /**
425     * This is the process holding what we currently consider to be
426     * the "home" activity.
427     */
428    ProcessRecord mHomeProcess;
429
430    /**
431     * This is the process holding the activity the user last visited that
432     * is in a different process from the one they are currently in.
433     */
434    ProcessRecord mPreviousProcess;
435
436    /**
437     * The time at which the previous process was last visible.
438     */
439    long mPreviousProcessVisibleTime;
440
441    /**
442     * Which uses have been started, so are allowed to run code.
443     */
444    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
445
446    /**
447     * LRU list of history of current users.  Most recently current is at the end.
448     */
449    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
450
451    /**
452     * Constant array of the users that are currently started.
453     */
454    int[] mStartedUserArray = new int[] { 0 };
455
456    /**
457     * Registered observers of the user switching mechanics.
458     */
459    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
460            = new RemoteCallbackList<IUserSwitchObserver>();
461
462    /**
463     * Currently active user switch.
464     */
465    Object mCurUserSwitchCallback;
466
467    /**
468     * Packages that the user has asked to have run in screen size
469     * compatibility mode instead of filling the screen.
470     */
471    final CompatModePackages mCompatModePackages;
472
473    /**
474     * Set of PendingResultRecord objects that are currently active.
475     */
476    final HashSet mPendingResultRecords = new HashSet();
477
478    /**
479     * Set of IntentSenderRecord objects that are currently active.
480     */
481    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
482            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
483
484    /**
485     * Fingerprints (hashCode()) of stack traces that we've
486     * already logged DropBox entries for.  Guarded by itself.  If
487     * something (rogue user app) forces this over
488     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
489     */
490    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
491    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
492
493    /**
494     * Strict Mode background batched logging state.
495     *
496     * The string buffer is guarded by itself, and its lock is also
497     * used to determine if another batched write is already
498     * in-flight.
499     */
500    private final StringBuilder mStrictModeBuffer = new StringBuilder();
501
502    /**
503     * Keeps track of all IIntentReceivers that have been registered for
504     * broadcasts.  Hash keys are the receiver IBinder, hash value is
505     * a ReceiverList.
506     */
507    final HashMap mRegisteredReceivers = new HashMap();
508
509    /**
510     * Resolver for broadcast intents to registered receivers.
511     * Holds BroadcastFilter (subclass of IntentFilter).
512     */
513    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
514            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
515        @Override
516        protected boolean allowFilterResult(
517                BroadcastFilter filter, List<BroadcastFilter> dest) {
518            IBinder target = filter.receiverList.receiver.asBinder();
519            for (int i=dest.size()-1; i>=0; i--) {
520                if (dest.get(i).receiverList.receiver.asBinder() == target) {
521                    return false;
522                }
523            }
524            return true;
525        }
526
527        @Override
528        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
529            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
530                    || userId == filter.owningUserId) {
531                return super.newResult(filter, match, userId);
532            }
533            return null;
534        }
535
536        @Override
537        protected BroadcastFilter[] newArray(int size) {
538            return new BroadcastFilter[size];
539        }
540
541        @Override
542        protected String packageForFilter(BroadcastFilter filter) {
543            return filter.packageName;
544        }
545    };
546
547    /**
548     * State of all active sticky broadcasts per user.  Keys are the action of the
549     * sticky Intent, values are an ArrayList of all broadcasted intents with
550     * that action (which should usually be one).  The SparseArray is keyed
551     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
552     * for stickies that are sent to all users.
553     */
554    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
555            new SparseArray<HashMap<String, ArrayList<Intent>>>();
556
557    final ActiveServices mServices;
558
559    /**
560     * Backup/restore process management
561     */
562    String mBackupAppName = null;
563    BackupRecord mBackupTarget = null;
564
565    /**
566     * List of PendingThumbnailsRecord objects of clients who are still
567     * waiting to receive all of the thumbnails for a task.
568     */
569    final ArrayList mPendingThumbnails = new ArrayList();
570
571    /**
572     * List of HistoryRecord objects that have been finished and must
573     * still report back to a pending thumbnail receiver.
574     */
575    final ArrayList mCancelledThumbnails = new ArrayList();
576
577    final ProviderMap mProviderMap;
578
579    /**
580     * List of content providers who have clients waiting for them.  The
581     * application is currently being launched and the provider will be
582     * removed from this list once it is published.
583     */
584    final ArrayList<ContentProviderRecord> mLaunchingProviders
585            = new ArrayList<ContentProviderRecord>();
586
587    /**
588     * Global set of specific Uri permissions that have been granted.
589     */
590    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591            = new SparseArray<HashMap<Uri, UriPermission>>();
592
593    CoreSettingsObserver mCoreSettingsObserver;
594
595    /**
596     * Thread-local storage used to carry caller permissions over through
597     * indirect content-provider access.
598     * @see #ActivityManagerService.openContentUri()
599     */
600    private class Identity {
601        public int pid;
602        public int uid;
603
604        Identity(int _pid, int _uid) {
605            pid = _pid;
606            uid = _uid;
607        }
608    }
609
610    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
611
612    /**
613     * All information we have collected about the runtime performance of
614     * any user id that can impact battery performance.
615     */
616    final BatteryStatsService mBatteryStatsService;
617
618    /**
619     * information about component usage
620     */
621    final UsageStatsService mUsageStatsService;
622
623    /**
624     * Current configuration information.  HistoryRecord objects are given
625     * a reference to this object to indicate which configuration they are
626     * currently running in, so this object must be kept immutable.
627     */
628    Configuration mConfiguration = new Configuration();
629
630    /**
631     * Current sequencing integer of the configuration, for skipping old
632     * configurations.
633     */
634    int mConfigurationSeq = 0;
635
636    /**
637     * Hardware-reported OpenGLES version.
638     */
639    final int GL_ES_VERSION;
640
641    /**
642     * List of initialization arguments to pass to all processes when binding applications to them.
643     * For example, references to the commonly used services.
644     */
645    HashMap<String, IBinder> mAppBindArgs;
646
647    /**
648     * Temporary to avoid allocations.  Protected by main lock.
649     */
650    final StringBuilder mStringBuilder = new StringBuilder(256);
651
652    /**
653     * Used to control how we initialize the service.
654     */
655    boolean mStartRunning = false;
656    ComponentName mTopComponent;
657    String mTopAction;
658    String mTopData;
659    boolean mProcessesReady = false;
660    boolean mSystemReady = false;
661    boolean mBooting = false;
662    boolean mWaitingUpdate = false;
663    boolean mDidUpdate = false;
664    boolean mOnBattery = false;
665    boolean mLaunchWarningShown = false;
666
667    Context mContext;
668
669    int mFactoryTest;
670
671    boolean mCheckedForSetup;
672
673    /**
674     * The time at which we will allow normal application switches again,
675     * after a call to {@link #stopAppSwitches()}.
676     */
677    long mAppSwitchesAllowedTime;
678
679    /**
680     * This is set to true after the first switch after mAppSwitchesAllowedTime
681     * is set; any switches after that will clear the time.
682     */
683    boolean mDidAppSwitch;
684
685    /**
686     * Last time (in realtime) at which we checked for power usage.
687     */
688    long mLastPowerCheckRealtime;
689
690    /**
691     * Last time (in uptime) at which we checked for power usage.
692     */
693    long mLastPowerCheckUptime;
694
695    /**
696     * Set while we are wanting to sleep, to prevent any
697     * activities from being started/resumed.
698     */
699    boolean mSleeping = false;
700
701    /**
702     * State of external calls telling us if the device is asleep.
703     */
704    boolean mWentToSleep = false;
705
706    /**
707     * State of external call telling us if the lock screen is shown.
708     */
709    boolean mLockScreenShown = false;
710
711    /**
712     * Set if we are shutting down the system, similar to sleeping.
713     */
714    boolean mShuttingDown = false;
715
716    /**
717     * Task identifier that activities are currently being started
718     * in.  Incremented each time a new task is created.
719     * todo: Replace this with a TokenSpace class that generates non-repeating
720     * integers that won't wrap.
721     */
722    int mCurTask = 1;
723
724    /**
725     * Current sequence id for oom_adj computation traversal.
726     */
727    int mAdjSeq = 0;
728
729    /**
730     * Current sequence id for process LRU updating.
731     */
732    int mLruSeq = 0;
733
734    /**
735     * Keep track of the non-hidden/empty process we last found, to help
736     * determine how to distribute hidden/empty processes next time.
737     */
738    int mNumNonHiddenProcs = 0;
739
740    /**
741     * Keep track of the number of hidden procs, to balance oom adj
742     * distribution between those and empty procs.
743     */
744    int mNumHiddenProcs = 0;
745
746    /**
747     * Keep track of the number of service processes we last found, to
748     * determine on the next iteration which should be B services.
749     */
750    int mNumServiceProcs = 0;
751    int mNewNumServiceProcs = 0;
752
753    /**
754     * System monitoring: number of processes that died since the last
755     * N procs were started.
756     */
757    int[] mProcDeaths = new int[20];
758
759    /**
760     * This is set if we had to do a delayed dexopt of an app before launching
761     * it, to increasing the ANR timeouts in that case.
762     */
763    boolean mDidDexOpt;
764
765    String mDebugApp = null;
766    boolean mWaitForDebugger = false;
767    boolean mDebugTransient = false;
768    String mOrigDebugApp = null;
769    boolean mOrigWaitForDebugger = false;
770    boolean mAlwaysFinishActivities = false;
771    IActivityController mController = null;
772    String mProfileApp = null;
773    ProcessRecord mProfileProc = null;
774    String mProfileFile;
775    ParcelFileDescriptor mProfileFd;
776    int mProfileType = 0;
777    boolean mAutoStopProfiler = false;
778    String mOpenGlTraceApp = null;
779
780    static class ProcessChangeItem {
781        static final int CHANGE_ACTIVITIES = 1<<0;
782        static final int CHANGE_IMPORTANCE= 1<<1;
783        int changes;
784        int uid;
785        int pid;
786        int importance;
787        boolean foregroundActivities;
788    }
789
790    final RemoteCallbackList<IProcessObserver> mProcessObservers
791            = new RemoteCallbackList<IProcessObserver>();
792    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
793
794    final ArrayList<ProcessChangeItem> mPendingProcessChanges
795            = new ArrayList<ProcessChangeItem>();
796    final ArrayList<ProcessChangeItem> mAvailProcessChanges
797            = new ArrayList<ProcessChangeItem>();
798
799    /**
800     * Callback of last caller to {@link #requestPss}.
801     */
802    Runnable mRequestPssCallback;
803
804    /**
805     * Remaining processes for which we are waiting results from the last
806     * call to {@link #requestPss}.
807     */
808    final ArrayList<ProcessRecord> mRequestPssList
809            = new ArrayList<ProcessRecord>();
810
811    /**
812     * Runtime statistics collection thread.  This object's lock is used to
813     * protect all related state.
814     */
815    final Thread mProcessStatsThread;
816
817    /**
818     * Used to collect process stats when showing not responding dialog.
819     * Protected by mProcessStatsThread.
820     */
821    final ProcessStats mProcessStats = new ProcessStats(
822            MONITOR_THREAD_CPU_USAGE);
823    final AtomicLong mLastCpuTime = new AtomicLong(0);
824    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
825
826    long mLastWriteTime = 0;
827
828    /**
829     * Set to true after the system has finished booting.
830     */
831    boolean mBooted = false;
832
833    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
834    int mProcessLimitOverride = -1;
835
836    WindowManagerService mWindowManager;
837
838    static ActivityManagerService mSelf;
839    static ActivityThread mSystemThread;
840
841    private int mCurrentUserId = 0;
842    private int[] mCurrentUserArray = new int[] { 0 };
843    private UserManagerService mUserManager;
844
845    private final class AppDeathRecipient implements IBinder.DeathRecipient {
846        final ProcessRecord mApp;
847        final int mPid;
848        final IApplicationThread mAppThread;
849
850        AppDeathRecipient(ProcessRecord app, int pid,
851                IApplicationThread thread) {
852            if (localLOGV) Slog.v(
853                TAG, "New death recipient " + this
854                + " for thread " + thread.asBinder());
855            mApp = app;
856            mPid = pid;
857            mAppThread = thread;
858        }
859
860        public void binderDied() {
861            if (localLOGV) Slog.v(
862                TAG, "Death received in " + this
863                + " for thread " + mAppThread.asBinder());
864            synchronized(ActivityManagerService.this) {
865                appDiedLocked(mApp, mPid, mAppThread);
866            }
867        }
868    }
869
870    static final int SHOW_ERROR_MSG = 1;
871    static final int SHOW_NOT_RESPONDING_MSG = 2;
872    static final int SHOW_FACTORY_ERROR_MSG = 3;
873    static final int UPDATE_CONFIGURATION_MSG = 4;
874    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
875    static final int WAIT_FOR_DEBUGGER_MSG = 6;
876    static final int SERVICE_TIMEOUT_MSG = 12;
877    static final int UPDATE_TIME_ZONE = 13;
878    static final int SHOW_UID_ERROR_MSG = 14;
879    static final int IM_FEELING_LUCKY_MSG = 15;
880    static final int PROC_START_TIMEOUT_MSG = 20;
881    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
882    static final int KILL_APPLICATION_MSG = 22;
883    static final int FINALIZE_PENDING_INTENT_MSG = 23;
884    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
885    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
886    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
887    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
888    static final int CLEAR_DNS_CACHE = 28;
889    static final int UPDATE_HTTP_PROXY = 29;
890    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
891    static final int DISPATCH_PROCESSES_CHANGED = 31;
892    static final int DISPATCH_PROCESS_DIED = 32;
893    static final int REPORT_MEM_USAGE = 33;
894    static final int REPORT_USER_SWITCH_MSG = 34;
895    static final int CONTINUE_USER_SWITCH_MSG = 35;
896    static final int USER_SWITCH_TIMEOUT_MSG = 36;
897
898    static final int FIRST_ACTIVITY_STACK_MSG = 100;
899    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
900    static final int FIRST_COMPAT_MODE_MSG = 300;
901
902    AlertDialog mUidAlert;
903    CompatModeDialog mCompatModeDialog;
904    long mLastMemUsageReportTime = 0;
905
906    final Handler mHandler = new Handler() {
907        //public Handler() {
908        //    if (localLOGV) Slog.v(TAG, "Handler started!");
909        //}
910
911        public void handleMessage(Message msg) {
912            switch (msg.what) {
913            case SHOW_ERROR_MSG: {
914                HashMap data = (HashMap) msg.obj;
915                synchronized (ActivityManagerService.this) {
916                    ProcessRecord proc = (ProcessRecord)data.get("app");
917                    if (proc != null && proc.crashDialog != null) {
918                        Slog.e(TAG, "App already has crash dialog: " + proc);
919                        return;
920                    }
921                    AppErrorResult res = (AppErrorResult) data.get("result");
922                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
923                        Dialog d = new AppErrorDialog(mContext, res, proc);
924                        d.show();
925                        proc.crashDialog = d;
926                    } else {
927                        // The device is asleep, so just pretend that the user
928                        // saw a crash dialog and hit "force quit".
929                        res.set(0);
930                    }
931                }
932
933                ensureBootCompleted();
934            } break;
935            case SHOW_NOT_RESPONDING_MSG: {
936                synchronized (ActivityManagerService.this) {
937                    HashMap data = (HashMap) msg.obj;
938                    ProcessRecord proc = (ProcessRecord)data.get("app");
939                    if (proc != null && proc.anrDialog != null) {
940                        Slog.e(TAG, "App already has anr dialog: " + proc);
941                        return;
942                    }
943
944                    Intent intent = new Intent("android.intent.action.ANR");
945                    if (!mProcessesReady) {
946                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
947                                | Intent.FLAG_RECEIVER_FOREGROUND);
948                    }
949                    broadcastIntentLocked(null, null, intent,
950                            null, null, 0, null, null, null,
951                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
952
953                    if (mShowDialogs) {
954                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
955                                mContext, proc, (ActivityRecord)data.get("activity"));
956                        d.show();
957                        proc.anrDialog = d;
958                    } else {
959                        // Just kill the app if there is no dialog to be shown.
960                        killAppAtUsersRequest(proc, null);
961                    }
962                }
963
964                ensureBootCompleted();
965            } break;
966            case SHOW_STRICT_MODE_VIOLATION_MSG: {
967                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
968                synchronized (ActivityManagerService.this) {
969                    ProcessRecord proc = (ProcessRecord) data.get("app");
970                    if (proc == null) {
971                        Slog.e(TAG, "App not found when showing strict mode dialog.");
972                        break;
973                    }
974                    if (proc.crashDialog != null) {
975                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
976                        return;
977                    }
978                    AppErrorResult res = (AppErrorResult) data.get("result");
979                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
980                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
981                        d.show();
982                        proc.crashDialog = d;
983                    } else {
984                        // The device is asleep, so just pretend that the user
985                        // saw a crash dialog and hit "force quit".
986                        res.set(0);
987                    }
988                }
989                ensureBootCompleted();
990            } break;
991            case SHOW_FACTORY_ERROR_MSG: {
992                Dialog d = new FactoryErrorDialog(
993                    mContext, msg.getData().getCharSequence("msg"));
994                d.show();
995                ensureBootCompleted();
996            } break;
997            case UPDATE_CONFIGURATION_MSG: {
998                final ContentResolver resolver = mContext.getContentResolver();
999                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1000            } break;
1001            case GC_BACKGROUND_PROCESSES_MSG: {
1002                synchronized (ActivityManagerService.this) {
1003                    performAppGcsIfAppropriateLocked();
1004                }
1005            } break;
1006            case WAIT_FOR_DEBUGGER_MSG: {
1007                synchronized (ActivityManagerService.this) {
1008                    ProcessRecord app = (ProcessRecord)msg.obj;
1009                    if (msg.arg1 != 0) {
1010                        if (!app.waitedForDebugger) {
1011                            Dialog d = new AppWaitingForDebuggerDialog(
1012                                    ActivityManagerService.this,
1013                                    mContext, app);
1014                            app.waitDialog = d;
1015                            app.waitedForDebugger = true;
1016                            d.show();
1017                        }
1018                    } else {
1019                        if (app.waitDialog != null) {
1020                            app.waitDialog.dismiss();
1021                            app.waitDialog = null;
1022                        }
1023                    }
1024                }
1025            } break;
1026            case SERVICE_TIMEOUT_MSG: {
1027                if (mDidDexOpt) {
1028                    mDidDexOpt = false;
1029                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1030                    nmsg.obj = msg.obj;
1031                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1032                    return;
1033                }
1034                mServices.serviceTimeout((ProcessRecord)msg.obj);
1035            } break;
1036            case UPDATE_TIME_ZONE: {
1037                synchronized (ActivityManagerService.this) {
1038                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1039                        ProcessRecord r = mLruProcesses.get(i);
1040                        if (r.thread != null) {
1041                            try {
1042                                r.thread.updateTimeZone();
1043                            } catch (RemoteException ex) {
1044                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1045                            }
1046                        }
1047                    }
1048                }
1049            } break;
1050            case CLEAR_DNS_CACHE: {
1051                synchronized (ActivityManagerService.this) {
1052                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1053                        ProcessRecord r = mLruProcesses.get(i);
1054                        if (r.thread != null) {
1055                            try {
1056                                r.thread.clearDnsCache();
1057                            } catch (RemoteException ex) {
1058                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1059                            }
1060                        }
1061                    }
1062                }
1063            } break;
1064            case UPDATE_HTTP_PROXY: {
1065                ProxyProperties proxy = (ProxyProperties)msg.obj;
1066                String host = "";
1067                String port = "";
1068                String exclList = "";
1069                if (proxy != null) {
1070                    host = proxy.getHost();
1071                    port = Integer.toString(proxy.getPort());
1072                    exclList = proxy.getExclusionList();
1073                }
1074                synchronized (ActivityManagerService.this) {
1075                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1076                        ProcessRecord r = mLruProcesses.get(i);
1077                        if (r.thread != null) {
1078                            try {
1079                                r.thread.setHttpProxy(host, port, exclList);
1080                            } catch (RemoteException ex) {
1081                                Slog.w(TAG, "Failed to update http proxy for: " +
1082                                        r.info.processName);
1083                            }
1084                        }
1085                    }
1086                }
1087            } break;
1088            case SHOW_UID_ERROR_MSG: {
1089                String title = "System UIDs Inconsistent";
1090                String text = "UIDs on the system are inconsistent, you need to wipe your"
1091                        + " data partition or your device will be unstable.";
1092                Log.e(TAG, title + ": " + text);
1093                if (mShowDialogs) {
1094                    // XXX This is a temporary dialog, no need to localize.
1095                    AlertDialog d = new BaseErrorDialog(mContext);
1096                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1097                    d.setCancelable(false);
1098                    d.setTitle(title);
1099                    d.setMessage(text);
1100                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1101                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1102                    mUidAlert = d;
1103                    d.show();
1104                }
1105            } break;
1106            case IM_FEELING_LUCKY_MSG: {
1107                if (mUidAlert != null) {
1108                    mUidAlert.dismiss();
1109                    mUidAlert = null;
1110                }
1111            } break;
1112            case PROC_START_TIMEOUT_MSG: {
1113                if (mDidDexOpt) {
1114                    mDidDexOpt = false;
1115                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1116                    nmsg.obj = msg.obj;
1117                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1118                    return;
1119                }
1120                ProcessRecord app = (ProcessRecord)msg.obj;
1121                synchronized (ActivityManagerService.this) {
1122                    processStartTimedOutLocked(app);
1123                }
1124            } break;
1125            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1126                synchronized (ActivityManagerService.this) {
1127                    doPendingActivityLaunchesLocked(true);
1128                }
1129            } break;
1130            case KILL_APPLICATION_MSG: {
1131                synchronized (ActivityManagerService.this) {
1132                    int appid = msg.arg1;
1133                    boolean restart = (msg.arg2 == 1);
1134                    String pkg = (String) msg.obj;
1135                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1136                            UserHandle.USER_ALL);
1137                }
1138            } break;
1139            case FINALIZE_PENDING_INTENT_MSG: {
1140                ((PendingIntentRecord)msg.obj).completeFinalize();
1141            } break;
1142            case POST_HEAVY_NOTIFICATION_MSG: {
1143                INotificationManager inm = NotificationManager.getService();
1144                if (inm == null) {
1145                    return;
1146                }
1147
1148                ActivityRecord root = (ActivityRecord)msg.obj;
1149                ProcessRecord process = root.app;
1150                if (process == null) {
1151                    return;
1152                }
1153
1154                try {
1155                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1156                    String text = mContext.getString(R.string.heavy_weight_notification,
1157                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1158                    Notification notification = new Notification();
1159                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1160                    notification.when = 0;
1161                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1162                    notification.tickerText = text;
1163                    notification.defaults = 0; // please be quiet
1164                    notification.sound = null;
1165                    notification.vibrate = null;
1166                    notification.setLatestEventInfo(context, text,
1167                            mContext.getText(R.string.heavy_weight_notification_detail),
1168                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1169                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1170                                    new UserHandle(root.userId)));
1171
1172                    try {
1173                        int[] outId = new int[1];
1174                        inm.enqueueNotificationWithTag("android", null,
1175                                R.string.heavy_weight_notification,
1176                                notification, outId, root.userId);
1177                    } catch (RuntimeException e) {
1178                        Slog.w(ActivityManagerService.TAG,
1179                                "Error showing notification for heavy-weight app", e);
1180                    } catch (RemoteException e) {
1181                    }
1182                } catch (NameNotFoundException e) {
1183                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1184                }
1185            } break;
1186            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1187                INotificationManager inm = NotificationManager.getService();
1188                if (inm == null) {
1189                    return;
1190                }
1191                try {
1192                    inm.cancelNotificationWithTag("android", null,
1193                            R.string.heavy_weight_notification,  msg.arg1);
1194                } catch (RuntimeException e) {
1195                    Slog.w(ActivityManagerService.TAG,
1196                            "Error canceling notification for service", e);
1197                } catch (RemoteException e) {
1198                }
1199            } break;
1200            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1201                synchronized (ActivityManagerService.this) {
1202                    checkExcessivePowerUsageLocked(true);
1203                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1204                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1205                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1206                }
1207            } break;
1208            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1209                synchronized (ActivityManagerService.this) {
1210                    ActivityRecord ar = (ActivityRecord)msg.obj;
1211                    if (mCompatModeDialog != null) {
1212                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1213                                ar.info.applicationInfo.packageName)) {
1214                            return;
1215                        }
1216                        mCompatModeDialog.dismiss();
1217                        mCompatModeDialog = null;
1218                    }
1219                    if (ar != null && false) {
1220                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1221                                ar.packageName)) {
1222                            int mode = mCompatModePackages.computeCompatModeLocked(
1223                                    ar.info.applicationInfo);
1224                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1225                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1226                                mCompatModeDialog = new CompatModeDialog(
1227                                        ActivityManagerService.this, mContext,
1228                                        ar.info.applicationInfo);
1229                                mCompatModeDialog.show();
1230                            }
1231                        }
1232                    }
1233                }
1234                break;
1235            }
1236            case DISPATCH_PROCESSES_CHANGED: {
1237                dispatchProcessesChanged();
1238                break;
1239            }
1240            case DISPATCH_PROCESS_DIED: {
1241                final int pid = msg.arg1;
1242                final int uid = msg.arg2;
1243                dispatchProcessDied(pid, uid);
1244                break;
1245            }
1246            case REPORT_MEM_USAGE: {
1247                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1248                if (!isDebuggable) {
1249                    return;
1250                }
1251                synchronized (ActivityManagerService.this) {
1252                    long now = SystemClock.uptimeMillis();
1253                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1254                        // Don't report more than every 5 minutes to somewhat
1255                        // avoid spamming.
1256                        return;
1257                    }
1258                    mLastMemUsageReportTime = now;
1259                }
1260                Thread thread = new Thread() {
1261                    @Override public void run() {
1262                        StringBuilder dropBuilder = new StringBuilder(1024);
1263                        StringBuilder logBuilder = new StringBuilder(1024);
1264                        StringWriter oomSw = new StringWriter();
1265                        PrintWriter oomPw = new PrintWriter(oomSw);
1266                        StringWriter catSw = new StringWriter();
1267                        PrintWriter catPw = new PrintWriter(catSw);
1268                        String[] emptyArgs = new String[] { };
1269                        StringBuilder tag = new StringBuilder(128);
1270                        StringBuilder stack = new StringBuilder(128);
1271                        tag.append("Low on memory -- ");
1272                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1273                                tag, stack);
1274                        dropBuilder.append(stack);
1275                        dropBuilder.append('\n');
1276                        dropBuilder.append('\n');
1277                        String oomString = oomSw.toString();
1278                        dropBuilder.append(oomString);
1279                        dropBuilder.append('\n');
1280                        logBuilder.append(oomString);
1281                        try {
1282                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1283                                    "procrank", });
1284                            final InputStreamReader converter = new InputStreamReader(
1285                                    proc.getInputStream());
1286                            BufferedReader in = new BufferedReader(converter);
1287                            String line;
1288                            while (true) {
1289                                line = in.readLine();
1290                                if (line == null) {
1291                                    break;
1292                                }
1293                                if (line.length() > 0) {
1294                                    logBuilder.append(line);
1295                                    logBuilder.append('\n');
1296                                }
1297                                dropBuilder.append(line);
1298                                dropBuilder.append('\n');
1299                            }
1300                            converter.close();
1301                        } catch (IOException e) {
1302                        }
1303                        synchronized (ActivityManagerService.this) {
1304                            catPw.println();
1305                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1306                            catPw.println();
1307                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1308                                    false, false, null);
1309                            catPw.println();
1310                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1311                        }
1312                        dropBuilder.append(catSw.toString());
1313                        addErrorToDropBox("lowmem", null, "system_server", null,
1314                                null, tag.toString(), dropBuilder.toString(), null, null);
1315                        Slog.i(TAG, logBuilder.toString());
1316                        synchronized (ActivityManagerService.this) {
1317                            long now = SystemClock.uptimeMillis();
1318                            if (mLastMemUsageReportTime < now) {
1319                                mLastMemUsageReportTime = now;
1320                            }
1321                        }
1322                    }
1323                };
1324                thread.start();
1325                break;
1326            }
1327            case REPORT_USER_SWITCH_MSG: {
1328                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1329                break;
1330            }
1331            case CONTINUE_USER_SWITCH_MSG: {
1332                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1333                break;
1334            }
1335            case USER_SWITCH_TIMEOUT_MSG: {
1336                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1337                break;
1338            }
1339            }
1340        }
1341    };
1342
1343    public static void setSystemProcess() {
1344        try {
1345            ActivityManagerService m = mSelf;
1346
1347            ServiceManager.addService("activity", m, true);
1348            ServiceManager.addService("meminfo", new MemBinder(m));
1349            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1350            ServiceManager.addService("dbinfo", new DbBinder(m));
1351            if (MONITOR_CPU_USAGE) {
1352                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1353            }
1354            ServiceManager.addService("permission", new PermissionController(m));
1355
1356            ApplicationInfo info =
1357                mSelf.mContext.getPackageManager().getApplicationInfo(
1358                            "android", STOCK_PM_FLAGS);
1359            mSystemThread.installSystemApplicationInfo(info);
1360
1361            synchronized (mSelf) {
1362                ProcessRecord app = mSelf.newProcessRecordLocked(
1363                        mSystemThread.getApplicationThread(), info,
1364                        info.processName, false);
1365                app.persistent = true;
1366                app.pid = MY_PID;
1367                app.maxAdj = ProcessList.SYSTEM_ADJ;
1368                mSelf.mProcessNames.put(app.processName, app.uid, app);
1369                synchronized (mSelf.mPidsSelfLocked) {
1370                    mSelf.mPidsSelfLocked.put(app.pid, app);
1371                }
1372                mSelf.updateLruProcessLocked(app, true);
1373            }
1374        } catch (PackageManager.NameNotFoundException e) {
1375            throw new RuntimeException(
1376                    "Unable to find android system package", e);
1377        }
1378    }
1379
1380    public void setWindowManager(WindowManagerService wm) {
1381        mWindowManager = wm;
1382    }
1383
1384    public static final Context main(int factoryTest) {
1385        AThread thr = new AThread();
1386        thr.start();
1387
1388        synchronized (thr) {
1389            while (thr.mService == null) {
1390                try {
1391                    thr.wait();
1392                } catch (InterruptedException e) {
1393                }
1394            }
1395        }
1396
1397        ActivityManagerService m = thr.mService;
1398        mSelf = m;
1399        ActivityThread at = ActivityThread.systemMain();
1400        mSystemThread = at;
1401        Context context = at.getSystemContext();
1402        context.setTheme(android.R.style.Theme_Holo);
1403        m.mContext = context;
1404        m.mFactoryTest = factoryTest;
1405        m.mMainStack = new ActivityStack(m, context, true);
1406
1407        m.mBatteryStatsService.publish(context);
1408        m.mUsageStatsService.publish(context);
1409
1410        synchronized (thr) {
1411            thr.mReady = true;
1412            thr.notifyAll();
1413        }
1414
1415        m.startRunning(null, null, null, null);
1416
1417        return context;
1418    }
1419
1420    public static ActivityManagerService self() {
1421        return mSelf;
1422    }
1423
1424    static class AThread extends Thread {
1425        ActivityManagerService mService;
1426        boolean mReady = false;
1427
1428        public AThread() {
1429            super("ActivityManager");
1430        }
1431
1432        public void run() {
1433            Looper.prepare();
1434
1435            android.os.Process.setThreadPriority(
1436                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1437            android.os.Process.setCanSelfBackground(false);
1438
1439            ActivityManagerService m = new ActivityManagerService();
1440
1441            synchronized (this) {
1442                mService = m;
1443                notifyAll();
1444            }
1445
1446            synchronized (this) {
1447                while (!mReady) {
1448                    try {
1449                        wait();
1450                    } catch (InterruptedException e) {
1451                    }
1452                }
1453            }
1454
1455            // For debug builds, log event loop stalls to dropbox for analysis.
1456            if (StrictMode.conditionallyEnableDebugLogging()) {
1457                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1458            }
1459
1460            Looper.loop();
1461        }
1462    }
1463
1464    static class MemBinder extends Binder {
1465        ActivityManagerService mActivityManagerService;
1466        MemBinder(ActivityManagerService activityManagerService) {
1467            mActivityManagerService = activityManagerService;
1468        }
1469
1470        @Override
1471        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1472            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1473                    != PackageManager.PERMISSION_GRANTED) {
1474                pw.println("Permission Denial: can't dump meminfo from from pid="
1475                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1476                        + " without permission " + android.Manifest.permission.DUMP);
1477                return;
1478            }
1479
1480            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1481                    false, null, null, null);
1482        }
1483    }
1484
1485    static class GraphicsBinder extends Binder {
1486        ActivityManagerService mActivityManagerService;
1487        GraphicsBinder(ActivityManagerService activityManagerService) {
1488            mActivityManagerService = activityManagerService;
1489        }
1490
1491        @Override
1492        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1493            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1494                    != PackageManager.PERMISSION_GRANTED) {
1495                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1496                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1497                        + " without permission " + android.Manifest.permission.DUMP);
1498                return;
1499            }
1500
1501            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1502        }
1503    }
1504
1505    static class DbBinder extends Binder {
1506        ActivityManagerService mActivityManagerService;
1507        DbBinder(ActivityManagerService activityManagerService) {
1508            mActivityManagerService = activityManagerService;
1509        }
1510
1511        @Override
1512        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1513            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1514                    != PackageManager.PERMISSION_GRANTED) {
1515                pw.println("Permission Denial: can't dump dbinfo from from pid="
1516                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1517                        + " without permission " + android.Manifest.permission.DUMP);
1518                return;
1519            }
1520
1521            mActivityManagerService.dumpDbInfo(fd, pw, args);
1522        }
1523    }
1524
1525    static class CpuBinder extends Binder {
1526        ActivityManagerService mActivityManagerService;
1527        CpuBinder(ActivityManagerService activityManagerService) {
1528            mActivityManagerService = activityManagerService;
1529        }
1530
1531        @Override
1532        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1533            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1534                    != PackageManager.PERMISSION_GRANTED) {
1535                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1536                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1537                        + " without permission " + android.Manifest.permission.DUMP);
1538                return;
1539            }
1540
1541            synchronized (mActivityManagerService.mProcessStatsThread) {
1542                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1543                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1544                        SystemClock.uptimeMillis()));
1545            }
1546        }
1547    }
1548
1549    private ActivityManagerService() {
1550        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1551
1552        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1553        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1554        mBroadcastQueues[0] = mFgBroadcastQueue;
1555        mBroadcastQueues[1] = mBgBroadcastQueue;
1556
1557        mServices = new ActiveServices(this);
1558        mProviderMap = new ProviderMap(this);
1559
1560        File dataDir = Environment.getDataDirectory();
1561        File systemDir = new File(dataDir, "system");
1562        systemDir.mkdirs();
1563        mBatteryStatsService = new BatteryStatsService(new File(
1564                systemDir, "batterystats.bin").toString());
1565        mBatteryStatsService.getActiveStatistics().readLocked();
1566        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1567        mOnBattery = DEBUG_POWER ? true
1568                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1569        mBatteryStatsService.getActiveStatistics().setCallback(this);
1570
1571        mUsageStatsService = new UsageStatsService(new File(
1572                systemDir, "usagestats").toString());
1573        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1574
1575        // User 0 is the first and only user that runs at boot.
1576        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1577        mUserLru.add(Integer.valueOf(0));
1578        updateStartedUserArrayLocked();
1579
1580        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1581            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1582
1583        mConfiguration.setToDefaults();
1584        mConfiguration.setLocale(Locale.getDefault());
1585
1586        mConfigurationSeq = mConfiguration.seq = 1;
1587        mProcessStats.init();
1588
1589        mCompatModePackages = new CompatModePackages(this, systemDir);
1590
1591        // Add ourself to the Watchdog monitors.
1592        Watchdog.getInstance().addMonitor(this);
1593
1594        mProcessStatsThread = new Thread("ProcessStats") {
1595            public void run() {
1596                while (true) {
1597                    try {
1598                        try {
1599                            synchronized(this) {
1600                                final long now = SystemClock.uptimeMillis();
1601                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1602                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1603                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1604                                //        + ", write delay=" + nextWriteDelay);
1605                                if (nextWriteDelay < nextCpuDelay) {
1606                                    nextCpuDelay = nextWriteDelay;
1607                                }
1608                                if (nextCpuDelay > 0) {
1609                                    mProcessStatsMutexFree.set(true);
1610                                    this.wait(nextCpuDelay);
1611                                }
1612                            }
1613                        } catch (InterruptedException e) {
1614                        }
1615                        updateCpuStatsNow();
1616                    } catch (Exception e) {
1617                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1618                    }
1619                }
1620            }
1621        };
1622        mProcessStatsThread.start();
1623    }
1624
1625    @Override
1626    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1627            throws RemoteException {
1628        if (code == SYSPROPS_TRANSACTION) {
1629            // We need to tell all apps about the system property change.
1630            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1631            synchronized(this) {
1632                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1633                    final int NA = apps.size();
1634                    for (int ia=0; ia<NA; ia++) {
1635                        ProcessRecord app = apps.valueAt(ia);
1636                        if (app.thread != null) {
1637                            procs.add(app.thread.asBinder());
1638                        }
1639                    }
1640                }
1641            }
1642
1643            int N = procs.size();
1644            for (int i=0; i<N; i++) {
1645                Parcel data2 = Parcel.obtain();
1646                try {
1647                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1648                } catch (RemoteException e) {
1649                }
1650                data2.recycle();
1651            }
1652        }
1653        try {
1654            return super.onTransact(code, data, reply, flags);
1655        } catch (RuntimeException e) {
1656            // The activity manager only throws security exceptions, so let's
1657            // log all others.
1658            if (!(e instanceof SecurityException)) {
1659                Slog.e(TAG, "Activity Manager Crash", e);
1660            }
1661            throw e;
1662        }
1663    }
1664
1665    void updateCpuStats() {
1666        final long now = SystemClock.uptimeMillis();
1667        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1668            return;
1669        }
1670        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1671            synchronized (mProcessStatsThread) {
1672                mProcessStatsThread.notify();
1673            }
1674        }
1675    }
1676
1677    void updateCpuStatsNow() {
1678        synchronized (mProcessStatsThread) {
1679            mProcessStatsMutexFree.set(false);
1680            final long now = SystemClock.uptimeMillis();
1681            boolean haveNewCpuStats = false;
1682
1683            if (MONITOR_CPU_USAGE &&
1684                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1685                mLastCpuTime.set(now);
1686                haveNewCpuStats = true;
1687                mProcessStats.update();
1688                //Slog.i(TAG, mProcessStats.printCurrentState());
1689                //Slog.i(TAG, "Total CPU usage: "
1690                //        + mProcessStats.getTotalCpuPercent() + "%");
1691
1692                // Slog the cpu usage if the property is set.
1693                if ("true".equals(SystemProperties.get("events.cpu"))) {
1694                    int user = mProcessStats.getLastUserTime();
1695                    int system = mProcessStats.getLastSystemTime();
1696                    int iowait = mProcessStats.getLastIoWaitTime();
1697                    int irq = mProcessStats.getLastIrqTime();
1698                    int softIrq = mProcessStats.getLastSoftIrqTime();
1699                    int idle = mProcessStats.getLastIdleTime();
1700
1701                    int total = user + system + iowait + irq + softIrq + idle;
1702                    if (total == 0) total = 1;
1703
1704                    EventLog.writeEvent(EventLogTags.CPU,
1705                            ((user+system+iowait+irq+softIrq) * 100) / total,
1706                            (user * 100) / total,
1707                            (system * 100) / total,
1708                            (iowait * 100) / total,
1709                            (irq * 100) / total,
1710                            (softIrq * 100) / total);
1711                }
1712            }
1713
1714            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1715            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1716            synchronized(bstats) {
1717                synchronized(mPidsSelfLocked) {
1718                    if (haveNewCpuStats) {
1719                        if (mOnBattery) {
1720                            int perc = bstats.startAddingCpuLocked();
1721                            int totalUTime = 0;
1722                            int totalSTime = 0;
1723                            final int N = mProcessStats.countStats();
1724                            for (int i=0; i<N; i++) {
1725                                ProcessStats.Stats st = mProcessStats.getStats(i);
1726                                if (!st.working) {
1727                                    continue;
1728                                }
1729                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1730                                int otherUTime = (st.rel_utime*perc)/100;
1731                                int otherSTime = (st.rel_stime*perc)/100;
1732                                totalUTime += otherUTime;
1733                                totalSTime += otherSTime;
1734                                if (pr != null) {
1735                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1736                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1737                                            st.rel_stime-otherSTime);
1738                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1739                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1740                                } else {
1741                                    BatteryStatsImpl.Uid.Proc ps =
1742                                            bstats.getProcessStatsLocked(st.name, st.pid);
1743                                    if (ps != null) {
1744                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1745                                                st.rel_stime-otherSTime);
1746                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1747                                    }
1748                                }
1749                            }
1750                            bstats.finishAddingCpuLocked(perc, totalUTime,
1751                                    totalSTime, cpuSpeedTimes);
1752                        }
1753                    }
1754                }
1755
1756                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1757                    mLastWriteTime = now;
1758                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1759                }
1760            }
1761        }
1762    }
1763
1764    @Override
1765    public void batteryNeedsCpuUpdate() {
1766        updateCpuStatsNow();
1767    }
1768
1769    @Override
1770    public void batteryPowerChanged(boolean onBattery) {
1771        // When plugging in, update the CPU stats first before changing
1772        // the plug state.
1773        updateCpuStatsNow();
1774        synchronized (this) {
1775            synchronized(mPidsSelfLocked) {
1776                mOnBattery = DEBUG_POWER ? true : onBattery;
1777            }
1778        }
1779    }
1780
1781    /**
1782     * Initialize the application bind args. These are passed to each
1783     * process when the bindApplication() IPC is sent to the process. They're
1784     * lazily setup to make sure the services are running when they're asked for.
1785     */
1786    private HashMap<String, IBinder> getCommonServicesLocked() {
1787        if (mAppBindArgs == null) {
1788            mAppBindArgs = new HashMap<String, IBinder>();
1789
1790            // Setup the application init args
1791            mAppBindArgs.put("package", ServiceManager.getService("package"));
1792            mAppBindArgs.put("window", ServiceManager.getService("window"));
1793            mAppBindArgs.put(Context.ALARM_SERVICE,
1794                    ServiceManager.getService(Context.ALARM_SERVICE));
1795        }
1796        return mAppBindArgs;
1797    }
1798
1799    final void setFocusedActivityLocked(ActivityRecord r) {
1800        if (mFocusedActivity != r) {
1801            mFocusedActivity = r;
1802            if (r != null) {
1803                mWindowManager.setFocusedApp(r.appToken, true);
1804            }
1805        }
1806    }
1807
1808    private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1809        // put it on the LRU to keep track of when it should be exited.
1810        int lrui = mLruProcesses.indexOf(app);
1811        if (lrui >= 0) mLruProcesses.remove(lrui);
1812
1813        int i = mLruProcesses.size()-1;
1814        int skipTop = 0;
1815
1816        app.lruSeq = mLruSeq;
1817
1818        // compute the new weight for this process.
1819        app.lastActivityTime = SystemClock.uptimeMillis();
1820        if (app.activities.size() > 0) {
1821            // If this process has activities, we more strongly want to keep
1822            // it around.
1823            app.lruWeight = app.lastActivityTime;
1824        } else if (app.pubProviders.size() > 0) {
1825            // If this process contains content providers, we want to keep
1826            // it a little more strongly.
1827            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1828            // Also don't let it kick out the first few "real" hidden processes.
1829            skipTop = ProcessList.MIN_HIDDEN_APPS;
1830        } else {
1831            // If this process doesn't have activities, we less strongly
1832            // want to keep it around, and generally want to avoid getting
1833            // in front of any very recently used activities.
1834            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1835            // Also don't let it kick out the first few "real" hidden processes.
1836            skipTop = ProcessList.MIN_HIDDEN_APPS;
1837        }
1838
1839        while (i >= 0) {
1840            ProcessRecord p = mLruProcesses.get(i);
1841            // If this app shouldn't be in front of the first N background
1842            // apps, then skip over that many that are currently hidden.
1843            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1844                skipTop--;
1845            }
1846            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1847                mLruProcesses.add(i+1, app);
1848                break;
1849            }
1850            i--;
1851        }
1852        if (i < 0) {
1853            mLruProcesses.add(0, app);
1854        }
1855
1856        // If the app is currently using a content provider or service,
1857        // bump those processes as well.
1858        if (app.connections.size() > 0) {
1859            for (ConnectionRecord cr : app.connections) {
1860                if (cr.binding != null && cr.binding.service != null
1861                        && cr.binding.service.app != null
1862                        && cr.binding.service.app.lruSeq != mLruSeq) {
1863                    updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1864                }
1865            }
1866        }
1867        for (int j=app.conProviders.size()-1; j>=0; j--) {
1868            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1869            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1870                updateLruProcessInternalLocked(cpr.proc, i+1);
1871            }
1872        }
1873    }
1874
1875    final void updateLruProcessLocked(ProcessRecord app,
1876            boolean oomAdj) {
1877        mLruSeq++;
1878        updateLruProcessInternalLocked(app, 0);
1879
1880        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1881        if (oomAdj) {
1882            updateOomAdjLocked();
1883        }
1884    }
1885
1886    final ProcessRecord getProcessRecordLocked(
1887            String processName, int uid) {
1888        if (uid == Process.SYSTEM_UID) {
1889            // The system gets to run in any process.  If there are multiple
1890            // processes with the same uid, just pick the first (this
1891            // should never happen).
1892            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1893                    processName);
1894            if (procs == null) return null;
1895            final int N = procs.size();
1896            for (int i = 0; i < N; i++) {
1897                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1898            }
1899        }
1900        ProcessRecord proc = mProcessNames.get(processName, uid);
1901        return proc;
1902    }
1903
1904    void ensurePackageDexOpt(String packageName) {
1905        IPackageManager pm = AppGlobals.getPackageManager();
1906        try {
1907            if (pm.performDexOpt(packageName)) {
1908                mDidDexOpt = true;
1909            }
1910        } catch (RemoteException e) {
1911        }
1912    }
1913
1914    boolean isNextTransitionForward() {
1915        int transit = mWindowManager.getPendingAppTransition();
1916        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1917                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1918                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1919    }
1920
1921    final ProcessRecord startProcessLocked(String processName,
1922            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1923            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1924            boolean isolated) {
1925        ProcessRecord app;
1926        if (!isolated) {
1927            app = getProcessRecordLocked(processName, info.uid);
1928        } else {
1929            // If this is an isolated process, it can't re-use an existing process.
1930            app = null;
1931        }
1932        // We don't have to do anything more if:
1933        // (1) There is an existing application record; and
1934        // (2) The caller doesn't think it is dead, OR there is no thread
1935        //     object attached to it so we know it couldn't have crashed; and
1936        // (3) There is a pid assigned to it, so it is either starting or
1937        //     already running.
1938        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1939                + " app=" + app + " knownToBeDead=" + knownToBeDead
1940                + " thread=" + (app != null ? app.thread : null)
1941                + " pid=" + (app != null ? app.pid : -1));
1942        if (app != null && app.pid > 0) {
1943            if (!knownToBeDead || app.thread == null) {
1944                // We already have the app running, or are waiting for it to
1945                // come up (we have a pid but not yet its thread), so keep it.
1946                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1947                // If this is a new package in the process, add the package to the list
1948                app.addPackage(info.packageName);
1949                return app;
1950            } else {
1951                // An application record is attached to a previous process,
1952                // clean it up now.
1953                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1954                handleAppDiedLocked(app, true, true);
1955            }
1956        }
1957
1958        String hostingNameStr = hostingName != null
1959                ? hostingName.flattenToShortString() : null;
1960
1961        if (!isolated) {
1962            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1963                // If we are in the background, then check to see if this process
1964                // is bad.  If so, we will just silently fail.
1965                if (mBadProcesses.get(info.processName, info.uid) != null) {
1966                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1967                            + "/" + info.processName);
1968                    return null;
1969                }
1970            } else {
1971                // When the user is explicitly starting a process, then clear its
1972                // crash count so that we won't make it bad until they see at
1973                // least one crash dialog again, and make the process good again
1974                // if it had been bad.
1975                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1976                        + "/" + info.processName);
1977                mProcessCrashTimes.remove(info.processName, info.uid);
1978                if (mBadProcesses.get(info.processName, info.uid) != null) {
1979                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
1980                            UserHandle.getUserId(info.uid), info.uid,
1981                            info.processName);
1982                    mBadProcesses.remove(info.processName, info.uid);
1983                    if (app != null) {
1984                        app.bad = false;
1985                    }
1986                }
1987            }
1988        }
1989
1990        if (app == null) {
1991            app = newProcessRecordLocked(null, info, processName, isolated);
1992            if (app == null) {
1993                Slog.w(TAG, "Failed making new process record for "
1994                        + processName + "/" + info.uid + " isolated=" + isolated);
1995                return null;
1996            }
1997            mProcessNames.put(processName, app.uid, app);
1998            if (isolated) {
1999                mIsolatedProcesses.put(app.uid, app);
2000            }
2001        } else {
2002            // If this is a new package in the process, add the package to the list
2003            app.addPackage(info.packageName);
2004        }
2005
2006        // If the system is not ready yet, then hold off on starting this
2007        // process until it is.
2008        if (!mProcessesReady
2009                && !isAllowedWhileBooting(info)
2010                && !allowWhileBooting) {
2011            if (!mProcessesOnHold.contains(app)) {
2012                mProcessesOnHold.add(app);
2013            }
2014            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2015            return app;
2016        }
2017
2018        startProcessLocked(app, hostingType, hostingNameStr);
2019        return (app.pid != 0) ? app : null;
2020    }
2021
2022    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2023        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2024    }
2025
2026    private final void startProcessLocked(ProcessRecord app,
2027            String hostingType, String hostingNameStr) {
2028        if (app.pid > 0 && app.pid != MY_PID) {
2029            synchronized (mPidsSelfLocked) {
2030                mPidsSelfLocked.remove(app.pid);
2031                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2032            }
2033            app.setPid(0);
2034        }
2035
2036        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2037                "startProcessLocked removing on hold: " + app);
2038        mProcessesOnHold.remove(app);
2039
2040        updateCpuStats();
2041
2042        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2043        mProcDeaths[0] = 0;
2044
2045        try {
2046            int uid = app.uid;
2047
2048            int[] gids = null;
2049            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2050            if (!app.isolated) {
2051                int[] permGids = null;
2052                try {
2053                    final PackageManager pm = mContext.getPackageManager();
2054                    permGids = pm.getPackageGids(app.info.packageName);
2055
2056                    if (Environment.isExternalStorageEmulated()) {
2057                        if (pm.checkPermission(
2058                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2059                                app.info.packageName) == PERMISSION_GRANTED) {
2060                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2061                        } else {
2062                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2063                        }
2064                    }
2065                } catch (PackageManager.NameNotFoundException e) {
2066                    Slog.w(TAG, "Unable to retrieve gids", e);
2067                }
2068
2069                /*
2070                 * Add shared application GID so applications can share some
2071                 * resources like shared libraries
2072                 */
2073                if (permGids == null) {
2074                    gids = new int[1];
2075                } else {
2076                    gids = new int[permGids.length + 1];
2077                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2078                }
2079                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2080            }
2081            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2082                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2083                        && mTopComponent != null
2084                        && app.processName.equals(mTopComponent.getPackageName())) {
2085                    uid = 0;
2086                }
2087                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2088                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2089                    uid = 0;
2090                }
2091            }
2092            int debugFlags = 0;
2093            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2094                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2095                // Also turn on CheckJNI for debuggable apps. It's quite
2096                // awkward to turn on otherwise.
2097                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2098            }
2099            // Run the app in safe mode if its manifest requests so or the
2100            // system is booted in safe mode.
2101            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2102                Zygote.systemInSafeMode == true) {
2103                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2104            }
2105            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2106                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2107            }
2108            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2109                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2110            }
2111            if ("1".equals(SystemProperties.get("debug.assert"))) {
2112                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2113            }
2114
2115            // Start the process.  It will either succeed and return a result containing
2116            // the PID of the new process, or else throw a RuntimeException.
2117            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2118                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2119                    app.info.targetSdkVersion, null, null);
2120
2121            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2122            synchronized (bs) {
2123                if (bs.isOnBattery()) {
2124                    app.batteryStats.incStartsLocked();
2125                }
2126            }
2127
2128            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2129                    UserHandle.getUserId(uid), startResult.pid, uid,
2130                    app.processName, hostingType,
2131                    hostingNameStr != null ? hostingNameStr : "");
2132
2133            if (app.persistent) {
2134                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2135            }
2136
2137            StringBuilder buf = mStringBuilder;
2138            buf.setLength(0);
2139            buf.append("Start proc ");
2140            buf.append(app.processName);
2141            buf.append(" for ");
2142            buf.append(hostingType);
2143            if (hostingNameStr != null) {
2144                buf.append(" ");
2145                buf.append(hostingNameStr);
2146            }
2147            buf.append(": pid=");
2148            buf.append(startResult.pid);
2149            buf.append(" uid=");
2150            buf.append(uid);
2151            buf.append(" gids={");
2152            if (gids != null) {
2153                for (int gi=0; gi<gids.length; gi++) {
2154                    if (gi != 0) buf.append(", ");
2155                    buf.append(gids[gi]);
2156
2157                }
2158            }
2159            buf.append("}");
2160            Slog.i(TAG, buf.toString());
2161            app.setPid(startResult.pid);
2162            app.usingWrapper = startResult.usingWrapper;
2163            app.removed = false;
2164            synchronized (mPidsSelfLocked) {
2165                this.mPidsSelfLocked.put(startResult.pid, app);
2166                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2167                msg.obj = app;
2168                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2169                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2170            }
2171        } catch (RuntimeException e) {
2172            // XXX do better error recovery.
2173            app.setPid(0);
2174            Slog.e(TAG, "Failure starting process " + app.processName, e);
2175        }
2176    }
2177
2178    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2179        if (resumed) {
2180            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2181        } else {
2182            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2183        }
2184    }
2185
2186    boolean startHomeActivityLocked(int userId) {
2187        if (mHeadless) {
2188            // Added because none of the other calls to ensureBootCompleted seem to fire
2189            // when running headless.
2190            ensureBootCompleted();
2191            return false;
2192        }
2193
2194        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2195                && mTopAction == null) {
2196            // We are running in factory test mode, but unable to find
2197            // the factory test app, so just sit around displaying the
2198            // error message and don't try to start anything.
2199            return false;
2200        }
2201        Intent intent = new Intent(
2202            mTopAction,
2203            mTopData != null ? Uri.parse(mTopData) : null);
2204        intent.setComponent(mTopComponent);
2205        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2206            intent.addCategory(Intent.CATEGORY_HOME);
2207        }
2208        ActivityInfo aInfo =
2209            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2210        if (aInfo != null) {
2211            intent.setComponent(new ComponentName(
2212                    aInfo.applicationInfo.packageName, aInfo.name));
2213            // Don't do this if the home app is currently being
2214            // instrumented.
2215            aInfo = new ActivityInfo(aInfo);
2216            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2217            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2218                    aInfo.applicationInfo.uid);
2219            if (app == null || app.instrumentationClass == null) {
2220                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2221                mMainStack.startActivityLocked(null, intent, null, aInfo,
2222                        null, null, 0, 0, 0, 0, null, false, null);
2223            }
2224        }
2225
2226        return true;
2227    }
2228
2229    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2230        ActivityInfo ai = null;
2231        ComponentName comp = intent.getComponent();
2232        try {
2233            if (comp != null) {
2234                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2235            } else {
2236                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2237                        intent,
2238                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2239                            flags, userId);
2240
2241                if (info != null) {
2242                    ai = info.activityInfo;
2243                }
2244            }
2245        } catch (RemoteException e) {
2246            // ignore
2247        }
2248
2249        return ai;
2250    }
2251
2252    /**
2253     * Starts the "new version setup screen" if appropriate.
2254     */
2255    void startSetupActivityLocked() {
2256        // Only do this once per boot.
2257        if (mCheckedForSetup) {
2258            return;
2259        }
2260
2261        // We will show this screen if the current one is a different
2262        // version than the last one shown, and we are not running in
2263        // low-level factory test mode.
2264        final ContentResolver resolver = mContext.getContentResolver();
2265        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2266                Settings.Global.getInt(resolver,
2267                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2268            mCheckedForSetup = true;
2269
2270            // See if we should be showing the platform update setup UI.
2271            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2272            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2273                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2274
2275            // We don't allow third party apps to replace this.
2276            ResolveInfo ri = null;
2277            for (int i=0; ris != null && i<ris.size(); i++) {
2278                if ((ris.get(i).activityInfo.applicationInfo.flags
2279                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2280                    ri = ris.get(i);
2281                    break;
2282                }
2283            }
2284
2285            if (ri != null) {
2286                String vers = ri.activityInfo.metaData != null
2287                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2288                        : null;
2289                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2290                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2291                            Intent.METADATA_SETUP_VERSION);
2292                }
2293                String lastVers = Settings.Secure.getString(
2294                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2295                if (vers != null && !vers.equals(lastVers)) {
2296                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2297                    intent.setComponent(new ComponentName(
2298                            ri.activityInfo.packageName, ri.activityInfo.name));
2299                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2300                            null, null, 0, 0, 0, 0, null, false, null);
2301                }
2302            }
2303        }
2304    }
2305
2306    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2307        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2308    }
2309
2310    void enforceNotIsolatedCaller(String caller) {
2311        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2312            throw new SecurityException("Isolated process not allowed to call " + caller);
2313        }
2314    }
2315
2316    public int getFrontActivityScreenCompatMode() {
2317        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2318        synchronized (this) {
2319            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2320        }
2321    }
2322
2323    public void setFrontActivityScreenCompatMode(int mode) {
2324        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2325                "setFrontActivityScreenCompatMode");
2326        synchronized (this) {
2327            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2328        }
2329    }
2330
2331    public int getPackageScreenCompatMode(String packageName) {
2332        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2333        synchronized (this) {
2334            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2335        }
2336    }
2337
2338    public void setPackageScreenCompatMode(String packageName, int mode) {
2339        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2340                "setPackageScreenCompatMode");
2341        synchronized (this) {
2342            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2343        }
2344    }
2345
2346    public boolean getPackageAskScreenCompat(String packageName) {
2347        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2348        synchronized (this) {
2349            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2350        }
2351    }
2352
2353    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2354        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2355                "setPackageAskScreenCompat");
2356        synchronized (this) {
2357            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2358        }
2359    }
2360
2361    void reportResumedActivityLocked(ActivityRecord r) {
2362        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2363        updateUsageStats(r, true);
2364    }
2365
2366    private void dispatchProcessesChanged() {
2367        int N;
2368        synchronized (this) {
2369            N = mPendingProcessChanges.size();
2370            if (mActiveProcessChanges.length < N) {
2371                mActiveProcessChanges = new ProcessChangeItem[N];
2372            }
2373            mPendingProcessChanges.toArray(mActiveProcessChanges);
2374            mAvailProcessChanges.addAll(mPendingProcessChanges);
2375            mPendingProcessChanges.clear();
2376            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2377        }
2378        int i = mProcessObservers.beginBroadcast();
2379        while (i > 0) {
2380            i--;
2381            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2382            if (observer != null) {
2383                try {
2384                    for (int j=0; j<N; j++) {
2385                        ProcessChangeItem item = mActiveProcessChanges[j];
2386                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2387                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2388                                    + item.pid + " uid=" + item.uid + ": "
2389                                    + item.foregroundActivities);
2390                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2391                                    item.foregroundActivities);
2392                        }
2393                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2394                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2395                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2396                            observer.onImportanceChanged(item.pid, item.uid,
2397                                    item.importance);
2398                        }
2399                    }
2400                } catch (RemoteException e) {
2401                }
2402            }
2403        }
2404        mProcessObservers.finishBroadcast();
2405    }
2406
2407    private void dispatchProcessDied(int pid, int uid) {
2408        int i = mProcessObservers.beginBroadcast();
2409        while (i > 0) {
2410            i--;
2411            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2412            if (observer != null) {
2413                try {
2414                    observer.onProcessDied(pid, uid);
2415                } catch (RemoteException e) {
2416                }
2417            }
2418        }
2419        mProcessObservers.finishBroadcast();
2420    }
2421
2422    final void doPendingActivityLaunchesLocked(boolean doResume) {
2423        final int N = mPendingActivityLaunches.size();
2424        if (N <= 0) {
2425            return;
2426        }
2427        for (int i=0; i<N; i++) {
2428            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2429            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2430                    pal.startFlags, doResume && i == (N-1), null);
2431        }
2432        mPendingActivityLaunches.clear();
2433    }
2434
2435    public final int startActivity(IApplicationThread caller,
2436            Intent intent, String resolvedType, IBinder resultTo,
2437            String resultWho, int requestCode, int startFlags,
2438            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2439        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2440                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2441    }
2442
2443    public final int startActivityAsUser(IApplicationThread caller,
2444            Intent intent, String resolvedType, IBinder resultTo,
2445            String resultWho, int requestCode, int startFlags,
2446            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2447        enforceNotIsolatedCaller("startActivity");
2448        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2449                false, true, "startActivity", null);
2450        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2451                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2452                null, null, options, userId);
2453    }
2454
2455    public final WaitResult startActivityAndWait(IApplicationThread caller,
2456            Intent intent, String resolvedType, IBinder resultTo,
2457            String resultWho, int requestCode, int startFlags, String profileFile,
2458            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2459        enforceNotIsolatedCaller("startActivityAndWait");
2460        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2461                false, true, "startActivityAndWait", null);
2462        WaitResult res = new WaitResult();
2463        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2464                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2465                res, null, options, UserHandle.getCallingUserId());
2466        return res;
2467    }
2468
2469    public final int startActivityWithConfig(IApplicationThread caller,
2470            Intent intent, String resolvedType, IBinder resultTo,
2471            String resultWho, int requestCode, int startFlags, Configuration config,
2472            Bundle options, int userId) {
2473        enforceNotIsolatedCaller("startActivityWithConfig");
2474        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2475                false, true, "startActivityWithConfig", null);
2476        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2477                resultTo, resultWho, requestCode, startFlags,
2478                null, null, null, config, options, userId);
2479        return ret;
2480    }
2481
2482    public int startActivityIntentSender(IApplicationThread caller,
2483            IntentSender intent, Intent fillInIntent, String resolvedType,
2484            IBinder resultTo, String resultWho, int requestCode,
2485            int flagsMask, int flagsValues, Bundle options) {
2486        enforceNotIsolatedCaller("startActivityIntentSender");
2487        // Refuse possible leaked file descriptors
2488        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2489            throw new IllegalArgumentException("File descriptors passed in Intent");
2490        }
2491
2492        IIntentSender sender = intent.getTarget();
2493        if (!(sender instanceof PendingIntentRecord)) {
2494            throw new IllegalArgumentException("Bad PendingIntent object");
2495        }
2496
2497        PendingIntentRecord pir = (PendingIntentRecord)sender;
2498
2499        synchronized (this) {
2500            // If this is coming from the currently resumed activity, it is
2501            // effectively saying that app switches are allowed at this point.
2502            if (mMainStack.mResumedActivity != null
2503                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2504                            Binder.getCallingUid()) {
2505                mAppSwitchesAllowedTime = 0;
2506            }
2507        }
2508        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2509                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2510        return ret;
2511    }
2512
2513    public boolean startNextMatchingActivity(IBinder callingActivity,
2514            Intent intent, Bundle options) {
2515        // Refuse possible leaked file descriptors
2516        if (intent != null && intent.hasFileDescriptors() == true) {
2517            throw new IllegalArgumentException("File descriptors passed in Intent");
2518        }
2519
2520        synchronized (this) {
2521            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2522            if (r == null) {
2523                ActivityOptions.abort(options);
2524                return false;
2525            }
2526            if (r.app == null || r.app.thread == null) {
2527                // The caller is not running...  d'oh!
2528                ActivityOptions.abort(options);
2529                return false;
2530            }
2531            intent = new Intent(intent);
2532            // The caller is not allowed to change the data.
2533            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2534            // And we are resetting to find the next component...
2535            intent.setComponent(null);
2536
2537            ActivityInfo aInfo = null;
2538            try {
2539                List<ResolveInfo> resolves =
2540                    AppGlobals.getPackageManager().queryIntentActivities(
2541                            intent, r.resolvedType,
2542                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2543                            UserHandle.getCallingUserId());
2544
2545                // Look for the original activity in the list...
2546                final int N = resolves != null ? resolves.size() : 0;
2547                for (int i=0; i<N; i++) {
2548                    ResolveInfo rInfo = resolves.get(i);
2549                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2550                            && rInfo.activityInfo.name.equals(r.info.name)) {
2551                        // We found the current one...  the next matching is
2552                        // after it.
2553                        i++;
2554                        if (i<N) {
2555                            aInfo = resolves.get(i).activityInfo;
2556                        }
2557                        break;
2558                    }
2559                }
2560            } catch (RemoteException e) {
2561            }
2562
2563            if (aInfo == null) {
2564                // Nobody who is next!
2565                ActivityOptions.abort(options);
2566                return false;
2567            }
2568
2569            intent.setComponent(new ComponentName(
2570                    aInfo.applicationInfo.packageName, aInfo.name));
2571            intent.setFlags(intent.getFlags()&~(
2572                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2573                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2574                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2575                    Intent.FLAG_ACTIVITY_NEW_TASK));
2576
2577            // Okay now we need to start the new activity, replacing the
2578            // currently running activity.  This is a little tricky because
2579            // we want to start the new one as if the current one is finished,
2580            // but not finish the current one first so that there is no flicker.
2581            // And thus...
2582            final boolean wasFinishing = r.finishing;
2583            r.finishing = true;
2584
2585            // Propagate reply information over to the new activity.
2586            final ActivityRecord resultTo = r.resultTo;
2587            final String resultWho = r.resultWho;
2588            final int requestCode = r.requestCode;
2589            r.resultTo = null;
2590            if (resultTo != null) {
2591                resultTo.removeResultsLocked(r, resultWho, requestCode);
2592            }
2593
2594            final long origId = Binder.clearCallingIdentity();
2595            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2596                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2597                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2598                    options, false, null);
2599            Binder.restoreCallingIdentity(origId);
2600
2601            r.finishing = wasFinishing;
2602            if (res != ActivityManager.START_SUCCESS) {
2603                return false;
2604            }
2605            return true;
2606        }
2607    }
2608
2609    final int startActivityInPackage(int uid,
2610            Intent intent, String resolvedType, IBinder resultTo,
2611            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2612
2613        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2614                false, true, "startActivityInPackage", null);
2615
2616        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2617                resultTo, resultWho, requestCode, startFlags,
2618                null, null, null, null, options, userId);
2619        return ret;
2620    }
2621
2622    public final int startActivities(IApplicationThread caller,
2623            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2624            int userId) {
2625        enforceNotIsolatedCaller("startActivities");
2626        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2627                false, true, "startActivity", null);
2628        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2629                options, userId);
2630        return ret;
2631    }
2632
2633    final int startActivitiesInPackage(int uid,
2634            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2635            Bundle options, int userId) {
2636
2637        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2638                false, true, "startActivityInPackage", null);
2639        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2640                options, userId);
2641        return ret;
2642    }
2643
2644    final void addRecentTaskLocked(TaskRecord task) {
2645        int N = mRecentTasks.size();
2646        // Quick case: check if the top-most recent task is the same.
2647        if (N > 0 && mRecentTasks.get(0) == task) {
2648            return;
2649        }
2650        // Remove any existing entries that are the same kind of task.
2651        for (int i=0; i<N; i++) {
2652            TaskRecord tr = mRecentTasks.get(i);
2653            if (task.userId == tr.userId
2654                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2655                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2656                mRecentTasks.remove(i);
2657                i--;
2658                N--;
2659                if (task.intent == null) {
2660                    // If the new recent task we are adding is not fully
2661                    // specified, then replace it with the existing recent task.
2662                    task = tr;
2663                }
2664            }
2665        }
2666        if (N >= MAX_RECENT_TASKS) {
2667            mRecentTasks.remove(N-1);
2668        }
2669        mRecentTasks.add(0, task);
2670    }
2671
2672    public void setRequestedOrientation(IBinder token,
2673            int requestedOrientation) {
2674        synchronized (this) {
2675            ActivityRecord r = mMainStack.isInStackLocked(token);
2676            if (r == null) {
2677                return;
2678            }
2679            final long origId = Binder.clearCallingIdentity();
2680            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2681            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2682                    mConfiguration,
2683                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2684            if (config != null) {
2685                r.frozenBeforeDestroy = true;
2686                if (!updateConfigurationLocked(config, r, false, false)) {
2687                    mMainStack.resumeTopActivityLocked(null);
2688                }
2689            }
2690            Binder.restoreCallingIdentity(origId);
2691        }
2692    }
2693
2694    public int getRequestedOrientation(IBinder token) {
2695        synchronized (this) {
2696            ActivityRecord r = mMainStack.isInStackLocked(token);
2697            if (r == null) {
2698                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2699            }
2700            return mWindowManager.getAppOrientation(r.appToken);
2701        }
2702    }
2703
2704    /**
2705     * This is the internal entry point for handling Activity.finish().
2706     *
2707     * @param token The Binder token referencing the Activity we want to finish.
2708     * @param resultCode Result code, if any, from this Activity.
2709     * @param resultData Result data (Intent), if any, from this Activity.
2710     *
2711     * @return Returns true if the activity successfully finished, or false if it is still running.
2712     */
2713    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2714        // Refuse possible leaked file descriptors
2715        if (resultData != null && resultData.hasFileDescriptors() == true) {
2716            throw new IllegalArgumentException("File descriptors passed in Intent");
2717        }
2718
2719        synchronized(this) {
2720            if (mController != null) {
2721                // Find the first activity that is not finishing.
2722                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2723                if (next != null) {
2724                    // ask watcher if this is allowed
2725                    boolean resumeOK = true;
2726                    try {
2727                        resumeOK = mController.activityResuming(next.packageName);
2728                    } catch (RemoteException e) {
2729                        mController = null;
2730                    }
2731
2732                    if (!resumeOK) {
2733                        return false;
2734                    }
2735                }
2736            }
2737            final long origId = Binder.clearCallingIdentity();
2738            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2739                    resultData, "app-request", true);
2740            Binder.restoreCallingIdentity(origId);
2741            return res;
2742        }
2743    }
2744
2745    public final void finishHeavyWeightApp() {
2746        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2747                != PackageManager.PERMISSION_GRANTED) {
2748            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2749                    + Binder.getCallingPid()
2750                    + ", uid=" + Binder.getCallingUid()
2751                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2752            Slog.w(TAG, msg);
2753            throw new SecurityException(msg);
2754        }
2755
2756        synchronized(this) {
2757            if (mHeavyWeightProcess == null) {
2758                return;
2759            }
2760
2761            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2762                    mHeavyWeightProcess.activities);
2763            for (int i=0; i<activities.size(); i++) {
2764                ActivityRecord r = activities.get(i);
2765                if (!r.finishing) {
2766                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2767                    if (index >= 0) {
2768                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2769                                null, "finish-heavy", true);
2770                    }
2771                }
2772            }
2773
2774            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2775                    mHeavyWeightProcess.userId, 0));
2776            mHeavyWeightProcess = null;
2777        }
2778    }
2779
2780    public void crashApplication(int uid, int initialPid, String packageName,
2781            String message) {
2782        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2783                != PackageManager.PERMISSION_GRANTED) {
2784            String msg = "Permission Denial: crashApplication() from pid="
2785                    + Binder.getCallingPid()
2786                    + ", uid=" + Binder.getCallingUid()
2787                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2788            Slog.w(TAG, msg);
2789            throw new SecurityException(msg);
2790        }
2791
2792        synchronized(this) {
2793            ProcessRecord proc = null;
2794
2795            // Figure out which process to kill.  We don't trust that initialPid
2796            // still has any relation to current pids, so must scan through the
2797            // list.
2798            synchronized (mPidsSelfLocked) {
2799                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2800                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2801                    if (p.uid != uid) {
2802                        continue;
2803                    }
2804                    if (p.pid == initialPid) {
2805                        proc = p;
2806                        break;
2807                    }
2808                    for (String str : p.pkgList) {
2809                        if (str.equals(packageName)) {
2810                            proc = p;
2811                        }
2812                    }
2813                }
2814            }
2815
2816            if (proc == null) {
2817                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2818                        + " initialPid=" + initialPid
2819                        + " packageName=" + packageName);
2820                return;
2821            }
2822
2823            if (proc.thread != null) {
2824                if (proc.pid == Process.myPid()) {
2825                    Log.w(TAG, "crashApplication: trying to crash self!");
2826                    return;
2827                }
2828                long ident = Binder.clearCallingIdentity();
2829                try {
2830                    proc.thread.scheduleCrash(message);
2831                } catch (RemoteException e) {
2832                }
2833                Binder.restoreCallingIdentity(ident);
2834            }
2835        }
2836    }
2837
2838    public final void finishSubActivity(IBinder token, String resultWho,
2839            int requestCode) {
2840        synchronized(this) {
2841            final long origId = Binder.clearCallingIdentity();
2842            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2843            Binder.restoreCallingIdentity(origId);
2844        }
2845    }
2846
2847    public boolean finishActivityAffinity(IBinder token) {
2848        synchronized(this) {
2849            final long origId = Binder.clearCallingIdentity();
2850            boolean res = mMainStack.finishActivityAffinityLocked(token);
2851            Binder.restoreCallingIdentity(origId);
2852            return res;
2853        }
2854    }
2855
2856    public boolean willActivityBeVisible(IBinder token) {
2857        synchronized(this) {
2858            int i;
2859            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2860                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2861                if (r.appToken == token) {
2862                    return true;
2863                }
2864                if (r.fullscreen && !r.finishing) {
2865                    return false;
2866                }
2867            }
2868            return true;
2869        }
2870    }
2871
2872    public void overridePendingTransition(IBinder token, String packageName,
2873            int enterAnim, int exitAnim) {
2874        synchronized(this) {
2875            ActivityRecord self = mMainStack.isInStackLocked(token);
2876            if (self == null) {
2877                return;
2878            }
2879
2880            final long origId = Binder.clearCallingIdentity();
2881
2882            if (self.state == ActivityState.RESUMED
2883                    || self.state == ActivityState.PAUSING) {
2884                mWindowManager.overridePendingAppTransition(packageName,
2885                        enterAnim, exitAnim, null);
2886            }
2887
2888            Binder.restoreCallingIdentity(origId);
2889        }
2890    }
2891
2892    /**
2893     * Main function for removing an existing process from the activity manager
2894     * as a result of that process going away.  Clears out all connections
2895     * to the process.
2896     */
2897    private final void handleAppDiedLocked(ProcessRecord app,
2898            boolean restarting, boolean allowRestart) {
2899        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2900        if (!restarting) {
2901            mLruProcesses.remove(app);
2902        }
2903
2904        if (mProfileProc == app) {
2905            clearProfilerLocked();
2906        }
2907
2908        // Just in case...
2909        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2910            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2911            mMainStack.mPausingActivity = null;
2912        }
2913        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2914            mMainStack.mLastPausedActivity = null;
2915        }
2916
2917        // Remove this application's activities from active lists.
2918        mMainStack.removeHistoryRecordsForAppLocked(app);
2919
2920        boolean atTop = true;
2921        boolean hasVisibleActivities = false;
2922
2923        // Clean out the history list.
2924        int i = mMainStack.mHistory.size();
2925        if (localLOGV) Slog.v(
2926            TAG, "Removing app " + app + " from history with " + i + " entries");
2927        while (i > 0) {
2928            i--;
2929            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2930            if (localLOGV) Slog.v(
2931                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2932            if (r.app == app) {
2933                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2934                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2935                        RuntimeException here = new RuntimeException("here");
2936                        here.fillInStackTrace();
2937                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2938                                + ": haveState=" + r.haveState
2939                                + " stateNotNeeded=" + r.stateNotNeeded
2940                                + " finishing=" + r.finishing
2941                                + " state=" + r.state, here);
2942                    }
2943                    if (!r.finishing) {
2944                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2945                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2946                                r.userId, System.identityHashCode(r),
2947                                r.task.taskId, r.shortComponentName,
2948                                "proc died without state saved");
2949                    }
2950                    mMainStack.removeActivityFromHistoryLocked(r);
2951
2952                } else {
2953                    // We have the current state for this activity, so
2954                    // it can be restarted later when needed.
2955                    if (localLOGV) Slog.v(
2956                        TAG, "Keeping entry, setting app to null");
2957                    if (r.visible) {
2958                        hasVisibleActivities = true;
2959                    }
2960                    r.app = null;
2961                    r.nowVisible = false;
2962                    if (!r.haveState) {
2963                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2964                                "App died, clearing saved state of " + r);
2965                        r.icicle = null;
2966                    }
2967                }
2968
2969                r.stack.cleanUpActivityLocked(r, true, true);
2970            }
2971            atTop = false;
2972        }
2973
2974        app.activities.clear();
2975
2976        if (app.instrumentationClass != null) {
2977            Slog.w(TAG, "Crash of app " + app.processName
2978                  + " running instrumentation " + app.instrumentationClass);
2979            Bundle info = new Bundle();
2980            info.putString("shortMsg", "Process crashed.");
2981            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2982        }
2983
2984        if (!restarting) {
2985            if (!mMainStack.resumeTopActivityLocked(null)) {
2986                // If there was nothing to resume, and we are not already
2987                // restarting this process, but there is a visible activity that
2988                // is hosted by the process...  then make sure all visible
2989                // activities are running, taking care of restarting this
2990                // process.
2991                if (hasVisibleActivities) {
2992                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2993                }
2994            }
2995        }
2996    }
2997
2998    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2999        IBinder threadBinder = thread.asBinder();
3000        // Find the application record.
3001        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3002            ProcessRecord rec = mLruProcesses.get(i);
3003            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3004                return i;
3005            }
3006        }
3007        return -1;
3008    }
3009
3010    final ProcessRecord getRecordForAppLocked(
3011            IApplicationThread thread) {
3012        if (thread == null) {
3013            return null;
3014        }
3015
3016        int appIndex = getLRURecordIndexForAppLocked(thread);
3017        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3018    }
3019
3020    final void appDiedLocked(ProcessRecord app, int pid,
3021            IApplicationThread thread) {
3022
3023        mProcDeaths[0]++;
3024
3025        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3026        synchronized (stats) {
3027            stats.noteProcessDiedLocked(app.info.uid, pid);
3028        }
3029
3030        // Clean up already done if the process has been re-started.
3031        if (app.pid == pid && app.thread != null &&
3032                app.thread.asBinder() == thread.asBinder()) {
3033            if (!app.killedBackground) {
3034                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3035                        + ") has died.");
3036            }
3037            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3038            if (localLOGV) Slog.v(
3039                TAG, "Dying app: " + app + ", pid: " + pid
3040                + ", thread: " + thread.asBinder());
3041            boolean doLowMem = app.instrumentationClass == null;
3042            handleAppDiedLocked(app, false, true);
3043
3044            if (doLowMem) {
3045                // If there are no longer any background processes running,
3046                // and the app that died was not running instrumentation,
3047                // then tell everyone we are now low on memory.
3048                boolean haveBg = false;
3049                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3050                    ProcessRecord rec = mLruProcesses.get(i);
3051                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3052                        haveBg = true;
3053                        break;
3054                    }
3055                }
3056
3057                if (!haveBg) {
3058                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3059                    long now = SystemClock.uptimeMillis();
3060                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3061                        ProcessRecord rec = mLruProcesses.get(i);
3062                        if (rec != app && rec.thread != null &&
3063                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3064                            // The low memory report is overriding any current
3065                            // state for a GC request.  Make sure to do
3066                            // heavy/important/visible/foreground processes first.
3067                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3068                                rec.lastRequestedGc = 0;
3069                            } else {
3070                                rec.lastRequestedGc = rec.lastLowMemory;
3071                            }
3072                            rec.reportLowMemory = true;
3073                            rec.lastLowMemory = now;
3074                            mProcessesToGc.remove(rec);
3075                            addProcessToGcListLocked(rec);
3076                        }
3077                    }
3078                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3079                    scheduleAppGcsLocked();
3080                }
3081            }
3082        } else if (app.pid != pid) {
3083            // A new process has already been started.
3084            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3085                    + ") has died and restarted (pid " + app.pid + ").");
3086            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3087        } else if (DEBUG_PROCESSES) {
3088            Slog.d(TAG, "Received spurious death notification for thread "
3089                    + thread.asBinder());
3090        }
3091    }
3092
3093    /**
3094     * If a stack trace dump file is configured, dump process stack traces.
3095     * @param clearTraces causes the dump file to be erased prior to the new
3096     *    traces being written, if true; when false, the new traces will be
3097     *    appended to any existing file content.
3098     * @param firstPids of dalvik VM processes to dump stack traces for first
3099     * @param lastPids of dalvik VM processes to dump stack traces for last
3100     * @param nativeProcs optional list of native process names to dump stack crawls
3101     * @return file containing stack traces, or null if no dump file is configured
3102     */
3103    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3104            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3105        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3106        if (tracesPath == null || tracesPath.length() == 0) {
3107            return null;
3108        }
3109
3110        File tracesFile = new File(tracesPath);
3111        try {
3112            File tracesDir = tracesFile.getParentFile();
3113            if (!tracesDir.exists()) {
3114                tracesFile.mkdirs();
3115                if (!SELinux.restorecon(tracesDir)) {
3116                    return null;
3117                }
3118            }
3119            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3120
3121            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3122            tracesFile.createNewFile();
3123            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3124        } catch (IOException e) {
3125            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3126            return null;
3127        }
3128
3129        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3130        return tracesFile;
3131    }
3132
3133    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3134            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3135        // Use a FileObserver to detect when traces finish writing.
3136        // The order of traces is considered important to maintain for legibility.
3137        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3138            public synchronized void onEvent(int event, String path) { notify(); }
3139        };
3140
3141        try {
3142            observer.startWatching();
3143
3144            // First collect all of the stacks of the most important pids.
3145            if (firstPids != null) {
3146                try {
3147                    int num = firstPids.size();
3148                    for (int i = 0; i < num; i++) {
3149                        synchronized (observer) {
3150                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3151                            observer.wait(200);  // Wait for write-close, give up after 200msec
3152                        }
3153                    }
3154                } catch (InterruptedException e) {
3155                    Log.wtf(TAG, e);
3156                }
3157            }
3158
3159            // Next measure CPU usage.
3160            if (processStats != null) {
3161                processStats.init();
3162                System.gc();
3163                processStats.update();
3164                try {
3165                    synchronized (processStats) {
3166                        processStats.wait(500); // measure over 1/2 second.
3167                    }
3168                } catch (InterruptedException e) {
3169                }
3170                processStats.update();
3171
3172                // We'll take the stack crawls of just the top apps using CPU.
3173                final int N = processStats.countWorkingStats();
3174                int numProcs = 0;
3175                for (int i=0; i<N && numProcs<5; i++) {
3176                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3177                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3178                        numProcs++;
3179                        try {
3180                            synchronized (observer) {
3181                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3182                                observer.wait(200);  // Wait for write-close, give up after 200msec
3183                            }
3184                        } catch (InterruptedException e) {
3185                            Log.wtf(TAG, e);
3186                        }
3187
3188                    }
3189                }
3190            }
3191
3192        } finally {
3193            observer.stopWatching();
3194        }
3195
3196        if (nativeProcs != null) {
3197            int[] pids = Process.getPidsForCommands(nativeProcs);
3198            if (pids != null) {
3199                for (int pid : pids) {
3200                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3201                }
3202            }
3203        }
3204    }
3205
3206    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3207        if (true || IS_USER_BUILD) {
3208            return;
3209        }
3210        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3211        if (tracesPath == null || tracesPath.length() == 0) {
3212            return;
3213        }
3214
3215        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3216        StrictMode.allowThreadDiskWrites();
3217        try {
3218            final File tracesFile = new File(tracesPath);
3219            final File tracesDir = tracesFile.getParentFile();
3220            final File tracesTmp = new File(tracesDir, "__tmp__");
3221            try {
3222                if (!tracesDir.exists()) {
3223                    tracesFile.mkdirs();
3224                    if (!SELinux.restorecon(tracesDir.getPath())) {
3225                        return;
3226                    }
3227                }
3228                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3229
3230                if (tracesFile.exists()) {
3231                    tracesTmp.delete();
3232                    tracesFile.renameTo(tracesTmp);
3233                }
3234                StringBuilder sb = new StringBuilder();
3235                Time tobj = new Time();
3236                tobj.set(System.currentTimeMillis());
3237                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3238                sb.append(": ");
3239                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3240                sb.append(" since ");
3241                sb.append(msg);
3242                FileOutputStream fos = new FileOutputStream(tracesFile);
3243                fos.write(sb.toString().getBytes());
3244                if (app == null) {
3245                    fos.write("\n*** No application process!".getBytes());
3246                }
3247                fos.close();
3248                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3249            } catch (IOException e) {
3250                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3251                return;
3252            }
3253
3254            if (app != null) {
3255                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3256                firstPids.add(app.pid);
3257                dumpStackTraces(tracesPath, firstPids, null, null, null);
3258            }
3259
3260            File lastTracesFile = null;
3261            File curTracesFile = null;
3262            for (int i=9; i>=0; i--) {
3263                String name = String.format("slow%02d.txt", i);
3264                curTracesFile = new File(tracesDir, name);
3265                if (curTracesFile.exists()) {
3266                    if (lastTracesFile != null) {
3267                        curTracesFile.renameTo(lastTracesFile);
3268                    } else {
3269                        curTracesFile.delete();
3270                    }
3271                }
3272                lastTracesFile = curTracesFile;
3273            }
3274            tracesFile.renameTo(curTracesFile);
3275            if (tracesTmp.exists()) {
3276                tracesTmp.renameTo(tracesFile);
3277            }
3278        } finally {
3279            StrictMode.setThreadPolicy(oldPolicy);
3280        }
3281    }
3282
3283    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3284            ActivityRecord parent, final String annotation) {
3285        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3286        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3287
3288        if (mController != null) {
3289            try {
3290                // 0 == continue, -1 = kill process immediately
3291                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3292                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3293            } catch (RemoteException e) {
3294                mController = null;
3295            }
3296        }
3297
3298        long anrTime = SystemClock.uptimeMillis();
3299        if (MONITOR_CPU_USAGE) {
3300            updateCpuStatsNow();
3301        }
3302
3303        synchronized (this) {
3304            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3305            if (mShuttingDown) {
3306                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3307                return;
3308            } else if (app.notResponding) {
3309                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3310                return;
3311            } else if (app.crashing) {
3312                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3313                return;
3314            }
3315
3316            // In case we come through here for the same app before completing
3317            // this one, mark as anring now so we will bail out.
3318            app.notResponding = true;
3319
3320            // Log the ANR to the event log.
3321            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3322                    app.processName, app.info.flags, annotation);
3323
3324            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3325            firstPids.add(app.pid);
3326
3327            int parentPid = app.pid;
3328            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3329            if (parentPid != app.pid) firstPids.add(parentPid);
3330
3331            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3332
3333            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3334                ProcessRecord r = mLruProcesses.get(i);
3335                if (r != null && r.thread != null) {
3336                    int pid = r.pid;
3337                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3338                        if (r.persistent) {
3339                            firstPids.add(pid);
3340                        } else {
3341                            lastPids.put(pid, Boolean.TRUE);
3342                        }
3343                    }
3344                }
3345            }
3346        }
3347
3348        // Log the ANR to the main log.
3349        StringBuilder info = new StringBuilder();
3350        info.setLength(0);
3351        info.append("ANR in ").append(app.processName);
3352        if (activity != null && activity.shortComponentName != null) {
3353            info.append(" (").append(activity.shortComponentName).append(")");
3354        }
3355        info.append("\n");
3356        if (annotation != null) {
3357            info.append("Reason: ").append(annotation).append("\n");
3358        }
3359        if (parent != null && parent != activity) {
3360            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3361        }
3362
3363        final ProcessStats processStats = new ProcessStats(true);
3364
3365        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3366
3367        String cpuInfo = null;
3368        if (MONITOR_CPU_USAGE) {
3369            updateCpuStatsNow();
3370            synchronized (mProcessStatsThread) {
3371                cpuInfo = mProcessStats.printCurrentState(anrTime);
3372            }
3373            info.append(processStats.printCurrentLoad());
3374            info.append(cpuInfo);
3375        }
3376
3377        info.append(processStats.printCurrentState(anrTime));
3378
3379        Slog.e(TAG, info.toString());
3380        if (tracesFile == null) {
3381            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3382            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3383        }
3384
3385        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3386                cpuInfo, tracesFile, null);
3387
3388        if (mController != null) {
3389            try {
3390                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3391                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3392                if (res != 0) {
3393                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3394                    return;
3395                }
3396            } catch (RemoteException e) {
3397                mController = null;
3398            }
3399        }
3400
3401        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3402        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3403                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3404
3405        synchronized (this) {
3406            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3407                Slog.w(TAG, "Killing " + app + ": background ANR");
3408                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3409                        app.processName, app.setAdj, "background ANR");
3410                Process.killProcessQuiet(app.pid);
3411                return;
3412            }
3413
3414            // Set the app's notResponding state, and look up the errorReportReceiver
3415            makeAppNotRespondingLocked(app,
3416                    activity != null ? activity.shortComponentName : null,
3417                    annotation != null ? "ANR " + annotation : "ANR",
3418                    info.toString());
3419
3420            // Bring up the infamous App Not Responding dialog
3421            Message msg = Message.obtain();
3422            HashMap map = new HashMap();
3423            msg.what = SHOW_NOT_RESPONDING_MSG;
3424            msg.obj = map;
3425            map.put("app", app);
3426            if (activity != null) {
3427                map.put("activity", activity);
3428            }
3429
3430            mHandler.sendMessage(msg);
3431        }
3432    }
3433
3434    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3435        if (!mLaunchWarningShown) {
3436            mLaunchWarningShown = true;
3437            mHandler.post(new Runnable() {
3438                @Override
3439                public void run() {
3440                    synchronized (ActivityManagerService.this) {
3441                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3442                        d.show();
3443                        mHandler.postDelayed(new Runnable() {
3444                            @Override
3445                            public void run() {
3446                                synchronized (ActivityManagerService.this) {
3447                                    d.dismiss();
3448                                    mLaunchWarningShown = false;
3449                                }
3450                            }
3451                        }, 4000);
3452                    }
3453                }
3454            });
3455        }
3456    }
3457
3458    public boolean clearApplicationUserData(final String packageName,
3459            final IPackageDataObserver observer, int userId) {
3460        enforceNotIsolatedCaller("clearApplicationUserData");
3461        int uid = Binder.getCallingUid();
3462        int pid = Binder.getCallingPid();
3463        userId = handleIncomingUser(pid, uid,
3464                userId, false, true, "clearApplicationUserData", null);
3465        long callingId = Binder.clearCallingIdentity();
3466        try {
3467            IPackageManager pm = AppGlobals.getPackageManager();
3468            int pkgUid = -1;
3469            synchronized(this) {
3470                try {
3471                    pkgUid = pm.getPackageUid(packageName, userId);
3472                } catch (RemoteException e) {
3473                }
3474                if (pkgUid == -1) {
3475                    Slog.w(TAG, "Invalid packageName:" + packageName);
3476                    return false;
3477                }
3478                if (uid == pkgUid || checkComponentPermission(
3479                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3480                        pid, uid, -1, true)
3481                        == PackageManager.PERMISSION_GRANTED) {
3482                    forceStopPackageLocked(packageName, pkgUid);
3483                } else {
3484                    throw new SecurityException(pid+" does not have permission:"+
3485                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3486                                    "for process:"+packageName);
3487                }
3488            }
3489
3490            try {
3491                //clear application user data
3492                pm.clearApplicationUserData(packageName, observer, userId);
3493                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3494                        Uri.fromParts("package", packageName, null));
3495                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3496                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3497                        null, null, 0, null, null, null, false, false, userId);
3498            } catch (RemoteException e) {
3499            }
3500        } finally {
3501            Binder.restoreCallingIdentity(callingId);
3502        }
3503        return true;
3504    }
3505
3506    public void killBackgroundProcesses(final String packageName, int userId) {
3507        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3508                != PackageManager.PERMISSION_GRANTED &&
3509                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3510                        != PackageManager.PERMISSION_GRANTED) {
3511            String msg = "Permission Denial: killBackgroundProcesses() 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        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3520                userId, true, true, "killBackgroundProcesses", null);
3521        long callingId = Binder.clearCallingIdentity();
3522        try {
3523            IPackageManager pm = AppGlobals.getPackageManager();
3524            synchronized(this) {
3525                int appId = -1;
3526                try {
3527                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3528                } catch (RemoteException e) {
3529                }
3530                if (appId == -1) {
3531                    Slog.w(TAG, "Invalid packageName: " + packageName);
3532                    return;
3533                }
3534                killPackageProcessesLocked(packageName, appId, userId,
3535                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3536            }
3537        } finally {
3538            Binder.restoreCallingIdentity(callingId);
3539        }
3540    }
3541
3542    public void killAllBackgroundProcesses() {
3543        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3544                != PackageManager.PERMISSION_GRANTED) {
3545            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3546                    + Binder.getCallingPid()
3547                    + ", uid=" + Binder.getCallingUid()
3548                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3549            Slog.w(TAG, msg);
3550            throw new SecurityException(msg);
3551        }
3552
3553        long callingId = Binder.clearCallingIdentity();
3554        try {
3555            synchronized(this) {
3556                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3557                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3558                    final int NA = apps.size();
3559                    for (int ia=0; ia<NA; ia++) {
3560                        ProcessRecord app = apps.valueAt(ia);
3561                        if (app.persistent) {
3562                            // we don't kill persistent processes
3563                            continue;
3564                        }
3565                        if (app.removed) {
3566                            procs.add(app);
3567                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3568                            app.removed = true;
3569                            procs.add(app);
3570                        }
3571                    }
3572                }
3573
3574                int N = procs.size();
3575                for (int i=0; i<N; i++) {
3576                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3577                }
3578            }
3579        } finally {
3580            Binder.restoreCallingIdentity(callingId);
3581        }
3582    }
3583
3584    public void forceStopPackage(final String packageName, int userId) {
3585        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3586                != PackageManager.PERMISSION_GRANTED) {
3587            String msg = "Permission Denial: forceStopPackage() from pid="
3588                    + Binder.getCallingPid()
3589                    + ", uid=" + Binder.getCallingUid()
3590                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3591            Slog.w(TAG, msg);
3592            throw new SecurityException(msg);
3593        }
3594        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3595                userId, true, true, "forceStopPackage", null);
3596        long callingId = Binder.clearCallingIdentity();
3597        try {
3598            IPackageManager pm = AppGlobals.getPackageManager();
3599            synchronized(this) {
3600                int[] users = userId == UserHandle.USER_ALL
3601                        ? getUsersLocked() : new int[] { userId };
3602                for (int user : users) {
3603                    int pkgUid = -1;
3604                    try {
3605                        pkgUid = pm.getPackageUid(packageName, user);
3606                    } catch (RemoteException e) {
3607                    }
3608                    if (pkgUid == -1) {
3609                        Slog.w(TAG, "Invalid packageName: " + packageName);
3610                        continue;
3611                    }
3612                    try {
3613                        pm.setPackageStoppedState(packageName, true, user);
3614                    } catch (RemoteException e) {
3615                    } catch (IllegalArgumentException e) {
3616                        Slog.w(TAG, "Failed trying to unstop package "
3617                                + packageName + ": " + e);
3618                    }
3619                    if (isUserRunningLocked(user)) {
3620                        forceStopPackageLocked(packageName, pkgUid);
3621                    }
3622                }
3623            }
3624        } finally {
3625            Binder.restoreCallingIdentity(callingId);
3626        }
3627    }
3628
3629    /*
3630     * The pkg name and app id have to be specified.
3631     */
3632    public void killApplicationWithAppId(String pkg, int appid) {
3633        if (pkg == null) {
3634            return;
3635        }
3636        // Make sure the uid is valid.
3637        if (appid < 0) {
3638            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3639            return;
3640        }
3641        int callerUid = Binder.getCallingUid();
3642        // Only the system server can kill an application
3643        if (callerUid == Process.SYSTEM_UID) {
3644            // Post an aysnc message to kill the application
3645            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3646            msg.arg1 = appid;
3647            msg.arg2 = 0;
3648            msg.obj = pkg;
3649            mHandler.sendMessage(msg);
3650        } else {
3651            throw new SecurityException(callerUid + " cannot kill pkg: " +
3652                    pkg);
3653        }
3654    }
3655
3656    public void closeSystemDialogs(String reason) {
3657        enforceNotIsolatedCaller("closeSystemDialogs");
3658
3659        final int pid = Binder.getCallingPid();
3660        final int uid = Binder.getCallingUid();
3661        final long origId = Binder.clearCallingIdentity();
3662        try {
3663            synchronized (this) {
3664                // Only allow this from foreground processes, so that background
3665                // applications can't abuse it to prevent system UI from being shown.
3666                if (uid >= Process.FIRST_APPLICATION_UID) {
3667                    ProcessRecord proc;
3668                    synchronized (mPidsSelfLocked) {
3669                        proc = mPidsSelfLocked.get(pid);
3670                    }
3671                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3672                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3673                                + " from background process " + proc);
3674                        return;
3675                    }
3676                }
3677                closeSystemDialogsLocked(reason);
3678            }
3679        } finally {
3680            Binder.restoreCallingIdentity(origId);
3681        }
3682    }
3683
3684    void closeSystemDialogsLocked(String reason) {
3685        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3686        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3687        if (reason != null) {
3688            intent.putExtra("reason", reason);
3689        }
3690        mWindowManager.closeSystemDialogs(reason);
3691
3692        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3693            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3694            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3695                r.stack.finishActivityLocked(r, i,
3696                        Activity.RESULT_CANCELED, null, "close-sys", true);
3697            }
3698        }
3699
3700        broadcastIntentLocked(null, null, intent, null,
3701                null, 0, null, null, null, false, false, -1,
3702                Process.SYSTEM_UID, UserHandle.USER_ALL);
3703    }
3704
3705    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3706            throws RemoteException {
3707        enforceNotIsolatedCaller("getProcessMemoryInfo");
3708        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3709        for (int i=pids.length-1; i>=0; i--) {
3710            infos[i] = new Debug.MemoryInfo();
3711            Debug.getMemoryInfo(pids[i], infos[i]);
3712        }
3713        return infos;
3714    }
3715
3716    public long[] getProcessPss(int[] pids) throws RemoteException {
3717        enforceNotIsolatedCaller("getProcessPss");
3718        long[] pss = new long[pids.length];
3719        for (int i=pids.length-1; i>=0; i--) {
3720            pss[i] = Debug.getPss(pids[i]);
3721        }
3722        return pss;
3723    }
3724
3725    public void killApplicationProcess(String processName, int uid) {
3726        if (processName == null) {
3727            return;
3728        }
3729
3730        int callerUid = Binder.getCallingUid();
3731        // Only the system server can kill an application
3732        if (callerUid == Process.SYSTEM_UID) {
3733            synchronized (this) {
3734                ProcessRecord app = getProcessRecordLocked(processName, uid);
3735                if (app != null && app.thread != null) {
3736                    try {
3737                        app.thread.scheduleSuicide();
3738                    } catch (RemoteException e) {
3739                        // If the other end already died, then our work here is done.
3740                    }
3741                } else {
3742                    Slog.w(TAG, "Process/uid not found attempting kill of "
3743                            + processName + " / " + uid);
3744                }
3745            }
3746        } else {
3747            throw new SecurityException(callerUid + " cannot kill app process: " +
3748                    processName);
3749        }
3750    }
3751
3752    private void forceStopPackageLocked(final String packageName, int uid) {
3753        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3754                false, true, false, UserHandle.getUserId(uid));
3755        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3756                Uri.fromParts("package", packageName, null));
3757        if (!mProcessesReady) {
3758            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3759        }
3760        intent.putExtra(Intent.EXTRA_UID, uid);
3761        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3762        broadcastIntentLocked(null, null, intent,
3763                null, null, 0, null, null, null,
3764                false, false,
3765                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3766    }
3767
3768    private void forceStopUserLocked(int userId) {
3769        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3770        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3771        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3772        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3773        broadcastIntentLocked(null, null, intent,
3774                null, null, 0, null, null, null,
3775                false, false,
3776                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3777    }
3778
3779    private final boolean killPackageProcessesLocked(String packageName, int appId,
3780            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3781            boolean doit, boolean evenPersistent, String reason) {
3782        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3783
3784        // Remove all processes this package may have touched: all with the
3785        // same UID (except for the system or root user), and all whose name
3786        // matches the package name.
3787        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3788        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3789            final int NA = apps.size();
3790            for (int ia=0; ia<NA; ia++) {
3791                ProcessRecord app = apps.valueAt(ia);
3792                if (app.persistent && !evenPersistent) {
3793                    // we don't kill persistent processes
3794                    continue;
3795                }
3796                if (app.removed) {
3797                    if (doit) {
3798                        procs.add(app);
3799                    }
3800                    continue;
3801                }
3802
3803                // Skip process if it doesn't meet our oom adj requirement.
3804                if (app.setAdj < minOomAdj) {
3805                    continue;
3806                }
3807
3808                // If no package is specified, we call all processes under the
3809                // give user id.
3810                if (packageName == null) {
3811                    if (app.userId != userId) {
3812                        continue;
3813                    }
3814                // Package has been specified, we want to hit all processes
3815                // that match it.  We need to qualify this by the processes
3816                // that are running under the specified app and user ID.
3817                } else {
3818                    if (UserHandle.getAppId(app.uid) != appId) {
3819                        continue;
3820                    }
3821                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3822                        continue;
3823                    }
3824                    if (!app.pkgList.contains(packageName)) {
3825                        continue;
3826                    }
3827                }
3828
3829                // Process has passed all conditions, kill it!
3830                if (!doit) {
3831                    return true;
3832                }
3833                app.removed = true;
3834                procs.add(app);
3835            }
3836        }
3837
3838        int N = procs.size();
3839        for (int i=0; i<N; i++) {
3840            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3841        }
3842        return N > 0;
3843    }
3844
3845    private final boolean forceStopPackageLocked(String name, int appId,
3846            boolean callerWillRestart, boolean purgeCache, boolean doit,
3847            boolean evenPersistent, int userId) {
3848        int i;
3849        int N;
3850
3851        if (userId == UserHandle.USER_ALL && name == null) {
3852            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3853        }
3854
3855        if (appId < 0 && name != null) {
3856            try {
3857                appId = UserHandle.getAppId(
3858                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3859            } catch (RemoteException e) {
3860            }
3861        }
3862
3863        if (doit) {
3864            if (name != null) {
3865                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3866                        + " user=" + userId);
3867            } else {
3868                Slog.i(TAG, "Force stopping user " + userId);
3869            }
3870
3871            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3872            while (badApps.hasNext()) {
3873                SparseArray<Long> ba = badApps.next();
3874                for (i=ba.size()-1; i>=0; i--) {
3875                    boolean remove = false;
3876                    final int entUid = ba.keyAt(i);
3877                    if (name != null) {
3878                        if (userId == UserHandle.USER_ALL) {
3879                            if (UserHandle.getAppId(entUid) == appId) {
3880                                remove = true;
3881                            }
3882                        } else {
3883                            if (entUid == UserHandle.getUid(userId, appId)) {
3884                                remove = true;
3885                            }
3886                        }
3887                    } else if (UserHandle.getUserId(entUid) == userId) {
3888                        remove = true;
3889                    }
3890                    if (remove) {
3891                        ba.removeAt(i);
3892                    }
3893                }
3894                if (ba.size() == 0) {
3895                    badApps.remove();
3896                }
3897            }
3898        }
3899
3900        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3901                -100, callerWillRestart, false, doit, evenPersistent,
3902                name == null ? ("force stop user " + userId) : ("force stop " + name));
3903
3904        TaskRecord lastTask = null;
3905        for (i=0; i<mMainStack.mHistory.size(); i++) {
3906            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3907            final boolean samePackage = r.packageName.equals(name)
3908                    || (name == null && r.userId == userId);
3909            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3910                    && (samePackage || r.task == lastTask)
3911                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3912                if (!doit) {
3913                    if (r.finishing) {
3914                        // If this activity is just finishing, then it is not
3915                        // interesting as far as something to stop.
3916                        continue;
3917                    }
3918                    return true;
3919                }
3920                didSomething = true;
3921                Slog.i(TAG, "  Force finishing activity " + r);
3922                if (samePackage) {
3923                    if (r.app != null) {
3924                        r.app.removed = true;
3925                    }
3926                    r.app = null;
3927                }
3928                lastTask = r.task;
3929                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3930                        null, "force-stop", true)) {
3931                    i--;
3932                }
3933            }
3934        }
3935
3936        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3937            if (!doit) {
3938                return true;
3939            }
3940            didSomething = true;
3941        }
3942
3943        if (name == null) {
3944            // Remove all sticky broadcasts from this user.
3945            mStickyBroadcasts.remove(userId);
3946        }
3947
3948        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3949        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3950                userId, providers)) {
3951            if (!doit) {
3952                return true;
3953            }
3954            didSomething = true;
3955        }
3956        N = providers.size();
3957        for (i=0; i<N; i++) {
3958            removeDyingProviderLocked(null, providers.get(i), true);
3959        }
3960
3961        if (mIntentSenderRecords.size() > 0) {
3962            Iterator<WeakReference<PendingIntentRecord>> it
3963                    = mIntentSenderRecords.values().iterator();
3964            while (it.hasNext()) {
3965                WeakReference<PendingIntentRecord> wpir = it.next();
3966                if (wpir == null) {
3967                    it.remove();
3968                    continue;
3969                }
3970                PendingIntentRecord pir = wpir.get();
3971                if (pir == null) {
3972                    it.remove();
3973                    continue;
3974                }
3975                if (name == null) {
3976                    // Stopping user, remove all objects for the user.
3977                    if (pir.key.userId != userId) {
3978                        // Not the same user, skip it.
3979                        continue;
3980                    }
3981                } else {
3982                    if (UserHandle.getAppId(pir.uid) != appId) {
3983                        // Different app id, skip it.
3984                        continue;
3985                    }
3986                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3987                        // Different user, skip it.
3988                        continue;
3989                    }
3990                    if (!pir.key.packageName.equals(name)) {
3991                        // Different package, skip it.
3992                        continue;
3993                    }
3994                }
3995                if (!doit) {
3996                    return true;
3997                }
3998                didSomething = true;
3999                it.remove();
4000                pir.canceled = true;
4001                if (pir.key.activity != null) {
4002                    pir.key.activity.pendingResults.remove(pir.ref);
4003                }
4004            }
4005        }
4006
4007        if (doit) {
4008            if (purgeCache && name != null) {
4009                AttributeCache ac = AttributeCache.instance();
4010                if (ac != null) {
4011                    ac.removePackage(name);
4012                }
4013            }
4014            if (mBooted) {
4015                mMainStack.resumeTopActivityLocked(null);
4016                mMainStack.scheduleIdleLocked();
4017            }
4018        }
4019
4020        return didSomething;
4021    }
4022
4023    private final boolean removeProcessLocked(ProcessRecord app,
4024            boolean callerWillRestart, boolean allowRestart, String reason) {
4025        final String name = app.processName;
4026        final int uid = app.uid;
4027        if (DEBUG_PROCESSES) Slog.d(
4028            TAG, "Force removing proc " + app.toShortString() + " (" + name
4029            + "/" + uid + ")");
4030
4031        mProcessNames.remove(name, uid);
4032        mIsolatedProcesses.remove(app.uid);
4033        if (mHeavyWeightProcess == app) {
4034            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4035                    mHeavyWeightProcess.userId, 0));
4036            mHeavyWeightProcess = null;
4037        }
4038        boolean needRestart = false;
4039        if (app.pid > 0 && app.pid != MY_PID) {
4040            int pid = app.pid;
4041            synchronized (mPidsSelfLocked) {
4042                mPidsSelfLocked.remove(pid);
4043                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4044            }
4045            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4046            handleAppDiedLocked(app, true, allowRestart);
4047            mLruProcesses.remove(app);
4048            Process.killProcessQuiet(pid);
4049
4050            if (app.persistent && !app.isolated) {
4051                if (!callerWillRestart) {
4052                    addAppLocked(app.info, false);
4053                } else {
4054                    needRestart = true;
4055                }
4056            }
4057        } else {
4058            mRemovedProcesses.add(app);
4059        }
4060
4061        return needRestart;
4062    }
4063
4064    private final void processStartTimedOutLocked(ProcessRecord app) {
4065        final int pid = app.pid;
4066        boolean gone = false;
4067        synchronized (mPidsSelfLocked) {
4068            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4069            if (knownApp != null && knownApp.thread == null) {
4070                mPidsSelfLocked.remove(pid);
4071                gone = true;
4072            }
4073        }
4074
4075        if (gone) {
4076            Slog.w(TAG, "Process " + app + " failed to attach");
4077            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4078                    pid, app.uid, app.processName);
4079            mProcessNames.remove(app.processName, app.uid);
4080            mIsolatedProcesses.remove(app.uid);
4081            if (mHeavyWeightProcess == app) {
4082                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4083                        mHeavyWeightProcess.userId, 0));
4084                mHeavyWeightProcess = null;
4085            }
4086            // Take care of any launching providers waiting for this process.
4087            checkAppInLaunchingProvidersLocked(app, true);
4088            // Take care of any services that are waiting for the process.
4089            mServices.processStartTimedOutLocked(app);
4090            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4091                    app.processName, app.setAdj, "start timeout");
4092            Process.killProcessQuiet(pid);
4093            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4094                Slog.w(TAG, "Unattached app died before backup, skipping");
4095                try {
4096                    IBackupManager bm = IBackupManager.Stub.asInterface(
4097                            ServiceManager.getService(Context.BACKUP_SERVICE));
4098                    bm.agentDisconnected(app.info.packageName);
4099                } catch (RemoteException e) {
4100                    // Can't happen; the backup manager is local
4101                }
4102            }
4103            if (isPendingBroadcastProcessLocked(pid)) {
4104                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4105                skipPendingBroadcastLocked(pid);
4106            }
4107        } else {
4108            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4109        }
4110    }
4111
4112    private final boolean attachApplicationLocked(IApplicationThread thread,
4113            int pid) {
4114
4115        // Find the application record that is being attached...  either via
4116        // the pid if we are running in multiple processes, or just pull the
4117        // next app record if we are emulating process with anonymous threads.
4118        ProcessRecord app;
4119        if (pid != MY_PID && pid >= 0) {
4120            synchronized (mPidsSelfLocked) {
4121                app = mPidsSelfLocked.get(pid);
4122            }
4123        } else {
4124            app = null;
4125        }
4126
4127        if (app == null) {
4128            Slog.w(TAG, "No pending application record for pid " + pid
4129                    + " (IApplicationThread " + thread + "); dropping process");
4130            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4131            if (pid > 0 && pid != MY_PID) {
4132                Process.killProcessQuiet(pid);
4133            } else {
4134                try {
4135                    thread.scheduleExit();
4136                } catch (Exception e) {
4137                    // Ignore exceptions.
4138                }
4139            }
4140            return false;
4141        }
4142
4143        // If this application record is still attached to a previous
4144        // process, clean it up now.
4145        if (app.thread != null) {
4146            handleAppDiedLocked(app, true, true);
4147        }
4148
4149        // Tell the process all about itself.
4150
4151        if (localLOGV) Slog.v(
4152                TAG, "Binding process pid " + pid + " to record " + app);
4153
4154        String processName = app.processName;
4155        try {
4156            AppDeathRecipient adr = new AppDeathRecipient(
4157                    app, pid, thread);
4158            thread.asBinder().linkToDeath(adr, 0);
4159            app.deathRecipient = adr;
4160        } catch (RemoteException e) {
4161            app.resetPackageList();
4162            startProcessLocked(app, "link fail", processName);
4163            return false;
4164        }
4165
4166        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4167
4168        app.thread = thread;
4169        app.curAdj = app.setAdj = -100;
4170        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4171        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4172        app.forcingToForeground = null;
4173        app.foregroundServices = false;
4174        app.hasShownUi = false;
4175        app.debugging = false;
4176
4177        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4178
4179        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4180        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4181
4182        if (!normalMode) {
4183            Slog.i(TAG, "Launching preboot mode app: " + app);
4184        }
4185
4186        if (localLOGV) Slog.v(
4187            TAG, "New app record " + app
4188            + " thread=" + thread.asBinder() + " pid=" + pid);
4189        try {
4190            int testMode = IApplicationThread.DEBUG_OFF;
4191            if (mDebugApp != null && mDebugApp.equals(processName)) {
4192                testMode = mWaitForDebugger
4193                    ? IApplicationThread.DEBUG_WAIT
4194                    : IApplicationThread.DEBUG_ON;
4195                app.debugging = true;
4196                if (mDebugTransient) {
4197                    mDebugApp = mOrigDebugApp;
4198                    mWaitForDebugger = mOrigWaitForDebugger;
4199                }
4200            }
4201            String profileFile = app.instrumentationProfileFile;
4202            ParcelFileDescriptor profileFd = null;
4203            boolean profileAutoStop = false;
4204            if (mProfileApp != null && mProfileApp.equals(processName)) {
4205                mProfileProc = app;
4206                profileFile = mProfileFile;
4207                profileFd = mProfileFd;
4208                profileAutoStop = mAutoStopProfiler;
4209            }
4210            boolean enableOpenGlTrace = false;
4211            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4212                enableOpenGlTrace = true;
4213                mOpenGlTraceApp = null;
4214            }
4215
4216            // If the app is being launched for restore or full backup, set it up specially
4217            boolean isRestrictedBackupMode = false;
4218            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4219                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4220                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4221                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4222            }
4223
4224            ensurePackageDexOpt(app.instrumentationInfo != null
4225                    ? app.instrumentationInfo.packageName
4226                    : app.info.packageName);
4227            if (app.instrumentationClass != null) {
4228                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4229            }
4230            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4231                    + processName + " with config " + mConfiguration);
4232            ApplicationInfo appInfo = app.instrumentationInfo != null
4233                    ? app.instrumentationInfo : app.info;
4234            app.compat = compatibilityInfoForPackageLocked(appInfo);
4235            if (profileFd != null) {
4236                profileFd = profileFd.dup();
4237            }
4238            thread.bindApplication(processName, appInfo, providers,
4239                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4240                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4241                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4242                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4243                    mCoreSettingsObserver.getCoreSettingsLocked());
4244            updateLruProcessLocked(app, false);
4245            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4246        } catch (Exception e) {
4247            // todo: Yikes!  What should we do?  For now we will try to
4248            // start another process, but that could easily get us in
4249            // an infinite loop of restarting processes...
4250            Slog.w(TAG, "Exception thrown during bind!", e);
4251
4252            app.resetPackageList();
4253            app.unlinkDeathRecipient();
4254            startProcessLocked(app, "bind fail", processName);
4255            return false;
4256        }
4257
4258        // Remove this record from the list of starting applications.
4259        mPersistentStartingProcesses.remove(app);
4260        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4261                "Attach application locked removing on hold: " + app);
4262        mProcessesOnHold.remove(app);
4263
4264        boolean badApp = false;
4265        boolean didSomething = false;
4266
4267        // See if the top visible activity is waiting to run in this process...
4268        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4269        if (hr != null && normalMode) {
4270            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4271                    && processName.equals(hr.processName)) {
4272                try {
4273                    if (mHeadless) {
4274                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4275                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4276                        didSomething = true;
4277                    }
4278                } catch (Exception e) {
4279                    Slog.w(TAG, "Exception in new application when starting activity "
4280                          + hr.intent.getComponent().flattenToShortString(), e);
4281                    badApp = true;
4282                }
4283            } else {
4284                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4285            }
4286        }
4287
4288        // Find any services that should be running in this process...
4289        if (!badApp) {
4290            try {
4291                didSomething |= mServices.attachApplicationLocked(app, processName);
4292            } catch (Exception e) {
4293                badApp = true;
4294            }
4295        }
4296
4297        // Check if a next-broadcast receiver is in this process...
4298        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4299            try {
4300                didSomething = sendPendingBroadcastsLocked(app);
4301            } catch (Exception e) {
4302                // If the app died trying to launch the receiver we declare it 'bad'
4303                badApp = true;
4304            }
4305        }
4306
4307        // Check whether the next backup agent is in this process...
4308        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4309            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4310            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4311            try {
4312                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4313                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4314                        mBackupTarget.backupMode);
4315            } catch (Exception e) {
4316                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4317                e.printStackTrace();
4318            }
4319        }
4320
4321        if (badApp) {
4322            // todo: Also need to kill application to deal with all
4323            // kinds of exceptions.
4324            handleAppDiedLocked(app, false, true);
4325            return false;
4326        }
4327
4328        if (!didSomething) {
4329            updateOomAdjLocked();
4330        }
4331
4332        return true;
4333    }
4334
4335    public final void attachApplication(IApplicationThread thread) {
4336        synchronized (this) {
4337            int callingPid = Binder.getCallingPid();
4338            final long origId = Binder.clearCallingIdentity();
4339            attachApplicationLocked(thread, callingPid);
4340            Binder.restoreCallingIdentity(origId);
4341        }
4342    }
4343
4344    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4345        final long origId = Binder.clearCallingIdentity();
4346        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4347        if (stopProfiling) {
4348            synchronized (this) {
4349                if (mProfileProc == r.app) {
4350                    if (mProfileFd != null) {
4351                        try {
4352                            mProfileFd.close();
4353                        } catch (IOException e) {
4354                        }
4355                        clearProfilerLocked();
4356                    }
4357                }
4358            }
4359        }
4360        Binder.restoreCallingIdentity(origId);
4361    }
4362
4363    void enableScreenAfterBoot() {
4364        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4365                SystemClock.uptimeMillis());
4366        mWindowManager.enableScreenAfterBoot();
4367
4368        synchronized (this) {
4369            updateEventDispatchingLocked();
4370        }
4371    }
4372
4373    public void showBootMessage(final CharSequence msg, final boolean always) {
4374        enforceNotIsolatedCaller("showBootMessage");
4375        mWindowManager.showBootMessage(msg, always);
4376    }
4377
4378    public void dismissKeyguardOnNextActivity() {
4379        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4380        final long token = Binder.clearCallingIdentity();
4381        try {
4382            synchronized (this) {
4383                if (mLockScreenShown) {
4384                    mLockScreenShown = false;
4385                    comeOutOfSleepIfNeededLocked();
4386                }
4387                mMainStack.dismissKeyguardOnNextActivityLocked();
4388            }
4389        } finally {
4390            Binder.restoreCallingIdentity(token);
4391        }
4392    }
4393
4394    final void finishBooting() {
4395        IntentFilter pkgFilter = new IntentFilter();
4396        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4397        pkgFilter.addDataScheme("package");
4398        mContext.registerReceiver(new BroadcastReceiver() {
4399            @Override
4400            public void onReceive(Context context, Intent intent) {
4401                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4402                if (pkgs != null) {
4403                    for (String pkg : pkgs) {
4404                        synchronized (ActivityManagerService.this) {
4405                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4406                                setResultCode(Activity.RESULT_OK);
4407                                return;
4408                            }
4409                        }
4410                    }
4411                }
4412            }
4413        }, pkgFilter);
4414
4415        synchronized (this) {
4416            // Ensure that any processes we had put on hold are now started
4417            // up.
4418            final int NP = mProcessesOnHold.size();
4419            if (NP > 0) {
4420                ArrayList<ProcessRecord> procs =
4421                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4422                for (int ip=0; ip<NP; ip++) {
4423                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4424                            + procs.get(ip));
4425                    startProcessLocked(procs.get(ip), "on-hold", null);
4426                }
4427            }
4428
4429            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4430                // Start looking for apps that are abusing wake locks.
4431                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4432                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4433                // Tell anyone interested that we are done booting!
4434                SystemProperties.set("sys.boot_completed", "1");
4435                SystemProperties.set("dev.bootcomplete", "1");
4436                for (int i=0; i<mStartedUsers.size(); i++) {
4437                    UserStartedState uss = mStartedUsers.valueAt(i);
4438                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4439                        uss.mState = UserStartedState.STATE_RUNNING;
4440                        final int userId = mStartedUsers.keyAt(i);
4441                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4442                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4443                        broadcastIntentLocked(null, null, intent,
4444                                null, null, 0, null, null,
4445                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4446                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4447                    }
4448                }
4449            }
4450        }
4451    }
4452
4453    final void ensureBootCompleted() {
4454        boolean booting;
4455        boolean enableScreen;
4456        synchronized (this) {
4457            booting = mBooting;
4458            mBooting = false;
4459            enableScreen = !mBooted;
4460            mBooted = true;
4461        }
4462
4463        if (booting) {
4464            finishBooting();
4465        }
4466
4467        if (enableScreen) {
4468            enableScreenAfterBoot();
4469        }
4470    }
4471
4472    public final void activityResumed(IBinder token) {
4473        final long origId = Binder.clearCallingIdentity();
4474        mMainStack.activityResumed(token);
4475        Binder.restoreCallingIdentity(origId);
4476    }
4477
4478    public final void activityPaused(IBinder token) {
4479        final long origId = Binder.clearCallingIdentity();
4480        mMainStack.activityPaused(token, false);
4481        Binder.restoreCallingIdentity(origId);
4482    }
4483
4484    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4485            CharSequence description) {
4486        if (localLOGV) Slog.v(
4487            TAG, "Activity stopped: token=" + token);
4488
4489        // Refuse possible leaked file descriptors
4490        if (icicle != null && icicle.hasFileDescriptors()) {
4491            throw new IllegalArgumentException("File descriptors passed in Bundle");
4492        }
4493
4494        ActivityRecord r = null;
4495
4496        final long origId = Binder.clearCallingIdentity();
4497
4498        synchronized (this) {
4499            r = mMainStack.isInStackLocked(token);
4500            if (r != null) {
4501                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4502            }
4503        }
4504
4505        if (r != null) {
4506            sendPendingThumbnail(r, null, null, null, false);
4507        }
4508
4509        trimApplications();
4510
4511        Binder.restoreCallingIdentity(origId);
4512    }
4513
4514    public final void activityDestroyed(IBinder token) {
4515        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4516        mMainStack.activityDestroyed(token);
4517    }
4518
4519    public String getCallingPackage(IBinder token) {
4520        synchronized (this) {
4521            ActivityRecord r = getCallingRecordLocked(token);
4522            return r != null && r.app != null ? r.info.packageName : null;
4523        }
4524    }
4525
4526    public ComponentName getCallingActivity(IBinder token) {
4527        synchronized (this) {
4528            ActivityRecord r = getCallingRecordLocked(token);
4529            return r != null ? r.intent.getComponent() : null;
4530        }
4531    }
4532
4533    private ActivityRecord getCallingRecordLocked(IBinder token) {
4534        ActivityRecord r = mMainStack.isInStackLocked(token);
4535        if (r == null) {
4536            return null;
4537        }
4538        return r.resultTo;
4539    }
4540
4541    public ComponentName getActivityClassForToken(IBinder token) {
4542        synchronized(this) {
4543            ActivityRecord r = mMainStack.isInStackLocked(token);
4544            if (r == null) {
4545                return null;
4546            }
4547            return r.intent.getComponent();
4548        }
4549    }
4550
4551    public String getPackageForToken(IBinder token) {
4552        synchronized(this) {
4553            ActivityRecord r = mMainStack.isInStackLocked(token);
4554            if (r == null) {
4555                return null;
4556            }
4557            return r.packageName;
4558        }
4559    }
4560
4561    public IIntentSender getIntentSender(int type,
4562            String packageName, IBinder token, String resultWho,
4563            int requestCode, Intent[] intents, String[] resolvedTypes,
4564            int flags, Bundle options, int userId) {
4565        enforceNotIsolatedCaller("getIntentSender");
4566        // Refuse possible leaked file descriptors
4567        if (intents != null) {
4568            if (intents.length < 1) {
4569                throw new IllegalArgumentException("Intents array length must be >= 1");
4570            }
4571            for (int i=0; i<intents.length; i++) {
4572                Intent intent = intents[i];
4573                if (intent != null) {
4574                    if (intent.hasFileDescriptors()) {
4575                        throw new IllegalArgumentException("File descriptors passed in Intent");
4576                    }
4577                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4578                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4579                        throw new IllegalArgumentException(
4580                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4581                    }
4582                    intents[i] = new Intent(intent);
4583                }
4584            }
4585            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4586                throw new IllegalArgumentException(
4587                        "Intent array length does not match resolvedTypes length");
4588            }
4589        }
4590        if (options != null) {
4591            if (options.hasFileDescriptors()) {
4592                throw new IllegalArgumentException("File descriptors passed in options");
4593            }
4594        }
4595
4596        synchronized(this) {
4597            int callingUid = Binder.getCallingUid();
4598            int origUserId = userId;
4599            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4600                    type == ActivityManager.INTENT_SENDER_BROADCAST, true,
4601                    "getIntentSender", null);
4602            if (origUserId == UserHandle.USER_CURRENT) {
4603                // We don't want to evaluate this until the pending intent is
4604                // actually executed.  However, we do want to always do the
4605                // security checking for it above.
4606                userId = UserHandle.USER_CURRENT;
4607            }
4608            try {
4609                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4610                    int uid = AppGlobals.getPackageManager()
4611                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4612                    if (!UserHandle.isSameApp(callingUid, uid)) {
4613                        String msg = "Permission Denial: getIntentSender() from pid="
4614                            + Binder.getCallingPid()
4615                            + ", uid=" + Binder.getCallingUid()
4616                            + ", (need uid=" + uid + ")"
4617                            + " is not allowed to send as package " + packageName;
4618                        Slog.w(TAG, msg);
4619                        throw new SecurityException(msg);
4620                    }
4621                }
4622
4623                return getIntentSenderLocked(type, packageName, callingUid, userId,
4624                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4625
4626            } catch (RemoteException e) {
4627                throw new SecurityException(e);
4628            }
4629        }
4630    }
4631
4632    IIntentSender getIntentSenderLocked(int type, String packageName,
4633            int callingUid, int userId, IBinder token, String resultWho,
4634            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4635            Bundle options) {
4636        if (DEBUG_MU)
4637            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4638        ActivityRecord activity = null;
4639        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4640            activity = mMainStack.isInStackLocked(token);
4641            if (activity == null) {
4642                return null;
4643            }
4644            if (activity.finishing) {
4645                return null;
4646            }
4647        }
4648
4649        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4650        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4651        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4652        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4653                |PendingIntent.FLAG_UPDATE_CURRENT);
4654
4655        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4656                type, packageName, activity, resultWho,
4657                requestCode, intents, resolvedTypes, flags, options, userId);
4658        WeakReference<PendingIntentRecord> ref;
4659        ref = mIntentSenderRecords.get(key);
4660        PendingIntentRecord rec = ref != null ? ref.get() : null;
4661        if (rec != null) {
4662            if (!cancelCurrent) {
4663                if (updateCurrent) {
4664                    if (rec.key.requestIntent != null) {
4665                        rec.key.requestIntent.replaceExtras(intents != null ?
4666                                intents[intents.length - 1] : null);
4667                    }
4668                    if (intents != null) {
4669                        intents[intents.length-1] = rec.key.requestIntent;
4670                        rec.key.allIntents = intents;
4671                        rec.key.allResolvedTypes = resolvedTypes;
4672                    } else {
4673                        rec.key.allIntents = null;
4674                        rec.key.allResolvedTypes = null;
4675                    }
4676                }
4677                return rec;
4678            }
4679            rec.canceled = true;
4680            mIntentSenderRecords.remove(key);
4681        }
4682        if (noCreate) {
4683            return rec;
4684        }
4685        rec = new PendingIntentRecord(this, key, callingUid);
4686        mIntentSenderRecords.put(key, rec.ref);
4687        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4688            if (activity.pendingResults == null) {
4689                activity.pendingResults
4690                        = new HashSet<WeakReference<PendingIntentRecord>>();
4691            }
4692            activity.pendingResults.add(rec.ref);
4693        }
4694        return rec;
4695    }
4696
4697    public void cancelIntentSender(IIntentSender sender) {
4698        if (!(sender instanceof PendingIntentRecord)) {
4699            return;
4700        }
4701        synchronized(this) {
4702            PendingIntentRecord rec = (PendingIntentRecord)sender;
4703            try {
4704                int uid = AppGlobals.getPackageManager()
4705                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4706                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4707                    String msg = "Permission Denial: cancelIntentSender() from pid="
4708                        + Binder.getCallingPid()
4709                        + ", uid=" + Binder.getCallingUid()
4710                        + " is not allowed to cancel packges "
4711                        + rec.key.packageName;
4712                    Slog.w(TAG, msg);
4713                    throw new SecurityException(msg);
4714                }
4715            } catch (RemoteException e) {
4716                throw new SecurityException(e);
4717            }
4718            cancelIntentSenderLocked(rec, true);
4719        }
4720    }
4721
4722    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4723        rec.canceled = true;
4724        mIntentSenderRecords.remove(rec.key);
4725        if (cleanActivity && rec.key.activity != null) {
4726            rec.key.activity.pendingResults.remove(rec.ref);
4727        }
4728    }
4729
4730    public String getPackageForIntentSender(IIntentSender pendingResult) {
4731        if (!(pendingResult instanceof PendingIntentRecord)) {
4732            return null;
4733        }
4734        try {
4735            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4736            return res.key.packageName;
4737        } catch (ClassCastException e) {
4738        }
4739        return null;
4740    }
4741
4742    public int getUidForIntentSender(IIntentSender sender) {
4743        if (sender instanceof PendingIntentRecord) {
4744            try {
4745                PendingIntentRecord res = (PendingIntentRecord)sender;
4746                return res.uid;
4747            } catch (ClassCastException e) {
4748            }
4749        }
4750        return -1;
4751    }
4752
4753    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4754        if (!(pendingResult instanceof PendingIntentRecord)) {
4755            return false;
4756        }
4757        try {
4758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4759            if (res.key.allIntents == null) {
4760                return false;
4761            }
4762            for (int i=0; i<res.key.allIntents.length; i++) {
4763                Intent intent = res.key.allIntents[i];
4764                if (intent.getPackage() != null && intent.getComponent() != null) {
4765                    return false;
4766                }
4767            }
4768            return true;
4769        } catch (ClassCastException e) {
4770        }
4771        return false;
4772    }
4773
4774    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4775        if (!(pendingResult instanceof PendingIntentRecord)) {
4776            return false;
4777        }
4778        try {
4779            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4780            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4781                return true;
4782            }
4783            return false;
4784        } catch (ClassCastException e) {
4785        }
4786        return false;
4787    }
4788
4789    public void setProcessLimit(int max) {
4790        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4791                "setProcessLimit()");
4792        synchronized (this) {
4793            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4794            mProcessLimitOverride = max;
4795        }
4796        trimApplications();
4797    }
4798
4799    public int getProcessLimit() {
4800        synchronized (this) {
4801            return mProcessLimitOverride;
4802        }
4803    }
4804
4805    void foregroundTokenDied(ForegroundToken token) {
4806        synchronized (ActivityManagerService.this) {
4807            synchronized (mPidsSelfLocked) {
4808                ForegroundToken cur
4809                    = mForegroundProcesses.get(token.pid);
4810                if (cur != token) {
4811                    return;
4812                }
4813                mForegroundProcesses.remove(token.pid);
4814                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4815                if (pr == null) {
4816                    return;
4817                }
4818                pr.forcingToForeground = null;
4819                pr.foregroundServices = false;
4820            }
4821            updateOomAdjLocked();
4822        }
4823    }
4824
4825    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4826        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4827                "setProcessForeground()");
4828        synchronized(this) {
4829            boolean changed = false;
4830
4831            synchronized (mPidsSelfLocked) {
4832                ProcessRecord pr = mPidsSelfLocked.get(pid);
4833                if (pr == null && isForeground) {
4834                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4835                    return;
4836                }
4837                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4838                if (oldToken != null) {
4839                    oldToken.token.unlinkToDeath(oldToken, 0);
4840                    mForegroundProcesses.remove(pid);
4841                    if (pr != null) {
4842                        pr.forcingToForeground = null;
4843                    }
4844                    changed = true;
4845                }
4846                if (isForeground && token != null) {
4847                    ForegroundToken newToken = new ForegroundToken() {
4848                        public void binderDied() {
4849                            foregroundTokenDied(this);
4850                        }
4851                    };
4852                    newToken.pid = pid;
4853                    newToken.token = token;
4854                    try {
4855                        token.linkToDeath(newToken, 0);
4856                        mForegroundProcesses.put(pid, newToken);
4857                        pr.forcingToForeground = token;
4858                        changed = true;
4859                    } catch (RemoteException e) {
4860                        // If the process died while doing this, we will later
4861                        // do the cleanup with the process death link.
4862                    }
4863                }
4864            }
4865
4866            if (changed) {
4867                updateOomAdjLocked();
4868            }
4869        }
4870    }
4871
4872    // =========================================================
4873    // PERMISSIONS
4874    // =========================================================
4875
4876    static class PermissionController extends IPermissionController.Stub {
4877        ActivityManagerService mActivityManagerService;
4878        PermissionController(ActivityManagerService activityManagerService) {
4879            mActivityManagerService = activityManagerService;
4880        }
4881
4882        public boolean checkPermission(String permission, int pid, int uid) {
4883            return mActivityManagerService.checkPermission(permission, pid,
4884                    uid) == PackageManager.PERMISSION_GRANTED;
4885        }
4886    }
4887
4888    /**
4889     * This can be called with or without the global lock held.
4890     */
4891    int checkComponentPermission(String permission, int pid, int uid,
4892            int owningUid, boolean exported) {
4893        // We might be performing an operation on behalf of an indirect binder
4894        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4895        // client identity accordingly before proceeding.
4896        Identity tlsIdentity = sCallerIdentity.get();
4897        if (tlsIdentity != null) {
4898            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4899                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4900            uid = tlsIdentity.uid;
4901            pid = tlsIdentity.pid;
4902        }
4903
4904        if (pid == MY_PID) {
4905            return PackageManager.PERMISSION_GRANTED;
4906        }
4907
4908        return ActivityManager.checkComponentPermission(permission, uid,
4909                owningUid, exported);
4910    }
4911
4912    /**
4913     * As the only public entry point for permissions checking, this method
4914     * can enforce the semantic that requesting a check on a null global
4915     * permission is automatically denied.  (Internally a null permission
4916     * string is used when calling {@link #checkComponentPermission} in cases
4917     * when only uid-based security is needed.)
4918     *
4919     * This can be called with or without the global lock held.
4920     */
4921    public int checkPermission(String permission, int pid, int uid) {
4922        if (permission == null) {
4923            return PackageManager.PERMISSION_DENIED;
4924        }
4925        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4926    }
4927
4928    /**
4929     * Binder IPC calls go through the public entry point.
4930     * This can be called with or without the global lock held.
4931     */
4932    int checkCallingPermission(String permission) {
4933        return checkPermission(permission,
4934                Binder.getCallingPid(),
4935                UserHandle.getAppId(Binder.getCallingUid()));
4936    }
4937
4938    /**
4939     * This can be called with or without the global lock held.
4940     */
4941    void enforceCallingPermission(String permission, String func) {
4942        if (checkCallingPermission(permission)
4943                == PackageManager.PERMISSION_GRANTED) {
4944            return;
4945        }
4946
4947        String msg = "Permission Denial: " + func + " from pid="
4948                + Binder.getCallingPid()
4949                + ", uid=" + Binder.getCallingUid()
4950                + " requires " + permission;
4951        Slog.w(TAG, msg);
4952        throw new SecurityException(msg);
4953    }
4954
4955    /**
4956     * Determine if UID is holding permissions required to access {@link Uri} in
4957     * the given {@link ProviderInfo}. Final permission checking is always done
4958     * in {@link ContentProvider}.
4959     */
4960    private final boolean checkHoldingPermissionsLocked(
4961            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4962        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4963                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4964
4965        if (pi.applicationInfo.uid == uid) {
4966            return true;
4967        } else if (!pi.exported) {
4968            return false;
4969        }
4970
4971        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4972        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4973        try {
4974            // check if target holds top-level <provider> permissions
4975            if (!readMet && pi.readPermission != null
4976                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4977                readMet = true;
4978            }
4979            if (!writeMet && pi.writePermission != null
4980                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4981                writeMet = true;
4982            }
4983
4984            // track if unprotected read/write is allowed; any denied
4985            // <path-permission> below removes this ability
4986            boolean allowDefaultRead = pi.readPermission == null;
4987            boolean allowDefaultWrite = pi.writePermission == null;
4988
4989            // check if target holds any <path-permission> that match uri
4990            final PathPermission[] pps = pi.pathPermissions;
4991            if (pps != null) {
4992                final String path = uri.getPath();
4993                int i = pps.length;
4994                while (i > 0 && (!readMet || !writeMet)) {
4995                    i--;
4996                    PathPermission pp = pps[i];
4997                    if (pp.match(path)) {
4998                        if (!readMet) {
4999                            final String pprperm = pp.getReadPermission();
5000                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5001                                    + pprperm + " for " + pp.getPath()
5002                                    + ": match=" + pp.match(path)
5003                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5004                            if (pprperm != null) {
5005                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5006                                    readMet = true;
5007                                } else {
5008                                    allowDefaultRead = false;
5009                                }
5010                            }
5011                        }
5012                        if (!writeMet) {
5013                            final String ppwperm = pp.getWritePermission();
5014                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5015                                    + ppwperm + " for " + pp.getPath()
5016                                    + ": match=" + pp.match(path)
5017                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5018                            if (ppwperm != null) {
5019                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5020                                    writeMet = true;
5021                                } else {
5022                                    allowDefaultWrite = false;
5023                                }
5024                            }
5025                        }
5026                    }
5027                }
5028            }
5029
5030            // grant unprotected <provider> read/write, if not blocked by
5031            // <path-permission> above
5032            if (allowDefaultRead) readMet = true;
5033            if (allowDefaultWrite) writeMet = true;
5034
5035        } catch (RemoteException e) {
5036            return false;
5037        }
5038
5039        return readMet && writeMet;
5040    }
5041
5042    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5043            int modeFlags) {
5044        // Root gets to do everything.
5045        if (uid == 0) {
5046            return true;
5047        }
5048        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5049        if (perms == null) return false;
5050        UriPermission perm = perms.get(uri);
5051        if (perm == null) return false;
5052        return (modeFlags&perm.modeFlags) == modeFlags;
5053    }
5054
5055    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5056        enforceNotIsolatedCaller("checkUriPermission");
5057
5058        // Another redirected-binder-call permissions check as in
5059        // {@link checkComponentPermission}.
5060        Identity tlsIdentity = sCallerIdentity.get();
5061        if (tlsIdentity != null) {
5062            uid = tlsIdentity.uid;
5063            pid = tlsIdentity.pid;
5064        }
5065
5066        // Our own process gets to do everything.
5067        if (pid == MY_PID) {
5068            return PackageManager.PERMISSION_GRANTED;
5069        }
5070        synchronized(this) {
5071            return checkUriPermissionLocked(uri, uid, modeFlags)
5072                    ? PackageManager.PERMISSION_GRANTED
5073                    : PackageManager.PERMISSION_DENIED;
5074        }
5075    }
5076
5077    /**
5078     * Check if the targetPkg can be granted permission to access uri by
5079     * the callingUid using the given modeFlags.  Throws a security exception
5080     * if callingUid is not allowed to do this.  Returns the uid of the target
5081     * if the URI permission grant should be performed; returns -1 if it is not
5082     * needed (for example targetPkg already has permission to access the URI).
5083     * If you already know the uid of the target, you can supply it in
5084     * lastTargetUid else set that to -1.
5085     */
5086    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5087            Uri uri, int modeFlags, int lastTargetUid) {
5088        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5089                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5090        if (modeFlags == 0) {
5091            return -1;
5092        }
5093
5094        if (targetPkg != null) {
5095            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5096                    "Checking grant " + targetPkg + " permission to " + uri);
5097        }
5098
5099        final IPackageManager pm = AppGlobals.getPackageManager();
5100
5101        // If this is not a content: uri, we can't do anything with it.
5102        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5103            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5104                    "Can't grant URI permission for non-content URI: " + uri);
5105            return -1;
5106        }
5107
5108        String name = uri.getAuthority();
5109        ProviderInfo pi = null;
5110        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5111                UserHandle.getUserId(callingUid));
5112        if (cpr != null) {
5113            pi = cpr.info;
5114        } else {
5115            try {
5116                pi = pm.resolveContentProvider(name,
5117                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5118                        UserHandle.getUserId(callingUid));
5119            } catch (RemoteException ex) {
5120            }
5121        }
5122        if (pi == null) {
5123            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5124            return -1;
5125        }
5126
5127        int targetUid = lastTargetUid;
5128        if (targetUid < 0 && targetPkg != null) {
5129            try {
5130                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5131                if (targetUid < 0) {
5132                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5133                            "Can't grant URI permission no uid for: " + targetPkg);
5134                    return -1;
5135                }
5136            } catch (RemoteException ex) {
5137                return -1;
5138            }
5139        }
5140
5141        if (targetUid >= 0) {
5142            // First...  does the target actually need this permission?
5143            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5144                // No need to grant the target this permission.
5145                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5146                        "Target " + targetPkg + " already has full permission to " + uri);
5147                return -1;
5148            }
5149        } else {
5150            // First...  there is no target package, so can anyone access it?
5151            boolean allowed = pi.exported;
5152            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5153                if (pi.readPermission != null) {
5154                    allowed = false;
5155                }
5156            }
5157            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5158                if (pi.writePermission != null) {
5159                    allowed = false;
5160                }
5161            }
5162            if (allowed) {
5163                return -1;
5164            }
5165        }
5166
5167        // Second...  is the provider allowing granting of URI permissions?
5168        if (!pi.grantUriPermissions) {
5169            throw new SecurityException("Provider " + pi.packageName
5170                    + "/" + pi.name
5171                    + " does not allow granting of Uri permissions (uri "
5172                    + uri + ")");
5173        }
5174        if (pi.uriPermissionPatterns != null) {
5175            final int N = pi.uriPermissionPatterns.length;
5176            boolean allowed = false;
5177            for (int i=0; i<N; i++) {
5178                if (pi.uriPermissionPatterns[i] != null
5179                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5180                    allowed = true;
5181                    break;
5182                }
5183            }
5184            if (!allowed) {
5185                throw new SecurityException("Provider " + pi.packageName
5186                        + "/" + pi.name
5187                        + " does not allow granting of permission to path of Uri "
5188                        + uri);
5189            }
5190        }
5191
5192        // Third...  does the caller itself have permission to access
5193        // this uri?
5194        if (callingUid != Process.myUid()) {
5195            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5196                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5197                    throw new SecurityException("Uid " + callingUid
5198                            + " does not have permission to uri " + uri);
5199                }
5200            }
5201        }
5202
5203        return targetUid;
5204    }
5205
5206    public int checkGrantUriPermission(int callingUid, String targetPkg,
5207            Uri uri, int modeFlags) {
5208        enforceNotIsolatedCaller("checkGrantUriPermission");
5209        synchronized(this) {
5210            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5211        }
5212    }
5213
5214    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5215            Uri uri, int modeFlags, UriPermissionOwner owner) {
5216        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5217                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5218        if (modeFlags == 0) {
5219            return;
5220        }
5221
5222        // So here we are: the caller has the assumed permission
5223        // to the uri, and the target doesn't.  Let's now give this to
5224        // the target.
5225
5226        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5227                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5228
5229        HashMap<Uri, UriPermission> targetUris
5230                = mGrantedUriPermissions.get(targetUid);
5231        if (targetUris == null) {
5232            targetUris = new HashMap<Uri, UriPermission>();
5233            mGrantedUriPermissions.put(targetUid, targetUris);
5234        }
5235
5236        UriPermission perm = targetUris.get(uri);
5237        if (perm == null) {
5238            perm = new UriPermission(targetUid, uri);
5239            targetUris.put(uri, perm);
5240        }
5241
5242        perm.modeFlags |= modeFlags;
5243        if (owner == null) {
5244            perm.globalModeFlags |= modeFlags;
5245        } else {
5246            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5247                 perm.readOwners.add(owner);
5248                 owner.addReadPermission(perm);
5249            }
5250            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5251                 perm.writeOwners.add(owner);
5252                 owner.addWritePermission(perm);
5253            }
5254        }
5255    }
5256
5257    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5258            int modeFlags, UriPermissionOwner owner) {
5259        if (targetPkg == null) {
5260            throw new NullPointerException("targetPkg");
5261        }
5262
5263        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5264        if (targetUid < 0) {
5265            return;
5266        }
5267
5268        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5269    }
5270
5271    static class NeededUriGrants extends ArrayList<Uri> {
5272        final String targetPkg;
5273        final int targetUid;
5274        final int flags;
5275
5276        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5277            targetPkg = _targetPkg;
5278            targetUid = _targetUid;
5279            flags = _flags;
5280        }
5281    }
5282
5283    /**
5284     * Like checkGrantUriPermissionLocked, but takes an Intent.
5285     */
5286    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5287            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5288        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5289                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5290                + " clip=" + (intent != null ? intent.getClipData() : null)
5291                + " from " + intent + "; flags=0x"
5292                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5293
5294        if (targetPkg == null) {
5295            throw new NullPointerException("targetPkg");
5296        }
5297
5298        if (intent == null) {
5299            return null;
5300        }
5301        Uri data = intent.getData();
5302        ClipData clip = intent.getClipData();
5303        if (data == null && clip == null) {
5304            return null;
5305        }
5306        if (data != null) {
5307            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5308                mode, needed != null ? needed.targetUid : -1);
5309            if (target > 0) {
5310                if (needed == null) {
5311                    needed = new NeededUriGrants(targetPkg, target, mode);
5312                }
5313                needed.add(data);
5314            }
5315        }
5316        if (clip != null) {
5317            for (int i=0; i<clip.getItemCount(); i++) {
5318                Uri uri = clip.getItemAt(i).getUri();
5319                if (uri != null) {
5320                    int target = -1;
5321                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5322                            mode, needed != null ? needed.targetUid : -1);
5323                    if (target > 0) {
5324                        if (needed == null) {
5325                            needed = new NeededUriGrants(targetPkg, target, mode);
5326                        }
5327                        needed.add(uri);
5328                    }
5329                } else {
5330                    Intent clipIntent = clip.getItemAt(i).getIntent();
5331                    if (clipIntent != null) {
5332                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5333                                callingUid, targetPkg, clipIntent, mode, needed);
5334                        if (newNeeded != null) {
5335                            needed = newNeeded;
5336                        }
5337                    }
5338                }
5339            }
5340        }
5341
5342        return needed;
5343    }
5344
5345    /**
5346     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5347     */
5348    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5349            UriPermissionOwner owner) {
5350        if (needed != null) {
5351            for (int i=0; i<needed.size(); i++) {
5352                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5353                        needed.get(i), needed.flags, owner);
5354            }
5355        }
5356    }
5357
5358    void grantUriPermissionFromIntentLocked(int callingUid,
5359            String targetPkg, Intent intent, UriPermissionOwner owner) {
5360        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5361                intent, intent != null ? intent.getFlags() : 0, null);
5362        if (needed == null) {
5363            return;
5364        }
5365
5366        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5367    }
5368
5369    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5370            Uri uri, int modeFlags) {
5371        enforceNotIsolatedCaller("grantUriPermission");
5372        synchronized(this) {
5373            final ProcessRecord r = getRecordForAppLocked(caller);
5374            if (r == null) {
5375                throw new SecurityException("Unable to find app for caller "
5376                        + caller
5377                        + " when granting permission to uri " + uri);
5378            }
5379            if (targetPkg == null) {
5380                throw new IllegalArgumentException("null target");
5381            }
5382            if (uri == null) {
5383                throw new IllegalArgumentException("null uri");
5384            }
5385
5386            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5387                    null);
5388        }
5389    }
5390
5391    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5392        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5393                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5394            HashMap<Uri, UriPermission> perms
5395                    = mGrantedUriPermissions.get(perm.uid);
5396            if (perms != null) {
5397                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5398                        "Removing " + perm.uid + " permission to " + perm.uri);
5399                perms.remove(perm.uri);
5400                if (perms.size() == 0) {
5401                    mGrantedUriPermissions.remove(perm.uid);
5402                }
5403            }
5404        }
5405    }
5406
5407    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5408            int modeFlags) {
5409        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5410                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5411        if (modeFlags == 0) {
5412            return;
5413        }
5414
5415        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5416                "Revoking all granted permissions to " + uri);
5417
5418        final IPackageManager pm = AppGlobals.getPackageManager();
5419
5420        final String authority = uri.getAuthority();
5421        ProviderInfo pi = null;
5422        int userId = UserHandle.getUserId(callingUid);
5423        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5424        if (cpr != null) {
5425            pi = cpr.info;
5426        } else {
5427            try {
5428                pi = pm.resolveContentProvider(authority,
5429                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5430            } catch (RemoteException ex) {
5431            }
5432        }
5433        if (pi == null) {
5434            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5435            return;
5436        }
5437
5438        // Does the caller have this permission on the URI?
5439        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5440            // Right now, if you are not the original owner of the permission,
5441            // you are not allowed to revoke it.
5442            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5443                throw new SecurityException("Uid " + callingUid
5444                        + " does not have permission to uri " + uri);
5445            //}
5446        }
5447
5448        // Go through all of the permissions and remove any that match.
5449        final List<String> SEGMENTS = uri.getPathSegments();
5450        if (SEGMENTS != null) {
5451            final int NS = SEGMENTS.size();
5452            int N = mGrantedUriPermissions.size();
5453            for (int i=0; i<N; i++) {
5454                HashMap<Uri, UriPermission> perms
5455                        = mGrantedUriPermissions.valueAt(i);
5456                Iterator<UriPermission> it = perms.values().iterator();
5457            toploop:
5458                while (it.hasNext()) {
5459                    UriPermission perm = it.next();
5460                    Uri targetUri = perm.uri;
5461                    if (!authority.equals(targetUri.getAuthority())) {
5462                        continue;
5463                    }
5464                    List<String> targetSegments = targetUri.getPathSegments();
5465                    if (targetSegments == null) {
5466                        continue;
5467                    }
5468                    if (targetSegments.size() < NS) {
5469                        continue;
5470                    }
5471                    for (int j=0; j<NS; j++) {
5472                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5473                            continue toploop;
5474                        }
5475                    }
5476                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5477                            "Revoking " + perm.uid + " permission to " + perm.uri);
5478                    perm.clearModes(modeFlags);
5479                    if (perm.modeFlags == 0) {
5480                        it.remove();
5481                    }
5482                }
5483                if (perms.size() == 0) {
5484                    mGrantedUriPermissions.remove(
5485                            mGrantedUriPermissions.keyAt(i));
5486                    N--;
5487                    i--;
5488                }
5489            }
5490        }
5491    }
5492
5493    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5494            int modeFlags) {
5495        enforceNotIsolatedCaller("revokeUriPermission");
5496        synchronized(this) {
5497            final ProcessRecord r = getRecordForAppLocked(caller);
5498            if (r == null) {
5499                throw new SecurityException("Unable to find app for caller "
5500                        + caller
5501                        + " when revoking permission to uri " + uri);
5502            }
5503            if (uri == null) {
5504                Slog.w(TAG, "revokeUriPermission: null uri");
5505                return;
5506            }
5507
5508            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5509                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5510            if (modeFlags == 0) {
5511                return;
5512            }
5513
5514            final IPackageManager pm = AppGlobals.getPackageManager();
5515
5516            final String authority = uri.getAuthority();
5517            ProviderInfo pi = null;
5518            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5519            if (cpr != null) {
5520                pi = cpr.info;
5521            } else {
5522                try {
5523                    pi = pm.resolveContentProvider(authority,
5524                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5525                } catch (RemoteException ex) {
5526                }
5527            }
5528            if (pi == null) {
5529                Slog.w(TAG, "No content provider found for permission revoke: "
5530                        + uri.toSafeString());
5531                return;
5532            }
5533
5534            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5535        }
5536    }
5537
5538    @Override
5539    public IBinder newUriPermissionOwner(String name) {
5540        enforceNotIsolatedCaller("newUriPermissionOwner");
5541        synchronized(this) {
5542            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5543            return owner.getExternalTokenLocked();
5544        }
5545    }
5546
5547    @Override
5548    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5549            Uri uri, int modeFlags) {
5550        synchronized(this) {
5551            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5552            if (owner == null) {
5553                throw new IllegalArgumentException("Unknown owner: " + token);
5554            }
5555            if (fromUid != Binder.getCallingUid()) {
5556                if (Binder.getCallingUid() != Process.myUid()) {
5557                    // Only system code can grant URI permissions on behalf
5558                    // of other users.
5559                    throw new SecurityException("nice try");
5560                }
5561            }
5562            if (targetPkg == null) {
5563                throw new IllegalArgumentException("null target");
5564            }
5565            if (uri == null) {
5566                throw new IllegalArgumentException("null uri");
5567            }
5568
5569            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5570        }
5571    }
5572
5573    @Override
5574    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5575        synchronized(this) {
5576            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5577            if (owner == null) {
5578                throw new IllegalArgumentException("Unknown owner: " + token);
5579            }
5580
5581            if (uri == null) {
5582                owner.removeUriPermissionsLocked(mode);
5583            } else {
5584                owner.removeUriPermissionLocked(uri, mode);
5585            }
5586        }
5587    }
5588
5589    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5590        synchronized (this) {
5591            ProcessRecord app =
5592                who != null ? getRecordForAppLocked(who) : null;
5593            if (app == null) return;
5594
5595            Message msg = Message.obtain();
5596            msg.what = WAIT_FOR_DEBUGGER_MSG;
5597            msg.obj = app;
5598            msg.arg1 = waiting ? 1 : 0;
5599            mHandler.sendMessage(msg);
5600        }
5601    }
5602
5603    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5604        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5605        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5606        outInfo.availMem = Process.getFreeMemory();
5607        outInfo.totalMem = Process.getTotalMemory();
5608        outInfo.threshold = homeAppMem;
5609        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5610        outInfo.hiddenAppThreshold = hiddenAppMem;
5611        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5612                ProcessList.SERVICE_ADJ);
5613        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5614                ProcessList.VISIBLE_APP_ADJ);
5615        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5616                ProcessList.FOREGROUND_APP_ADJ);
5617    }
5618
5619    // =========================================================
5620    // TASK MANAGEMENT
5621    // =========================================================
5622
5623    public List getTasks(int maxNum, int flags,
5624                         IThumbnailReceiver receiver) {
5625        ArrayList list = new ArrayList();
5626
5627        PendingThumbnailsRecord pending = null;
5628        IApplicationThread topThumbnail = null;
5629        ActivityRecord topRecord = null;
5630
5631        synchronized(this) {
5632            if (localLOGV) Slog.v(
5633                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5634                + ", receiver=" + receiver);
5635
5636            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5637                    != PackageManager.PERMISSION_GRANTED) {
5638                if (receiver != null) {
5639                    // If the caller wants to wait for pending thumbnails,
5640                    // it ain't gonna get them.
5641                    try {
5642                        receiver.finished();
5643                    } catch (RemoteException ex) {
5644                    }
5645                }
5646                String msg = "Permission Denial: getTasks() from pid="
5647                        + Binder.getCallingPid()
5648                        + ", uid=" + Binder.getCallingUid()
5649                        + " requires " + android.Manifest.permission.GET_TASKS;
5650                Slog.w(TAG, msg);
5651                throw new SecurityException(msg);
5652            }
5653
5654            int pos = mMainStack.mHistory.size()-1;
5655            ActivityRecord next =
5656                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5657            ActivityRecord top = null;
5658            TaskRecord curTask = null;
5659            int numActivities = 0;
5660            int numRunning = 0;
5661            while (pos >= 0 && maxNum > 0) {
5662                final ActivityRecord r = next;
5663                pos--;
5664                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5665
5666                // Initialize state for next task if needed.
5667                if (top == null ||
5668                        (top.state == ActivityState.INITIALIZING
5669                            && top.task == r.task)) {
5670                    top = r;
5671                    curTask = r.task;
5672                    numActivities = numRunning = 0;
5673                }
5674
5675                // Add 'r' into the current task.
5676                numActivities++;
5677                if (r.app != null && r.app.thread != null) {
5678                    numRunning++;
5679                }
5680
5681                if (localLOGV) Slog.v(
5682                    TAG, r.intent.getComponent().flattenToShortString()
5683                    + ": task=" + r.task);
5684
5685                // If the next one is a different task, generate a new
5686                // TaskInfo entry for what we have.
5687                if (next == null || next.task != curTask) {
5688                    ActivityManager.RunningTaskInfo ci
5689                            = new ActivityManager.RunningTaskInfo();
5690                    ci.id = curTask.taskId;
5691                    ci.baseActivity = r.intent.getComponent();
5692                    ci.topActivity = top.intent.getComponent();
5693                    if (top.thumbHolder != null) {
5694                        ci.description = top.thumbHolder.lastDescription;
5695                    }
5696                    ci.numActivities = numActivities;
5697                    ci.numRunning = numRunning;
5698                    //System.out.println(
5699                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5700                    if (ci.thumbnail == null && receiver != null) {
5701                        if (localLOGV) Slog.v(
5702                            TAG, "State=" + top.state + "Idle=" + top.idle
5703                            + " app=" + top.app
5704                            + " thr=" + (top.app != null ? top.app.thread : null));
5705                        if (top.state == ActivityState.RESUMED
5706                                || top.state == ActivityState.PAUSING) {
5707                            if (top.idle && top.app != null
5708                                && top.app.thread != null) {
5709                                topRecord = top;
5710                                topThumbnail = top.app.thread;
5711                            } else {
5712                                top.thumbnailNeeded = true;
5713                            }
5714                        }
5715                        if (pending == null) {
5716                            pending = new PendingThumbnailsRecord(receiver);
5717                        }
5718                        pending.pendingRecords.add(top);
5719                    }
5720                    list.add(ci);
5721                    maxNum--;
5722                    top = null;
5723                }
5724            }
5725
5726            if (pending != null) {
5727                mPendingThumbnails.add(pending);
5728            }
5729        }
5730
5731        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5732
5733        if (topThumbnail != null) {
5734            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5735            try {
5736                topThumbnail.requestThumbnail(topRecord.appToken);
5737            } catch (Exception e) {
5738                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5739                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5740            }
5741        }
5742
5743        if (pending == null && receiver != null) {
5744            // In this case all thumbnails were available and the client
5745            // is being asked to be told when the remaining ones come in...
5746            // which is unusually, since the top-most currently running
5747            // activity should never have a canned thumbnail!  Oh well.
5748            try {
5749                receiver.finished();
5750            } catch (RemoteException ex) {
5751            }
5752        }
5753
5754        return list;
5755    }
5756
5757    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5758            int flags, int userId) {
5759        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5760                false, true, "getRecentTasks", null);
5761
5762        synchronized (this) {
5763            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5764                    "getRecentTasks()");
5765            final boolean detailed = checkCallingPermission(
5766                    android.Manifest.permission.GET_DETAILED_TASKS)
5767                    == PackageManager.PERMISSION_GRANTED;
5768
5769            IPackageManager pm = AppGlobals.getPackageManager();
5770
5771            final int N = mRecentTasks.size();
5772            ArrayList<ActivityManager.RecentTaskInfo> res
5773                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5774                            maxNum < N ? maxNum : N);
5775            for (int i=0; i<N && maxNum > 0; i++) {
5776                TaskRecord tr = mRecentTasks.get(i);
5777                // Only add calling user's recent tasks
5778                if (tr.userId != userId) continue;
5779                // Return the entry if desired by the caller.  We always return
5780                // the first entry, because callers always expect this to be the
5781                // foreground app.  We may filter others if the caller has
5782                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5783                // we should exclude the entry.
5784
5785                if (i == 0
5786                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5787                        || (tr.intent == null)
5788                        || ((tr.intent.getFlags()
5789                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5790                    ActivityManager.RecentTaskInfo rti
5791                            = new ActivityManager.RecentTaskInfo();
5792                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5793                    rti.persistentId = tr.taskId;
5794                    rti.baseIntent = new Intent(
5795                            tr.intent != null ? tr.intent : tr.affinityIntent);
5796                    if (!detailed) {
5797                        rti.baseIntent.replaceExtras((Bundle)null);
5798                    }
5799                    rti.origActivity = tr.origActivity;
5800                    rti.description = tr.lastDescription;
5801
5802                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5803                        // Check whether this activity is currently available.
5804                        try {
5805                            if (rti.origActivity != null) {
5806                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5807                                        == null) {
5808                                    continue;
5809                                }
5810                            } else if (rti.baseIntent != null) {
5811                                if (pm.queryIntentActivities(rti.baseIntent,
5812                                        null, 0, userId) == null) {
5813                                    continue;
5814                                }
5815                            }
5816                        } catch (RemoteException e) {
5817                            // Will never happen.
5818                        }
5819                    }
5820
5821                    res.add(rti);
5822                    maxNum--;
5823                }
5824            }
5825            return res;
5826        }
5827    }
5828
5829    private TaskRecord taskForIdLocked(int id) {
5830        final int N = mRecentTasks.size();
5831        for (int i=0; i<N; i++) {
5832            TaskRecord tr = mRecentTasks.get(i);
5833            if (tr.taskId == id) {
5834                return tr;
5835            }
5836        }
5837        return null;
5838    }
5839
5840    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5841        synchronized (this) {
5842            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5843                    "getTaskThumbnails()");
5844            TaskRecord tr = taskForIdLocked(id);
5845            if (tr != null) {
5846                return mMainStack.getTaskThumbnailsLocked(tr);
5847            }
5848        }
5849        return null;
5850    }
5851
5852    public Bitmap getTaskTopThumbnail(int id) {
5853        synchronized (this) {
5854            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5855                    "getTaskTopThumbnail()");
5856            TaskRecord tr = taskForIdLocked(id);
5857            if (tr != null) {
5858                return mMainStack.getTaskTopThumbnailLocked(tr);
5859            }
5860        }
5861        return null;
5862    }
5863
5864    public boolean removeSubTask(int taskId, int subTaskIndex) {
5865        synchronized (this) {
5866            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5867                    "removeSubTask()");
5868            long ident = Binder.clearCallingIdentity();
5869            try {
5870                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5871                        true) != null;
5872            } finally {
5873                Binder.restoreCallingIdentity(ident);
5874            }
5875        }
5876    }
5877
5878    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5879        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5880        Intent baseIntent = new Intent(
5881                tr.intent != null ? tr.intent : tr.affinityIntent);
5882        ComponentName component = baseIntent.getComponent();
5883        if (component == null) {
5884            Slog.w(TAG, "Now component for base intent of task: " + tr);
5885            return;
5886        }
5887
5888        // Find any running services associated with this app.
5889        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5890
5891        if (killProcesses) {
5892            // Find any running processes associated with this app.
5893            final String pkg = component.getPackageName();
5894            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5895            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5896            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5897                for (int i=0; i<uids.size(); i++) {
5898                    ProcessRecord proc = uids.valueAt(i);
5899                    if (proc.userId != tr.userId) {
5900                        continue;
5901                    }
5902                    if (!proc.pkgList.contains(pkg)) {
5903                        continue;
5904                    }
5905                    procs.add(proc);
5906                }
5907            }
5908
5909            // Kill the running processes.
5910            for (int i=0; i<procs.size(); i++) {
5911                ProcessRecord pr = procs.get(i);
5912                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5913                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5914                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5915                            pr.processName, pr.setAdj, "remove task");
5916                    pr.killedBackground = true;
5917                    Process.killProcessQuiet(pr.pid);
5918                } else {
5919                    pr.waitingToKill = "remove task";
5920                }
5921            }
5922        }
5923    }
5924
5925    public boolean removeTask(int taskId, int flags) {
5926        synchronized (this) {
5927            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5928                    "removeTask()");
5929            long ident = Binder.clearCallingIdentity();
5930            try {
5931                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5932                        false);
5933                if (r != null) {
5934                    mRecentTasks.remove(r.task);
5935                    cleanUpRemovedTaskLocked(r.task, flags);
5936                    return true;
5937                } else {
5938                    TaskRecord tr = null;
5939                    int i=0;
5940                    while (i < mRecentTasks.size()) {
5941                        TaskRecord t = mRecentTasks.get(i);
5942                        if (t.taskId == taskId) {
5943                            tr = t;
5944                            break;
5945                        }
5946                        i++;
5947                    }
5948                    if (tr != null) {
5949                        if (tr.numActivities <= 0) {
5950                            // Caller is just removing a recent task that is
5951                            // not actively running.  That is easy!
5952                            mRecentTasks.remove(i);
5953                            cleanUpRemovedTaskLocked(tr, flags);
5954                            return true;
5955                        } else {
5956                            Slog.w(TAG, "removeTask: task " + taskId
5957                                    + " does not have activities to remove, "
5958                                    + " but numActivities=" + tr.numActivities
5959                                    + ": " + tr);
5960                        }
5961                    }
5962                }
5963            } finally {
5964                Binder.restoreCallingIdentity(ident);
5965            }
5966        }
5967        return false;
5968    }
5969
5970    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5971        int j;
5972        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5973        TaskRecord jt = startTask;
5974
5975        // First look backwards
5976        for (j=startIndex-1; j>=0; j--) {
5977            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5978            if (r.task != jt) {
5979                jt = r.task;
5980                if (affinity.equals(jt.affinity)) {
5981                    return j;
5982                }
5983            }
5984        }
5985
5986        // Now look forwards
5987        final int N = mMainStack.mHistory.size();
5988        jt = startTask;
5989        for (j=startIndex+1; j<N; j++) {
5990            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5991            if (r.task != jt) {
5992                if (affinity.equals(jt.affinity)) {
5993                    return j;
5994                }
5995                jt = r.task;
5996            }
5997        }
5998
5999        // Might it be at the top?
6000        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6001            return N-1;
6002        }
6003
6004        return -1;
6005    }
6006
6007    /**
6008     * TODO: Add mController hook
6009     */
6010    public void moveTaskToFront(int task, int flags, Bundle options) {
6011        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6012                "moveTaskToFront()");
6013
6014        synchronized(this) {
6015            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6016                    Binder.getCallingUid(), "Task to front")) {
6017                ActivityOptions.abort(options);
6018                return;
6019            }
6020            final long origId = Binder.clearCallingIdentity();
6021            try {
6022                TaskRecord tr = taskForIdLocked(task);
6023                if (tr != null) {
6024                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6025                        mMainStack.mUserLeaving = true;
6026                    }
6027                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6028                        // Caller wants the home activity moved with it.  To accomplish this,
6029                        // we'll just move the home task to the top first.
6030                        mMainStack.moveHomeToFrontLocked();
6031                    }
6032                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6033                    return;
6034                }
6035                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6036                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6037                    if (hr.task.taskId == task) {
6038                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6039                            mMainStack.mUserLeaving = true;
6040                        }
6041                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6042                            // Caller wants the home activity moved with it.  To accomplish this,
6043                            // we'll just move the home task to the top first.
6044                            mMainStack.moveHomeToFrontLocked();
6045                        }
6046                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6047                        return;
6048                    }
6049                }
6050            } finally {
6051                Binder.restoreCallingIdentity(origId);
6052            }
6053            ActivityOptions.abort(options);
6054        }
6055    }
6056
6057    public void moveTaskToBack(int task) {
6058        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6059                "moveTaskToBack()");
6060
6061        synchronized(this) {
6062            if (mMainStack.mResumedActivity != null
6063                    && mMainStack.mResumedActivity.task.taskId == task) {
6064                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6065                        Binder.getCallingUid(), "Task to back")) {
6066                    return;
6067                }
6068            }
6069            final long origId = Binder.clearCallingIdentity();
6070            mMainStack.moveTaskToBackLocked(task, null);
6071            Binder.restoreCallingIdentity(origId);
6072        }
6073    }
6074
6075    /**
6076     * Moves an activity, and all of the other activities within the same task, to the bottom
6077     * of the history stack.  The activity's order within the task is unchanged.
6078     *
6079     * @param token A reference to the activity we wish to move
6080     * @param nonRoot If false then this only works if the activity is the root
6081     *                of a task; if true it will work for any activity in a task.
6082     * @return Returns true if the move completed, false if not.
6083     */
6084    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6085        enforceNotIsolatedCaller("moveActivityTaskToBack");
6086        synchronized(this) {
6087            final long origId = Binder.clearCallingIdentity();
6088            int taskId = getTaskForActivityLocked(token, !nonRoot);
6089            if (taskId >= 0) {
6090                return mMainStack.moveTaskToBackLocked(taskId, null);
6091            }
6092            Binder.restoreCallingIdentity(origId);
6093        }
6094        return false;
6095    }
6096
6097    public void moveTaskBackwards(int task) {
6098        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6099                "moveTaskBackwards()");
6100
6101        synchronized(this) {
6102            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6103                    Binder.getCallingUid(), "Task backwards")) {
6104                return;
6105            }
6106            final long origId = Binder.clearCallingIdentity();
6107            moveTaskBackwardsLocked(task);
6108            Binder.restoreCallingIdentity(origId);
6109        }
6110    }
6111
6112    private final void moveTaskBackwardsLocked(int task) {
6113        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6114    }
6115
6116    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6117        synchronized(this) {
6118            return getTaskForActivityLocked(token, onlyRoot);
6119        }
6120    }
6121
6122    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6123        final int N = mMainStack.mHistory.size();
6124        TaskRecord lastTask = null;
6125        for (int i=0; i<N; i++) {
6126            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6127            if (r.appToken == token) {
6128                if (!onlyRoot || lastTask != r.task) {
6129                    return r.task.taskId;
6130                }
6131                return -1;
6132            }
6133            lastTask = r.task;
6134        }
6135
6136        return -1;
6137    }
6138
6139    // =========================================================
6140    // THUMBNAILS
6141    // =========================================================
6142
6143    public void reportThumbnail(IBinder token,
6144            Bitmap thumbnail, CharSequence description) {
6145        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6146        final long origId = Binder.clearCallingIdentity();
6147        sendPendingThumbnail(null, token, thumbnail, description, true);
6148        Binder.restoreCallingIdentity(origId);
6149    }
6150
6151    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6152            Bitmap thumbnail, CharSequence description, boolean always) {
6153        TaskRecord task = null;
6154        ArrayList receivers = null;
6155
6156        //System.out.println("Send pending thumbnail: " + r);
6157
6158        synchronized(this) {
6159            if (r == null) {
6160                r = mMainStack.isInStackLocked(token);
6161                if (r == null) {
6162                    return;
6163                }
6164            }
6165            if (thumbnail == null && r.thumbHolder != null) {
6166                thumbnail = r.thumbHolder.lastThumbnail;
6167                description = r.thumbHolder.lastDescription;
6168            }
6169            if (thumbnail == null && !always) {
6170                // If there is no thumbnail, and this entry is not actually
6171                // going away, then abort for now and pick up the next
6172                // thumbnail we get.
6173                return;
6174            }
6175            task = r.task;
6176
6177            int N = mPendingThumbnails.size();
6178            int i=0;
6179            while (i<N) {
6180                PendingThumbnailsRecord pr =
6181                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6182                //System.out.println("Looking in " + pr.pendingRecords);
6183                if (pr.pendingRecords.remove(r)) {
6184                    if (receivers == null) {
6185                        receivers = new ArrayList();
6186                    }
6187                    receivers.add(pr);
6188                    if (pr.pendingRecords.size() == 0) {
6189                        pr.finished = true;
6190                        mPendingThumbnails.remove(i);
6191                        N--;
6192                        continue;
6193                    }
6194                }
6195                i++;
6196            }
6197        }
6198
6199        if (receivers != null) {
6200            final int N = receivers.size();
6201            for (int i=0; i<N; i++) {
6202                try {
6203                    PendingThumbnailsRecord pr =
6204                        (PendingThumbnailsRecord)receivers.get(i);
6205                    pr.receiver.newThumbnail(
6206                        task != null ? task.taskId : -1, thumbnail, description);
6207                    if (pr.finished) {
6208                        pr.receiver.finished();
6209                    }
6210                } catch (Exception e) {
6211                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6212                }
6213            }
6214        }
6215    }
6216
6217    // =========================================================
6218    // CONTENT PROVIDERS
6219    // =========================================================
6220
6221    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6222        List<ProviderInfo> providers = null;
6223        try {
6224            providers = AppGlobals.getPackageManager().
6225                queryContentProviders(app.processName, app.uid,
6226                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6227        } catch (RemoteException ex) {
6228        }
6229        if (DEBUG_MU)
6230            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6231        int userId = app.userId;
6232        if (providers != null) {
6233            int N = providers.size();
6234            for (int i=0; i<N; i++) {
6235                ProviderInfo cpi =
6236                    (ProviderInfo)providers.get(i);
6237                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6238                        cpi.name, cpi.flags);
6239                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6240                    // This is a singleton provider, but a user besides the
6241                    // default user is asking to initialize a process it runs
6242                    // in...  well, no, it doesn't actually run in this process,
6243                    // it runs in the process of the default user.  Get rid of it.
6244                    providers.remove(i);
6245                    N--;
6246                    continue;
6247                }
6248
6249                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6250                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6251                if (cpr == null) {
6252                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6253                    mProviderMap.putProviderByClass(comp, cpr);
6254                }
6255                if (DEBUG_MU)
6256                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6257                app.pubProviders.put(cpi.name, cpr);
6258                app.addPackage(cpi.applicationInfo.packageName);
6259                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6260            }
6261        }
6262        return providers;
6263    }
6264
6265    /**
6266     * Check if {@link ProcessRecord} has a possible chance at accessing the
6267     * given {@link ProviderInfo}. Final permission checking is always done
6268     * in {@link ContentProvider}.
6269     */
6270    private final String checkContentProviderPermissionLocked(
6271            ProviderInfo cpi, ProcessRecord r) {
6272        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6273        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6274        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6275                cpi.applicationInfo.uid, cpi.exported)
6276                == PackageManager.PERMISSION_GRANTED) {
6277            return null;
6278        }
6279        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6280                cpi.applicationInfo.uid, cpi.exported)
6281                == PackageManager.PERMISSION_GRANTED) {
6282            return null;
6283        }
6284
6285        PathPermission[] pps = cpi.pathPermissions;
6286        if (pps != null) {
6287            int i = pps.length;
6288            while (i > 0) {
6289                i--;
6290                PathPermission pp = pps[i];
6291                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6292                        cpi.applicationInfo.uid, cpi.exported)
6293                        == PackageManager.PERMISSION_GRANTED) {
6294                    return null;
6295                }
6296                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6297                        cpi.applicationInfo.uid, cpi.exported)
6298                        == PackageManager.PERMISSION_GRANTED) {
6299                    return null;
6300                }
6301            }
6302        }
6303
6304        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6305        if (perms != null) {
6306            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6307                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6308                    return null;
6309                }
6310            }
6311        }
6312
6313        String msg;
6314        if (!cpi.exported) {
6315            msg = "Permission Denial: opening provider " + cpi.name
6316                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6317                    + ", uid=" + callingUid + ") that is not exported from uid "
6318                    + cpi.applicationInfo.uid;
6319        } else {
6320            msg = "Permission Denial: opening provider " + cpi.name
6321                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6322                    + ", uid=" + callingUid + ") requires "
6323                    + cpi.readPermission + " or " + cpi.writePermission;
6324        }
6325        Slog.w(TAG, msg);
6326        return msg;
6327    }
6328
6329    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6330            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6331        if (r != null) {
6332            for (int i=0; i<r.conProviders.size(); i++) {
6333                ContentProviderConnection conn = r.conProviders.get(i);
6334                if (conn.provider == cpr) {
6335                    if (DEBUG_PROVIDER) Slog.v(TAG,
6336                            "Adding provider requested by "
6337                            + r.processName + " from process "
6338                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6339                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6340                    if (stable) {
6341                        conn.stableCount++;
6342                        conn.numStableIncs++;
6343                    } else {
6344                        conn.unstableCount++;
6345                        conn.numUnstableIncs++;
6346                    }
6347                    return conn;
6348                }
6349            }
6350            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6351            if (stable) {
6352                conn.stableCount = 1;
6353                conn.numStableIncs = 1;
6354            } else {
6355                conn.unstableCount = 1;
6356                conn.numUnstableIncs = 1;
6357            }
6358            cpr.connections.add(conn);
6359            r.conProviders.add(conn);
6360            return conn;
6361        }
6362        cpr.addExternalProcessHandleLocked(externalProcessToken);
6363        return null;
6364    }
6365
6366    boolean decProviderCountLocked(ContentProviderConnection conn,
6367            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6368        if (conn != null) {
6369            cpr = conn.provider;
6370            if (DEBUG_PROVIDER) Slog.v(TAG,
6371                    "Removing provider requested by "
6372                    + conn.client.processName + " from process "
6373                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6374                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6375            if (stable) {
6376                conn.stableCount--;
6377            } else {
6378                conn.unstableCount--;
6379            }
6380            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6381                cpr.connections.remove(conn);
6382                conn.client.conProviders.remove(conn);
6383                return true;
6384            }
6385            return false;
6386        }
6387        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6388        return false;
6389    }
6390
6391    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6392            String name, IBinder token, boolean stable, int userId) {
6393        ContentProviderRecord cpr;
6394        ContentProviderConnection conn = null;
6395        ProviderInfo cpi = null;
6396
6397        synchronized(this) {
6398            ProcessRecord r = null;
6399            if (caller != null) {
6400                r = getRecordForAppLocked(caller);
6401                if (r == null) {
6402                    throw new SecurityException(
6403                            "Unable to find app for caller " + caller
6404                          + " (pid=" + Binder.getCallingPid()
6405                          + ") when getting content provider " + name);
6406                }
6407            }
6408
6409            // First check if this content provider has been published...
6410            cpr = mProviderMap.getProviderByName(name, userId);
6411            boolean providerRunning = cpr != null;
6412            if (providerRunning) {
6413                cpi = cpr.info;
6414                String msg;
6415                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6416                    throw new SecurityException(msg);
6417                }
6418
6419                if (r != null && cpr.canRunHere(r)) {
6420                    // This provider has been published or is in the process
6421                    // of being published...  but it is also allowed to run
6422                    // in the caller's process, so don't make a connection
6423                    // and just let the caller instantiate its own instance.
6424                    ContentProviderHolder holder = cpr.newHolder(null);
6425                    // don't give caller the provider object, it needs
6426                    // to make its own.
6427                    holder.provider = null;
6428                    return holder;
6429                }
6430
6431                final long origId = Binder.clearCallingIdentity();
6432
6433                // In this case the provider instance already exists, so we can
6434                // return it right away.
6435                conn = incProviderCountLocked(r, cpr, token, stable);
6436                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6437                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6438                        // If this is a perceptible app accessing the provider,
6439                        // make sure to count it as being accessed and thus
6440                        // back up on the LRU list.  This is good because
6441                        // content providers are often expensive to start.
6442                        updateLruProcessLocked(cpr.proc, false);
6443                    }
6444                }
6445
6446                if (cpr.proc != null) {
6447                    if (false) {
6448                        if (cpr.name.flattenToShortString().equals(
6449                                "com.android.providers.calendar/.CalendarProvider2")) {
6450                            Slog.v(TAG, "****************** KILLING "
6451                                + cpr.name.flattenToShortString());
6452                            Process.killProcess(cpr.proc.pid);
6453                        }
6454                    }
6455                    boolean success = updateOomAdjLocked(cpr.proc);
6456                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6457                    // NOTE: there is still a race here where a signal could be
6458                    // pending on the process even though we managed to update its
6459                    // adj level.  Not sure what to do about this, but at least
6460                    // the race is now smaller.
6461                    if (!success) {
6462                        // Uh oh...  it looks like the provider's process
6463                        // has been killed on us.  We need to wait for a new
6464                        // process to be started, and make sure its death
6465                        // doesn't kill our process.
6466                        Slog.i(TAG,
6467                                "Existing provider " + cpr.name.flattenToShortString()
6468                                + " is crashing; detaching " + r);
6469                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6470                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6471                        if (!lastRef) {
6472                            // This wasn't the last ref our process had on
6473                            // the provider...  we have now been killed, bail.
6474                            return null;
6475                        }
6476                        providerRunning = false;
6477                        conn = null;
6478                    }
6479                }
6480
6481                Binder.restoreCallingIdentity(origId);
6482            }
6483
6484            boolean singleton;
6485            if (!providerRunning) {
6486                try {
6487                    cpi = AppGlobals.getPackageManager().
6488                        resolveContentProvider(name,
6489                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6490                } catch (RemoteException ex) {
6491                }
6492                if (cpi == null) {
6493                    return null;
6494                }
6495                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6496                        cpi.name, cpi.flags);
6497                if (singleton) {
6498                    userId = 0;
6499                }
6500                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6501
6502                String msg;
6503                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6504                    throw new SecurityException(msg);
6505                }
6506
6507                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6508                        && !cpi.processName.equals("system")) {
6509                    // If this content provider does not run in the system
6510                    // process, and the system is not yet ready to run other
6511                    // processes, then fail fast instead of hanging.
6512                    throw new IllegalArgumentException(
6513                            "Attempt to launch content provider before system ready");
6514                }
6515
6516                // Make sure that the user who owns this provider is started.  If not,
6517                // we don't want to allow it to run.
6518                if (mStartedUsers.get(userId) == null) {
6519                    Slog.w(TAG, "Unable to launch app "
6520                            + cpi.applicationInfo.packageName + "/"
6521                            + cpi.applicationInfo.uid + " for provider "
6522                            + name + ": user " + userId + " is stopped");
6523                    return null;
6524                }
6525
6526                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6527                cpr = mProviderMap.getProviderByClass(comp, userId);
6528                final boolean firstClass = cpr == null;
6529                if (firstClass) {
6530                    try {
6531                        ApplicationInfo ai =
6532                            AppGlobals.getPackageManager().
6533                                getApplicationInfo(
6534                                        cpi.applicationInfo.packageName,
6535                                        STOCK_PM_FLAGS, userId);
6536                        if (ai == null) {
6537                            Slog.w(TAG, "No package info for content provider "
6538                                    + cpi.name);
6539                            return null;
6540                        }
6541                        ai = getAppInfoForUser(ai, userId);
6542                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6543                    } catch (RemoteException ex) {
6544                        // pm is in same process, this will never happen.
6545                    }
6546                }
6547
6548                if (r != null && cpr.canRunHere(r)) {
6549                    // If this is a multiprocess provider, then just return its
6550                    // info and allow the caller to instantiate it.  Only do
6551                    // this if the provider is the same user as the caller's
6552                    // process, or can run as root (so can be in any process).
6553                    return cpr.newHolder(null);
6554                }
6555
6556                if (DEBUG_PROVIDER) {
6557                    RuntimeException e = new RuntimeException("here");
6558                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6559                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6560                }
6561
6562                // This is single process, and our app is now connecting to it.
6563                // See if we are already in the process of launching this
6564                // provider.
6565                final int N = mLaunchingProviders.size();
6566                int i;
6567                for (i=0; i<N; i++) {
6568                    if (mLaunchingProviders.get(i) == cpr) {
6569                        break;
6570                    }
6571                }
6572
6573                // If the provider is not already being launched, then get it
6574                // started.
6575                if (i >= N) {
6576                    final long origId = Binder.clearCallingIdentity();
6577
6578                    try {
6579                        // Content provider is now in use, its package can't be stopped.
6580                        try {
6581                            AppGlobals.getPackageManager().setPackageStoppedState(
6582                                    cpr.appInfo.packageName, false, userId);
6583                        } catch (RemoteException e) {
6584                        } catch (IllegalArgumentException e) {
6585                            Slog.w(TAG, "Failed trying to unstop package "
6586                                    + cpr.appInfo.packageName + ": " + e);
6587                        }
6588
6589                        ProcessRecord proc = startProcessLocked(cpi.processName,
6590                                cpr.appInfo, false, 0, "content provider",
6591                                new ComponentName(cpi.applicationInfo.packageName,
6592                                        cpi.name), false, false);
6593                        if (proc == null) {
6594                            Slog.w(TAG, "Unable to launch app "
6595                                    + cpi.applicationInfo.packageName + "/"
6596                                    + cpi.applicationInfo.uid + " for provider "
6597                                    + name + ": process is bad");
6598                            return null;
6599                        }
6600                        cpr.launchingApp = proc;
6601                        mLaunchingProviders.add(cpr);
6602                    } finally {
6603                        Binder.restoreCallingIdentity(origId);
6604                    }
6605                }
6606
6607                // Make sure the provider is published (the same provider class
6608                // may be published under multiple names).
6609                if (firstClass) {
6610                    mProviderMap.putProviderByClass(comp, cpr);
6611                }
6612
6613                mProviderMap.putProviderByName(name, cpr);
6614                conn = incProviderCountLocked(r, cpr, token, stable);
6615                if (conn != null) {
6616                    conn.waiting = true;
6617                }
6618            }
6619        }
6620
6621        // Wait for the provider to be published...
6622        synchronized (cpr) {
6623            while (cpr.provider == null) {
6624                if (cpr.launchingApp == null) {
6625                    Slog.w(TAG, "Unable to launch app "
6626                            + cpi.applicationInfo.packageName + "/"
6627                            + cpi.applicationInfo.uid + " for provider "
6628                            + name + ": launching app became null");
6629                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6630                            UserHandle.getUserId(cpi.applicationInfo.uid),
6631                            cpi.applicationInfo.packageName,
6632                            cpi.applicationInfo.uid, name);
6633                    return null;
6634                }
6635                try {
6636                    if (DEBUG_MU) {
6637                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6638                                + cpr.launchingApp);
6639                    }
6640                    if (conn != null) {
6641                        conn.waiting = true;
6642                    }
6643                    cpr.wait();
6644                } catch (InterruptedException ex) {
6645                } finally {
6646                    if (conn != null) {
6647                        conn.waiting = false;
6648                    }
6649                }
6650            }
6651        }
6652        return cpr != null ? cpr.newHolder(conn) : null;
6653    }
6654
6655    public final ContentProviderHolder getContentProvider(
6656            IApplicationThread caller, String name, int userId, boolean stable) {
6657        enforceNotIsolatedCaller("getContentProvider");
6658        if (caller == null) {
6659            String msg = "null IApplicationThread when getting content provider "
6660                    + name;
6661            Slog.w(TAG, msg);
6662            throw new SecurityException(msg);
6663        }
6664
6665        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6666                false, true, "getContentProvider", null);
6667        return getContentProviderImpl(caller, name, null, stable, userId);
6668    }
6669
6670    public ContentProviderHolder getContentProviderExternal(
6671            String name, int userId, IBinder token) {
6672        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6673            "Do not have permission in call getContentProviderExternal()");
6674        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6675                false, true, "getContentProvider", null);
6676        return getContentProviderExternalUnchecked(name, token, userId);
6677    }
6678
6679    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6680            IBinder token, int userId) {
6681        return getContentProviderImpl(null, name, token, true, userId);
6682    }
6683
6684    /**
6685     * Drop a content provider from a ProcessRecord's bookkeeping
6686     * @param cpr
6687     */
6688    public void removeContentProvider(IBinder connection, boolean stable) {
6689        enforceNotIsolatedCaller("removeContentProvider");
6690        synchronized (this) {
6691            ContentProviderConnection conn;
6692            try {
6693                conn = (ContentProviderConnection)connection;
6694            } catch (ClassCastException e) {
6695                String msg ="removeContentProvider: " + connection
6696                        + " not a ContentProviderConnection";
6697                Slog.w(TAG, msg);
6698                throw new IllegalArgumentException(msg);
6699            }
6700            if (conn == null) {
6701                throw new NullPointerException("connection is null");
6702            }
6703            if (decProviderCountLocked(conn, null, null, stable)) {
6704                updateOomAdjLocked();
6705            }
6706        }
6707    }
6708
6709    public void removeContentProviderExternal(String name, IBinder token) {
6710        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6711            "Do not have permission in call removeContentProviderExternal()");
6712        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6713    }
6714
6715    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6716        synchronized (this) {
6717            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6718            if(cpr == null) {
6719                //remove from mProvidersByClass
6720                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6721                return;
6722            }
6723
6724            //update content provider record entry info
6725            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6726            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6727            if (localCpr.hasExternalProcessHandles()) {
6728                if (localCpr.removeExternalProcessHandleLocked(token)) {
6729                    updateOomAdjLocked();
6730                } else {
6731                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6732                            + " with no external reference for token: "
6733                            + token + ".");
6734                }
6735            } else {
6736                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6737                        + " with no external references.");
6738            }
6739        }
6740    }
6741
6742    public final void publishContentProviders(IApplicationThread caller,
6743            List<ContentProviderHolder> providers) {
6744        if (providers == null) {
6745            return;
6746        }
6747
6748        enforceNotIsolatedCaller("publishContentProviders");
6749        synchronized (this) {
6750            final ProcessRecord r = getRecordForAppLocked(caller);
6751            if (DEBUG_MU)
6752                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6753            if (r == null) {
6754                throw new SecurityException(
6755                        "Unable to find app for caller " + caller
6756                      + " (pid=" + Binder.getCallingPid()
6757                      + ") when publishing content providers");
6758            }
6759
6760            final long origId = Binder.clearCallingIdentity();
6761
6762            final int N = providers.size();
6763            for (int i=0; i<N; i++) {
6764                ContentProviderHolder src = providers.get(i);
6765                if (src == null || src.info == null || src.provider == null) {
6766                    continue;
6767                }
6768                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6769                if (DEBUG_MU)
6770                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6771                if (dst != null) {
6772                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6773                    mProviderMap.putProviderByClass(comp, dst);
6774                    String names[] = dst.info.authority.split(";");
6775                    for (int j = 0; j < names.length; j++) {
6776                        mProviderMap.putProviderByName(names[j], dst);
6777                    }
6778
6779                    int NL = mLaunchingProviders.size();
6780                    int j;
6781                    for (j=0; j<NL; j++) {
6782                        if (mLaunchingProviders.get(j) == dst) {
6783                            mLaunchingProviders.remove(j);
6784                            j--;
6785                            NL--;
6786                        }
6787                    }
6788                    synchronized (dst) {
6789                        dst.provider = src.provider;
6790                        dst.proc = r;
6791                        dst.notifyAll();
6792                    }
6793                    updateOomAdjLocked(r);
6794                }
6795            }
6796
6797            Binder.restoreCallingIdentity(origId);
6798        }
6799    }
6800
6801    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6802        ContentProviderConnection conn;
6803        try {
6804            conn = (ContentProviderConnection)connection;
6805        } catch (ClassCastException e) {
6806            String msg ="refContentProvider: " + connection
6807                    + " not a ContentProviderConnection";
6808            Slog.w(TAG, msg);
6809            throw new IllegalArgumentException(msg);
6810        }
6811        if (conn == null) {
6812            throw new NullPointerException("connection is null");
6813        }
6814
6815        synchronized (this) {
6816            if (stable > 0) {
6817                conn.numStableIncs += stable;
6818            }
6819            stable = conn.stableCount + stable;
6820            if (stable < 0) {
6821                throw new IllegalStateException("stableCount < 0: " + stable);
6822            }
6823
6824            if (unstable > 0) {
6825                conn.numUnstableIncs += unstable;
6826            }
6827            unstable = conn.unstableCount + unstable;
6828            if (unstable < 0) {
6829                throw new IllegalStateException("unstableCount < 0: " + unstable);
6830            }
6831
6832            if ((stable+unstable) <= 0) {
6833                throw new IllegalStateException("ref counts can't go to zero here: stable="
6834                        + stable + " unstable=" + unstable);
6835            }
6836            conn.stableCount = stable;
6837            conn.unstableCount = unstable;
6838            return !conn.dead;
6839        }
6840    }
6841
6842    public void unstableProviderDied(IBinder connection) {
6843        ContentProviderConnection conn;
6844        try {
6845            conn = (ContentProviderConnection)connection;
6846        } catch (ClassCastException e) {
6847            String msg ="refContentProvider: " + connection
6848                    + " not a ContentProviderConnection";
6849            Slog.w(TAG, msg);
6850            throw new IllegalArgumentException(msg);
6851        }
6852        if (conn == null) {
6853            throw new NullPointerException("connection is null");
6854        }
6855
6856        // Safely retrieve the content provider associated with the connection.
6857        IContentProvider provider;
6858        synchronized (this) {
6859            provider = conn.provider.provider;
6860        }
6861
6862        if (provider == null) {
6863            // Um, yeah, we're way ahead of you.
6864            return;
6865        }
6866
6867        // Make sure the caller is being honest with us.
6868        if (provider.asBinder().pingBinder()) {
6869            // Er, no, still looks good to us.
6870            synchronized (this) {
6871                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6872                        + " says " + conn + " died, but we don't agree");
6873                return;
6874            }
6875        }
6876
6877        // Well look at that!  It's dead!
6878        synchronized (this) {
6879            if (conn.provider.provider != provider) {
6880                // But something changed...  good enough.
6881                return;
6882            }
6883
6884            ProcessRecord proc = conn.provider.proc;
6885            if (proc == null || proc.thread == null) {
6886                // Seems like the process is already cleaned up.
6887                return;
6888            }
6889
6890            // As far as we're concerned, this is just like receiving a
6891            // death notification...  just a bit prematurely.
6892            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6893                    + ") early provider death");
6894            final long ident = Binder.clearCallingIdentity();
6895            try {
6896                appDiedLocked(proc, proc.pid, proc.thread);
6897            } finally {
6898                Binder.restoreCallingIdentity(ident);
6899            }
6900        }
6901    }
6902
6903    public static final void installSystemProviders() {
6904        List<ProviderInfo> providers;
6905        synchronized (mSelf) {
6906            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6907            providers = mSelf.generateApplicationProvidersLocked(app);
6908            if (providers != null) {
6909                for (int i=providers.size()-1; i>=0; i--) {
6910                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6911                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6912                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6913                                + ": not system .apk");
6914                        providers.remove(i);
6915                    }
6916                }
6917            }
6918        }
6919        if (providers != null) {
6920            mSystemThread.installSystemProviders(providers);
6921        }
6922
6923        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6924
6925        mSelf.mUsageStatsService.monitorPackages();
6926    }
6927
6928    /**
6929     * Allows app to retrieve the MIME type of a URI without having permission
6930     * to access its content provider.
6931     *
6932     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6933     *
6934     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6935     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6936     */
6937    public String getProviderMimeType(Uri uri, int userId) {
6938        enforceNotIsolatedCaller("getProviderMimeType");
6939        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6940                userId, false, true, "getProviderMimeType", null);
6941        final String name = uri.getAuthority();
6942        final long ident = Binder.clearCallingIdentity();
6943        ContentProviderHolder holder = null;
6944
6945        try {
6946            holder = getContentProviderExternalUnchecked(name, null, userId);
6947            if (holder != null) {
6948                return holder.provider.getType(uri);
6949            }
6950        } catch (RemoteException e) {
6951            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6952            return null;
6953        } finally {
6954            if (holder != null) {
6955                removeContentProviderExternalUnchecked(name, null, userId);
6956            }
6957            Binder.restoreCallingIdentity(ident);
6958        }
6959
6960        return null;
6961    }
6962
6963    // =========================================================
6964    // GLOBAL MANAGEMENT
6965    // =========================================================
6966
6967    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6968            ApplicationInfo info, String customProcess, boolean isolated) {
6969        String proc = customProcess != null ? customProcess : info.processName;
6970        BatteryStatsImpl.Uid.Proc ps = null;
6971        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6972        int uid = info.uid;
6973        if (isolated) {
6974            int userId = UserHandle.getUserId(uid);
6975            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6976            uid = 0;
6977            while (true) {
6978                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6979                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6980                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6981                }
6982                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6983                mNextIsolatedProcessUid++;
6984                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6985                    // No process for this uid, use it.
6986                    break;
6987                }
6988                stepsLeft--;
6989                if (stepsLeft <= 0) {
6990                    return null;
6991                }
6992            }
6993        }
6994        synchronized (stats) {
6995            ps = stats.getProcessStatsLocked(info.uid, proc);
6996        }
6997        return new ProcessRecord(ps, thread, info, proc, uid);
6998    }
6999
7000    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7001        ProcessRecord app;
7002        if (!isolated) {
7003            app = getProcessRecordLocked(info.processName, info.uid);
7004        } else {
7005            app = null;
7006        }
7007
7008        if (app == null) {
7009            app = newProcessRecordLocked(null, info, null, isolated);
7010            mProcessNames.put(info.processName, app.uid, app);
7011            if (isolated) {
7012                mIsolatedProcesses.put(app.uid, app);
7013            }
7014            updateLruProcessLocked(app, true);
7015        }
7016
7017        // This package really, really can not be stopped.
7018        try {
7019            AppGlobals.getPackageManager().setPackageStoppedState(
7020                    info.packageName, false, UserHandle.getUserId(app.uid));
7021        } catch (RemoteException e) {
7022        } catch (IllegalArgumentException e) {
7023            Slog.w(TAG, "Failed trying to unstop package "
7024                    + info.packageName + ": " + e);
7025        }
7026
7027        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7028                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7029            app.persistent = true;
7030            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7031        }
7032        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7033            mPersistentStartingProcesses.add(app);
7034            startProcessLocked(app, "added application", app.processName);
7035        }
7036
7037        return app;
7038    }
7039
7040    public void unhandledBack() {
7041        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7042                "unhandledBack()");
7043
7044        synchronized(this) {
7045            int count = mMainStack.mHistory.size();
7046            if (DEBUG_SWITCH) Slog.d(
7047                TAG, "Performing unhandledBack(): stack size = " + count);
7048            if (count > 1) {
7049                final long origId = Binder.clearCallingIdentity();
7050                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7051                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7052                Binder.restoreCallingIdentity(origId);
7053            }
7054        }
7055    }
7056
7057    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7058        enforceNotIsolatedCaller("openContentUri");
7059        final int userId = UserHandle.getCallingUserId();
7060        String name = uri.getAuthority();
7061        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7062        ParcelFileDescriptor pfd = null;
7063        if (cph != null) {
7064            // We record the binder invoker's uid in thread-local storage before
7065            // going to the content provider to open the file.  Later, in the code
7066            // that handles all permissions checks, we look for this uid and use
7067            // that rather than the Activity Manager's own uid.  The effect is that
7068            // we do the check against the caller's permissions even though it looks
7069            // to the content provider like the Activity Manager itself is making
7070            // the request.
7071            sCallerIdentity.set(new Identity(
7072                    Binder.getCallingPid(), Binder.getCallingUid()));
7073            try {
7074                pfd = cph.provider.openFile(uri, "r");
7075            } catch (FileNotFoundException e) {
7076                // do nothing; pfd will be returned null
7077            } finally {
7078                // Ensure that whatever happens, we clean up the identity state
7079                sCallerIdentity.remove();
7080            }
7081
7082            // We've got the fd now, so we're done with the provider.
7083            removeContentProviderExternalUnchecked(name, null, userId);
7084        } else {
7085            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7086        }
7087        return pfd;
7088    }
7089
7090    // Actually is sleeping or shutting down or whatever else in the future
7091    // is an inactive state.
7092    public boolean isSleeping() {
7093        return mSleeping || mShuttingDown;
7094    }
7095
7096    public void goingToSleep() {
7097        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7098                != PackageManager.PERMISSION_GRANTED) {
7099            throw new SecurityException("Requires permission "
7100                    + android.Manifest.permission.DEVICE_POWER);
7101        }
7102
7103        synchronized(this) {
7104            mWentToSleep = true;
7105            updateEventDispatchingLocked();
7106
7107            if (!mSleeping) {
7108                mSleeping = true;
7109                mMainStack.stopIfSleepingLocked();
7110
7111                // Initialize the wake times of all processes.
7112                checkExcessivePowerUsageLocked(false);
7113                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7114                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7115                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7116            }
7117        }
7118    }
7119
7120    public boolean shutdown(int timeout) {
7121        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7122                != PackageManager.PERMISSION_GRANTED) {
7123            throw new SecurityException("Requires permission "
7124                    + android.Manifest.permission.SHUTDOWN);
7125        }
7126
7127        boolean timedout = false;
7128
7129        synchronized(this) {
7130            mShuttingDown = true;
7131            updateEventDispatchingLocked();
7132
7133            if (mMainStack.mResumedActivity != null) {
7134                mMainStack.stopIfSleepingLocked();
7135                final long endTime = System.currentTimeMillis() + timeout;
7136                while (mMainStack.mResumedActivity != null
7137                        || mMainStack.mPausingActivity != null) {
7138                    long delay = endTime - System.currentTimeMillis();
7139                    if (delay <= 0) {
7140                        Slog.w(TAG, "Activity manager shutdown timed out");
7141                        timedout = true;
7142                        break;
7143                    }
7144                    try {
7145                        this.wait();
7146                    } catch (InterruptedException e) {
7147                    }
7148                }
7149            }
7150        }
7151
7152        mUsageStatsService.shutdown();
7153        mBatteryStatsService.shutdown();
7154
7155        return timedout;
7156    }
7157
7158    public final void activitySlept(IBinder token) {
7159        if (localLOGV) Slog.v(
7160            TAG, "Activity slept: token=" + token);
7161
7162        ActivityRecord r = null;
7163
7164        final long origId = Binder.clearCallingIdentity();
7165
7166        synchronized (this) {
7167            r = mMainStack.isInStackLocked(token);
7168            if (r != null) {
7169                mMainStack.activitySleptLocked(r);
7170            }
7171        }
7172
7173        Binder.restoreCallingIdentity(origId);
7174    }
7175
7176    private void comeOutOfSleepIfNeededLocked() {
7177        if (!mWentToSleep && !mLockScreenShown) {
7178            if (mSleeping) {
7179                mSleeping = false;
7180                mMainStack.awakeFromSleepingLocked();
7181                mMainStack.resumeTopActivityLocked(null);
7182            }
7183        }
7184    }
7185
7186    public void wakingUp() {
7187        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7188                != PackageManager.PERMISSION_GRANTED) {
7189            throw new SecurityException("Requires permission "
7190                    + android.Manifest.permission.DEVICE_POWER);
7191        }
7192
7193        synchronized(this) {
7194            mWentToSleep = false;
7195            updateEventDispatchingLocked();
7196            comeOutOfSleepIfNeededLocked();
7197        }
7198    }
7199
7200    private void updateEventDispatchingLocked() {
7201        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7202    }
7203
7204    public void setLockScreenShown(boolean shown) {
7205        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7206                != PackageManager.PERMISSION_GRANTED) {
7207            throw new SecurityException("Requires permission "
7208                    + android.Manifest.permission.DEVICE_POWER);
7209        }
7210
7211        synchronized(this) {
7212            mLockScreenShown = shown;
7213            comeOutOfSleepIfNeededLocked();
7214        }
7215    }
7216
7217    public void stopAppSwitches() {
7218        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7219                != PackageManager.PERMISSION_GRANTED) {
7220            throw new SecurityException("Requires permission "
7221                    + android.Manifest.permission.STOP_APP_SWITCHES);
7222        }
7223
7224        synchronized(this) {
7225            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7226                    + APP_SWITCH_DELAY_TIME;
7227            mDidAppSwitch = false;
7228            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7229            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7230            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7231        }
7232    }
7233
7234    public void resumeAppSwitches() {
7235        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7236                != PackageManager.PERMISSION_GRANTED) {
7237            throw new SecurityException("Requires permission "
7238                    + android.Manifest.permission.STOP_APP_SWITCHES);
7239        }
7240
7241        synchronized(this) {
7242            // Note that we don't execute any pending app switches... we will
7243            // let those wait until either the timeout, or the next start
7244            // activity request.
7245            mAppSwitchesAllowedTime = 0;
7246        }
7247    }
7248
7249    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7250            String name) {
7251        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7252            return true;
7253        }
7254
7255        final int perm = checkComponentPermission(
7256                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7257                callingUid, -1, true);
7258        if (perm == PackageManager.PERMISSION_GRANTED) {
7259            return true;
7260        }
7261
7262        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7263        return false;
7264    }
7265
7266    public void setDebugApp(String packageName, boolean waitForDebugger,
7267            boolean persistent) {
7268        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7269                "setDebugApp()");
7270
7271        // Note that this is not really thread safe if there are multiple
7272        // callers into it at the same time, but that's not a situation we
7273        // care about.
7274        if (persistent) {
7275            final ContentResolver resolver = mContext.getContentResolver();
7276            Settings.System.putString(
7277                resolver, Settings.System.DEBUG_APP,
7278                packageName);
7279            Settings.System.putInt(
7280                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7281                waitForDebugger ? 1 : 0);
7282        }
7283
7284        synchronized (this) {
7285            if (!persistent) {
7286                mOrigDebugApp = mDebugApp;
7287                mOrigWaitForDebugger = mWaitForDebugger;
7288            }
7289            mDebugApp = packageName;
7290            mWaitForDebugger = waitForDebugger;
7291            mDebugTransient = !persistent;
7292            if (packageName != null) {
7293                final long origId = Binder.clearCallingIdentity();
7294                forceStopPackageLocked(packageName, -1, false, false, true, true,
7295                        UserHandle.USER_ALL);
7296                Binder.restoreCallingIdentity(origId);
7297            }
7298        }
7299    }
7300
7301    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7302        synchronized (this) {
7303            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7304            if (!isDebuggable) {
7305                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7306                    throw new SecurityException("Process not debuggable: " + app.packageName);
7307                }
7308            }
7309
7310            mOpenGlTraceApp = processName;
7311        }
7312    }
7313
7314    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7315            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7316        synchronized (this) {
7317            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7318            if (!isDebuggable) {
7319                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7320                    throw new SecurityException("Process not debuggable: " + app.packageName);
7321                }
7322            }
7323            mProfileApp = processName;
7324            mProfileFile = profileFile;
7325            if (mProfileFd != null) {
7326                try {
7327                    mProfileFd.close();
7328                } catch (IOException e) {
7329                }
7330                mProfileFd = null;
7331            }
7332            mProfileFd = profileFd;
7333            mProfileType = 0;
7334            mAutoStopProfiler = autoStopProfiler;
7335        }
7336    }
7337
7338    public void setAlwaysFinish(boolean enabled) {
7339        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7340                "setAlwaysFinish()");
7341
7342        Settings.System.putInt(
7343                mContext.getContentResolver(),
7344                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7345
7346        synchronized (this) {
7347            mAlwaysFinishActivities = enabled;
7348        }
7349    }
7350
7351    public void setActivityController(IActivityController controller) {
7352        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7353                "setActivityController()");
7354        synchronized (this) {
7355            mController = controller;
7356        }
7357    }
7358
7359    public boolean isUserAMonkey() {
7360        // For now the fact that there is a controller implies
7361        // we have a monkey.
7362        synchronized (this) {
7363            return mController != null;
7364        }
7365    }
7366
7367    public void registerProcessObserver(IProcessObserver observer) {
7368        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7369                "registerProcessObserver()");
7370        synchronized (this) {
7371            mProcessObservers.register(observer);
7372        }
7373    }
7374
7375    public void unregisterProcessObserver(IProcessObserver observer) {
7376        synchronized (this) {
7377            mProcessObservers.unregister(observer);
7378        }
7379    }
7380
7381    public void setImmersive(IBinder token, boolean immersive) {
7382        synchronized(this) {
7383            ActivityRecord r = mMainStack.isInStackLocked(token);
7384            if (r == null) {
7385                throw new IllegalArgumentException();
7386            }
7387            r.immersive = immersive;
7388        }
7389    }
7390
7391    public boolean isImmersive(IBinder token) {
7392        synchronized (this) {
7393            ActivityRecord r = mMainStack.isInStackLocked(token);
7394            if (r == null) {
7395                throw new IllegalArgumentException();
7396            }
7397            return r.immersive;
7398        }
7399    }
7400
7401    public boolean isTopActivityImmersive() {
7402        enforceNotIsolatedCaller("startActivity");
7403        synchronized (this) {
7404            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7405            return (r != null) ? r.immersive : false;
7406        }
7407    }
7408
7409    public final void enterSafeMode() {
7410        synchronized(this) {
7411            // It only makes sense to do this before the system is ready
7412            // and started launching other packages.
7413            if (!mSystemReady) {
7414                try {
7415                    AppGlobals.getPackageManager().enterSafeMode();
7416                } catch (RemoteException e) {
7417                }
7418            }
7419        }
7420    }
7421
7422    public final void showSafeModeOverlay() {
7423        View v = LayoutInflater.from(mContext).inflate(
7424                com.android.internal.R.layout.safe_mode, null);
7425        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7426        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7427        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7428        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7429        lp.gravity = Gravity.BOTTOM | Gravity.START;
7430        lp.format = v.getBackground().getOpacity();
7431        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7432                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7433        ((WindowManager)mContext.getSystemService(
7434                Context.WINDOW_SERVICE)).addView(v, lp);
7435    }
7436
7437    public void noteWakeupAlarm(IIntentSender sender) {
7438        if (!(sender instanceof PendingIntentRecord)) {
7439            return;
7440        }
7441        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7442        synchronized (stats) {
7443            if (mBatteryStatsService.isOnBattery()) {
7444                mBatteryStatsService.enforceCallingPermission();
7445                PendingIntentRecord rec = (PendingIntentRecord)sender;
7446                int MY_UID = Binder.getCallingUid();
7447                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7448                BatteryStatsImpl.Uid.Pkg pkg =
7449                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7450                pkg.incWakeupsLocked();
7451            }
7452        }
7453    }
7454
7455    public boolean killPids(int[] pids, String pReason, boolean secure) {
7456        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7457            throw new SecurityException("killPids only available to the system");
7458        }
7459        String reason = (pReason == null) ? "Unknown" : pReason;
7460        // XXX Note: don't acquire main activity lock here, because the window
7461        // manager calls in with its locks held.
7462
7463        boolean killed = false;
7464        synchronized (mPidsSelfLocked) {
7465            int[] types = new int[pids.length];
7466            int worstType = 0;
7467            for (int i=0; i<pids.length; i++) {
7468                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7469                if (proc != null) {
7470                    int type = proc.setAdj;
7471                    types[i] = type;
7472                    if (type > worstType) {
7473                        worstType = type;
7474                    }
7475                }
7476            }
7477
7478            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7479            // then constrain it so we will kill all hidden procs.
7480            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7481                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7482                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7483            }
7484
7485            // If this is not a secure call, don't let it kill processes that
7486            // are important.
7487            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7488                worstType = ProcessList.SERVICE_ADJ;
7489            }
7490
7491            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7492            for (int i=0; i<pids.length; i++) {
7493                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7494                if (proc == null) {
7495                    continue;
7496                }
7497                int adj = proc.setAdj;
7498                if (adj >= worstType && !proc.killedBackground) {
7499                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7500                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7501                            proc.processName, adj, reason);
7502                    killed = true;
7503                    proc.killedBackground = true;
7504                    Process.killProcessQuiet(pids[i]);
7505                }
7506            }
7507        }
7508        return killed;
7509    }
7510
7511    @Override
7512    public boolean killProcessesBelowForeground(String reason) {
7513        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7514            throw new SecurityException("killProcessesBelowForeground() only available to system");
7515        }
7516
7517        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7518    }
7519
7520    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7521        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7522            throw new SecurityException("killProcessesBelowAdj() only available to system");
7523        }
7524
7525        boolean killed = false;
7526        synchronized (mPidsSelfLocked) {
7527            final int size = mPidsSelfLocked.size();
7528            for (int i = 0; i < size; i++) {
7529                final int pid = mPidsSelfLocked.keyAt(i);
7530                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7531                if (proc == null) continue;
7532
7533                final int adj = proc.setAdj;
7534                if (adj > belowAdj && !proc.killedBackground) {
7535                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7536                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7537                            proc.pid, proc.processName, adj, reason);
7538                    killed = true;
7539                    proc.killedBackground = true;
7540                    Process.killProcessQuiet(pid);
7541                }
7542            }
7543        }
7544        return killed;
7545    }
7546
7547    public final void startRunning(String pkg, String cls, String action,
7548            String data) {
7549        synchronized(this) {
7550            if (mStartRunning) {
7551                return;
7552            }
7553            mStartRunning = true;
7554            mTopComponent = pkg != null && cls != null
7555                    ? new ComponentName(pkg, cls) : null;
7556            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7557            mTopData = data;
7558            if (!mSystemReady) {
7559                return;
7560            }
7561        }
7562
7563        systemReady(null);
7564    }
7565
7566    private void retrieveSettings() {
7567        final ContentResolver resolver = mContext.getContentResolver();
7568        String debugApp = Settings.System.getString(
7569            resolver, Settings.System.DEBUG_APP);
7570        boolean waitForDebugger = Settings.System.getInt(
7571            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7572        boolean alwaysFinishActivities = Settings.System.getInt(
7573            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7574
7575        Configuration configuration = new Configuration();
7576        Settings.System.getConfiguration(resolver, configuration);
7577
7578        synchronized (this) {
7579            mDebugApp = mOrigDebugApp = debugApp;
7580            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7581            mAlwaysFinishActivities = alwaysFinishActivities;
7582            // This happens before any activities are started, so we can
7583            // change mConfiguration in-place.
7584            updateConfigurationLocked(configuration, null, false, true);
7585            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7586        }
7587    }
7588
7589    public boolean testIsSystemReady() {
7590        // no need to synchronize(this) just to read & return the value
7591        return mSystemReady;
7592    }
7593
7594    private static File getCalledPreBootReceiversFile() {
7595        File dataDir = Environment.getDataDirectory();
7596        File systemDir = new File(dataDir, "system");
7597        File fname = new File(systemDir, "called_pre_boots.dat");
7598        return fname;
7599    }
7600
7601    static final int LAST_DONE_VERSION = 10000;
7602
7603    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7604        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7605        File file = getCalledPreBootReceiversFile();
7606        FileInputStream fis = null;
7607        try {
7608            fis = new FileInputStream(file);
7609            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7610            int fvers = dis.readInt();
7611            if (fvers == LAST_DONE_VERSION) {
7612                String vers = dis.readUTF();
7613                String codename = dis.readUTF();
7614                String build = dis.readUTF();
7615                if (android.os.Build.VERSION.RELEASE.equals(vers)
7616                        && android.os.Build.VERSION.CODENAME.equals(codename)
7617                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7618                    int num = dis.readInt();
7619                    while (num > 0) {
7620                        num--;
7621                        String pkg = dis.readUTF();
7622                        String cls = dis.readUTF();
7623                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7624                    }
7625                }
7626            }
7627        } catch (FileNotFoundException e) {
7628        } catch (IOException e) {
7629            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7630        } finally {
7631            if (fis != null) {
7632                try {
7633                    fis.close();
7634                } catch (IOException e) {
7635                }
7636            }
7637        }
7638        return lastDoneReceivers;
7639    }
7640
7641    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7642        File file = getCalledPreBootReceiversFile();
7643        FileOutputStream fos = null;
7644        DataOutputStream dos = null;
7645        try {
7646            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7647            fos = new FileOutputStream(file);
7648            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7649            dos.writeInt(LAST_DONE_VERSION);
7650            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7651            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7652            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7653            dos.writeInt(list.size());
7654            for (int i=0; i<list.size(); i++) {
7655                dos.writeUTF(list.get(i).getPackageName());
7656                dos.writeUTF(list.get(i).getClassName());
7657            }
7658        } catch (IOException e) {
7659            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7660            file.delete();
7661        } finally {
7662            FileUtils.sync(fos);
7663            if (dos != null) {
7664                try {
7665                    dos.close();
7666                } catch (IOException e) {
7667                    // TODO Auto-generated catch block
7668                    e.printStackTrace();
7669                }
7670            }
7671        }
7672    }
7673
7674    public void systemReady(final Runnable goingCallback) {
7675        synchronized(this) {
7676            if (mSystemReady) {
7677                if (goingCallback != null) goingCallback.run();
7678                return;
7679            }
7680
7681            // Check to see if there are any update receivers to run.
7682            if (!mDidUpdate) {
7683                if (mWaitingUpdate) {
7684                    return;
7685                }
7686                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7687                List<ResolveInfo> ris = null;
7688                try {
7689                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7690                            intent, null, 0, 0);
7691                } catch (RemoteException e) {
7692                }
7693                if (ris != null) {
7694                    for (int i=ris.size()-1; i>=0; i--) {
7695                        if ((ris.get(i).activityInfo.applicationInfo.flags
7696                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7697                            ris.remove(i);
7698                        }
7699                    }
7700                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7701
7702                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7703
7704                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7705                    for (int i=0; i<ris.size(); i++) {
7706                        ActivityInfo ai = ris.get(i).activityInfo;
7707                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7708                        if (lastDoneReceivers.contains(comp)) {
7709                            ris.remove(i);
7710                            i--;
7711                        }
7712                    }
7713
7714                    final int[] users = getUsersLocked();
7715                    for (int i=0; i<ris.size(); i++) {
7716                        ActivityInfo ai = ris.get(i).activityInfo;
7717                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7718                        doneReceivers.add(comp);
7719                        intent.setComponent(comp);
7720                        for (int j=0; j<users.length; j++) {
7721                            IIntentReceiver finisher = null;
7722                            if (i == ris.size()-1 && j == users.length-1) {
7723                                finisher = new IIntentReceiver.Stub() {
7724                                    public void performReceive(Intent intent, int resultCode,
7725                                            String data, Bundle extras, boolean ordered,
7726                                            boolean sticky, int sendingUser) {
7727                                        // The raw IIntentReceiver interface is called
7728                                        // with the AM lock held, so redispatch to
7729                                        // execute our code without the lock.
7730                                        mHandler.post(new Runnable() {
7731                                            public void run() {
7732                                                synchronized (ActivityManagerService.this) {
7733                                                    mDidUpdate = true;
7734                                                }
7735                                                writeLastDonePreBootReceivers(doneReceivers);
7736                                                showBootMessage(mContext.getText(
7737                                                        R.string.android_upgrading_complete),
7738                                                        false);
7739                                                systemReady(goingCallback);
7740                                            }
7741                                        });
7742                                    }
7743                                };
7744                            }
7745                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7746                                    + " for user " + users[j]);
7747                            broadcastIntentLocked(null, null, intent, null, finisher,
7748                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7749                                    users[j]);
7750                            if (finisher != null) {
7751                                mWaitingUpdate = true;
7752                            }
7753                        }
7754                    }
7755                }
7756                if (mWaitingUpdate) {
7757                    return;
7758                }
7759                mDidUpdate = true;
7760            }
7761
7762            mSystemReady = true;
7763            if (!mStartRunning) {
7764                return;
7765            }
7766        }
7767
7768        ArrayList<ProcessRecord> procsToKill = null;
7769        synchronized(mPidsSelfLocked) {
7770            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7771                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7772                if (!isAllowedWhileBooting(proc.info)){
7773                    if (procsToKill == null) {
7774                        procsToKill = new ArrayList<ProcessRecord>();
7775                    }
7776                    procsToKill.add(proc);
7777                }
7778            }
7779        }
7780
7781        synchronized(this) {
7782            if (procsToKill != null) {
7783                for (int i=procsToKill.size()-1; i>=0; i--) {
7784                    ProcessRecord proc = procsToKill.get(i);
7785                    Slog.i(TAG, "Removing system update proc: " + proc);
7786                    removeProcessLocked(proc, true, false, "system update done");
7787                }
7788            }
7789
7790            // Now that we have cleaned up any update processes, we
7791            // are ready to start launching real processes and know that
7792            // we won't trample on them any more.
7793            mProcessesReady = true;
7794        }
7795
7796        Slog.i(TAG, "System now ready");
7797        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7798            SystemClock.uptimeMillis());
7799
7800        synchronized(this) {
7801            // Make sure we have no pre-ready processes sitting around.
7802
7803            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7804                ResolveInfo ri = mContext.getPackageManager()
7805                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7806                                STOCK_PM_FLAGS);
7807                CharSequence errorMsg = null;
7808                if (ri != null) {
7809                    ActivityInfo ai = ri.activityInfo;
7810                    ApplicationInfo app = ai.applicationInfo;
7811                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7812                        mTopAction = Intent.ACTION_FACTORY_TEST;
7813                        mTopData = null;
7814                        mTopComponent = new ComponentName(app.packageName,
7815                                ai.name);
7816                    } else {
7817                        errorMsg = mContext.getResources().getText(
7818                                com.android.internal.R.string.factorytest_not_system);
7819                    }
7820                } else {
7821                    errorMsg = mContext.getResources().getText(
7822                            com.android.internal.R.string.factorytest_no_action);
7823                }
7824                if (errorMsg != null) {
7825                    mTopAction = null;
7826                    mTopData = null;
7827                    mTopComponent = null;
7828                    Message msg = Message.obtain();
7829                    msg.what = SHOW_FACTORY_ERROR_MSG;
7830                    msg.getData().putCharSequence("msg", errorMsg);
7831                    mHandler.sendMessage(msg);
7832                }
7833            }
7834        }
7835
7836        retrieveSettings();
7837
7838        if (goingCallback != null) goingCallback.run();
7839
7840        synchronized (this) {
7841            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7842                try {
7843                    List apps = AppGlobals.getPackageManager().
7844                        getPersistentApplications(STOCK_PM_FLAGS);
7845                    if (apps != null) {
7846                        int N = apps.size();
7847                        int i;
7848                        for (i=0; i<N; i++) {
7849                            ApplicationInfo info
7850                                = (ApplicationInfo)apps.get(i);
7851                            if (info != null &&
7852                                    !info.packageName.equals("android")) {
7853                                addAppLocked(info, false);
7854                            }
7855                        }
7856                    }
7857                } catch (RemoteException ex) {
7858                    // pm is in same process, this will never happen.
7859                }
7860            }
7861
7862            // Start up initial activity.
7863            mBooting = true;
7864
7865            try {
7866                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7867                    Message msg = Message.obtain();
7868                    msg.what = SHOW_UID_ERROR_MSG;
7869                    mHandler.sendMessage(msg);
7870                }
7871            } catch (RemoteException e) {
7872            }
7873
7874            long ident = Binder.clearCallingIdentity();
7875            try {
7876                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7877                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7878                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7879                broadcastIntentLocked(null, null, intent,
7880                        null, null, 0, null, null, null,
7881                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7882            } finally {
7883                Binder.restoreCallingIdentity(ident);
7884            }
7885            mMainStack.resumeTopActivityLocked(null);
7886            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7887        }
7888    }
7889
7890    private boolean makeAppCrashingLocked(ProcessRecord app,
7891            String shortMsg, String longMsg, String stackTrace) {
7892        app.crashing = true;
7893        app.crashingReport = generateProcessError(app,
7894                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7895        startAppProblemLocked(app);
7896        app.stopFreezingAllLocked();
7897        return handleAppCrashLocked(app);
7898    }
7899
7900    private void makeAppNotRespondingLocked(ProcessRecord app,
7901            String activity, String shortMsg, String longMsg) {
7902        app.notResponding = true;
7903        app.notRespondingReport = generateProcessError(app,
7904                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7905                activity, shortMsg, longMsg, null);
7906        startAppProblemLocked(app);
7907        app.stopFreezingAllLocked();
7908    }
7909
7910    /**
7911     * Generate a process error record, suitable for attachment to a ProcessRecord.
7912     *
7913     * @param app The ProcessRecord in which the error occurred.
7914     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7915     *                      ActivityManager.AppErrorStateInfo
7916     * @param activity The activity associated with the crash, if known.
7917     * @param shortMsg Short message describing the crash.
7918     * @param longMsg Long message describing the crash.
7919     * @param stackTrace Full crash stack trace, may be null.
7920     *
7921     * @return Returns a fully-formed AppErrorStateInfo record.
7922     */
7923    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7924            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7925        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7926
7927        report.condition = condition;
7928        report.processName = app.processName;
7929        report.pid = app.pid;
7930        report.uid = app.info.uid;
7931        report.tag = activity;
7932        report.shortMsg = shortMsg;
7933        report.longMsg = longMsg;
7934        report.stackTrace = stackTrace;
7935
7936        return report;
7937    }
7938
7939    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7940        synchronized (this) {
7941            app.crashing = false;
7942            app.crashingReport = null;
7943            app.notResponding = false;
7944            app.notRespondingReport = null;
7945            if (app.anrDialog == fromDialog) {
7946                app.anrDialog = null;
7947            }
7948            if (app.waitDialog == fromDialog) {
7949                app.waitDialog = null;
7950            }
7951            if (app.pid > 0 && app.pid != MY_PID) {
7952                handleAppCrashLocked(app);
7953                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7954                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
7955                        app.processName, app.setAdj, "user's request after error");
7956                Process.killProcessQuiet(app.pid);
7957            }
7958        }
7959    }
7960
7961    private boolean handleAppCrashLocked(ProcessRecord app) {
7962        if (mHeadless) {
7963            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7964            return false;
7965        }
7966        long now = SystemClock.uptimeMillis();
7967
7968        Long crashTime;
7969        if (!app.isolated) {
7970            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7971        } else {
7972            crashTime = null;
7973        }
7974        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7975            // This process loses!
7976            Slog.w(TAG, "Process " + app.info.processName
7977                    + " has crashed too many times: killing!");
7978            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7979                    app.userId, app.info.processName, app.uid);
7980            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7981                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7982                if (r.app == app) {
7983                    Slog.w(TAG, "  Force finishing activity "
7984                        + r.intent.getComponent().flattenToShortString());
7985                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7986                            null, "crashed", false);
7987                }
7988            }
7989            if (!app.persistent) {
7990                // We don't want to start this process again until the user
7991                // explicitly does so...  but for persistent process, we really
7992                // need to keep it running.  If a persistent process is actually
7993                // repeatedly crashing, then badness for everyone.
7994                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
7995                        app.info.processName);
7996                if (!app.isolated) {
7997                    // XXX We don't have a way to mark isolated processes
7998                    // as bad, since they don't have a peristent identity.
7999                    mBadProcesses.put(app.info.processName, app.uid, now);
8000                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8001                }
8002                app.bad = true;
8003                app.removed = true;
8004                // Don't let services in this process be restarted and potentially
8005                // annoy the user repeatedly.  Unless it is persistent, since those
8006                // processes run critical code.
8007                removeProcessLocked(app, false, false, "crash");
8008                mMainStack.resumeTopActivityLocked(null);
8009                return false;
8010            }
8011            mMainStack.resumeTopActivityLocked(null);
8012        } else {
8013            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8014            if (r != null && r.app == app) {
8015                // If the top running activity is from this crashing
8016                // process, then terminate it to avoid getting in a loop.
8017                Slog.w(TAG, "  Force finishing activity "
8018                        + r.intent.getComponent().flattenToShortString());
8019                int index = mMainStack.indexOfActivityLocked(r);
8020                r.stack.finishActivityLocked(r, index,
8021                        Activity.RESULT_CANCELED, null, "crashed", false);
8022                // Also terminate any activities below it that aren't yet
8023                // stopped, to avoid a situation where one will get
8024                // re-start our crashing activity once it gets resumed again.
8025                index--;
8026                if (index >= 0) {
8027                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8028                    if (r.state == ActivityState.RESUMED
8029                            || r.state == ActivityState.PAUSING
8030                            || r.state == ActivityState.PAUSED) {
8031                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8032                            Slog.w(TAG, "  Force finishing activity "
8033                                    + r.intent.getComponent().flattenToShortString());
8034                            r.stack.finishActivityLocked(r, index,
8035                                    Activity.RESULT_CANCELED, null, "crashed", false);
8036                        }
8037                    }
8038                }
8039            }
8040        }
8041
8042        // Bump up the crash count of any services currently running in the proc.
8043        if (app.services.size() != 0) {
8044            // Any services running in the application need to be placed
8045            // back in the pending list.
8046            Iterator<ServiceRecord> it = app.services.iterator();
8047            while (it.hasNext()) {
8048                ServiceRecord sr = it.next();
8049                sr.crashCount++;
8050            }
8051        }
8052
8053        // If the crashing process is what we consider to be the "home process" and it has been
8054        // replaced by a third-party app, clear the package preferred activities from packages
8055        // with a home activity running in the process to prevent a repeatedly crashing app
8056        // from blocking the user to manually clear the list.
8057        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8058                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8059            Iterator it = mHomeProcess.activities.iterator();
8060            while (it.hasNext()) {
8061                ActivityRecord r = (ActivityRecord)it.next();
8062                if (r.isHomeActivity) {
8063                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8064                    try {
8065                        ActivityThread.getPackageManager()
8066                                .clearPackagePreferredActivities(r.packageName);
8067                    } catch (RemoteException c) {
8068                        // pm is in same process, this will never happen.
8069                    }
8070                }
8071            }
8072        }
8073
8074        if (!app.isolated) {
8075            // XXX Can't keep track of crash times for isolated processes,
8076            // because they don't have a perisistent identity.
8077            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8078        }
8079
8080        return true;
8081    }
8082
8083    void startAppProblemLocked(ProcessRecord app) {
8084        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8085                mContext, app.info.packageName, app.info.flags);
8086        skipCurrentReceiverLocked(app);
8087    }
8088
8089    void skipCurrentReceiverLocked(ProcessRecord app) {
8090        for (BroadcastQueue queue : mBroadcastQueues) {
8091            queue.skipCurrentReceiverLocked(app);
8092        }
8093    }
8094
8095    /**
8096     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8097     * The application process will exit immediately after this call returns.
8098     * @param app object of the crashing app, null for the system server
8099     * @param crashInfo describing the exception
8100     */
8101    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8102        ProcessRecord r = findAppProcess(app, "Crash");
8103        final String processName = app == null ? "system_server"
8104                : (r == null ? "unknown" : r.processName);
8105
8106        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8107                UserHandle.getUserId(Binder.getCallingUid()), processName,
8108                r == null ? -1 : r.info.flags,
8109                crashInfo.exceptionClassName,
8110                crashInfo.exceptionMessage,
8111                crashInfo.throwFileName,
8112                crashInfo.throwLineNumber);
8113
8114        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8115
8116        crashApplication(r, crashInfo);
8117    }
8118
8119    public void handleApplicationStrictModeViolation(
8120            IBinder app,
8121            int violationMask,
8122            StrictMode.ViolationInfo info) {
8123        ProcessRecord r = findAppProcess(app, "StrictMode");
8124        if (r == null) {
8125            return;
8126        }
8127
8128        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8129            Integer stackFingerprint = info.hashCode();
8130            boolean logIt = true;
8131            synchronized (mAlreadyLoggedViolatedStacks) {
8132                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8133                    logIt = false;
8134                    // TODO: sub-sample into EventLog for these, with
8135                    // the info.durationMillis?  Then we'd get
8136                    // the relative pain numbers, without logging all
8137                    // the stack traces repeatedly.  We'd want to do
8138                    // likewise in the client code, which also does
8139                    // dup suppression, before the Binder call.
8140                } else {
8141                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8142                        mAlreadyLoggedViolatedStacks.clear();
8143                    }
8144                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8145                }
8146            }
8147            if (logIt) {
8148                logStrictModeViolationToDropBox(r, info);
8149            }
8150        }
8151
8152        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8153            AppErrorResult result = new AppErrorResult();
8154            synchronized (this) {
8155                final long origId = Binder.clearCallingIdentity();
8156
8157                Message msg = Message.obtain();
8158                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8159                HashMap<String, Object> data = new HashMap<String, Object>();
8160                data.put("result", result);
8161                data.put("app", r);
8162                data.put("violationMask", violationMask);
8163                data.put("info", info);
8164                msg.obj = data;
8165                mHandler.sendMessage(msg);
8166
8167                Binder.restoreCallingIdentity(origId);
8168            }
8169            int res = result.get();
8170            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8171        }
8172    }
8173
8174    // Depending on the policy in effect, there could be a bunch of
8175    // these in quick succession so we try to batch these together to
8176    // minimize disk writes, number of dropbox entries, and maximize
8177    // compression, by having more fewer, larger records.
8178    private void logStrictModeViolationToDropBox(
8179            ProcessRecord process,
8180            StrictMode.ViolationInfo info) {
8181        if (info == null) {
8182            return;
8183        }
8184        final boolean isSystemApp = process == null ||
8185                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8186                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8187        final String processName = process == null ? "unknown" : process.processName;
8188        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8189        final DropBoxManager dbox = (DropBoxManager)
8190                mContext.getSystemService(Context.DROPBOX_SERVICE);
8191
8192        // Exit early if the dropbox isn't configured to accept this report type.
8193        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8194
8195        boolean bufferWasEmpty;
8196        boolean needsFlush;
8197        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8198        synchronized (sb) {
8199            bufferWasEmpty = sb.length() == 0;
8200            appendDropBoxProcessHeaders(process, processName, sb);
8201            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8202            sb.append("System-App: ").append(isSystemApp).append("\n");
8203            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8204            if (info.violationNumThisLoop != 0) {
8205                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8206            }
8207            if (info.numAnimationsRunning != 0) {
8208                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8209            }
8210            if (info.broadcastIntentAction != null) {
8211                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8212            }
8213            if (info.durationMillis != -1) {
8214                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8215            }
8216            if (info.numInstances != -1) {
8217                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8218            }
8219            if (info.tags != null) {
8220                for (String tag : info.tags) {
8221                    sb.append("Span-Tag: ").append(tag).append("\n");
8222                }
8223            }
8224            sb.append("\n");
8225            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8226                sb.append(info.crashInfo.stackTrace);
8227            }
8228            sb.append("\n");
8229
8230            // Only buffer up to ~64k.  Various logging bits truncate
8231            // things at 128k.
8232            needsFlush = (sb.length() > 64 * 1024);
8233        }
8234
8235        // Flush immediately if the buffer's grown too large, or this
8236        // is a non-system app.  Non-system apps are isolated with a
8237        // different tag & policy and not batched.
8238        //
8239        // Batching is useful during internal testing with
8240        // StrictMode settings turned up high.  Without batching,
8241        // thousands of separate files could be created on boot.
8242        if (!isSystemApp || needsFlush) {
8243            new Thread("Error dump: " + dropboxTag) {
8244                @Override
8245                public void run() {
8246                    String report;
8247                    synchronized (sb) {
8248                        report = sb.toString();
8249                        sb.delete(0, sb.length());
8250                        sb.trimToSize();
8251                    }
8252                    if (report.length() != 0) {
8253                        dbox.addText(dropboxTag, report);
8254                    }
8255                }
8256            }.start();
8257            return;
8258        }
8259
8260        // System app batching:
8261        if (!bufferWasEmpty) {
8262            // An existing dropbox-writing thread is outstanding, so
8263            // we don't need to start it up.  The existing thread will
8264            // catch the buffer appends we just did.
8265            return;
8266        }
8267
8268        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8269        // (After this point, we shouldn't access AMS internal data structures.)
8270        new Thread("Error dump: " + dropboxTag) {
8271            @Override
8272            public void run() {
8273                // 5 second sleep to let stacks arrive and be batched together
8274                try {
8275                    Thread.sleep(5000);  // 5 seconds
8276                } catch (InterruptedException e) {}
8277
8278                String errorReport;
8279                synchronized (mStrictModeBuffer) {
8280                    errorReport = mStrictModeBuffer.toString();
8281                    if (errorReport.length() == 0) {
8282                        return;
8283                    }
8284                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8285                    mStrictModeBuffer.trimToSize();
8286                }
8287                dbox.addText(dropboxTag, errorReport);
8288            }
8289        }.start();
8290    }
8291
8292    /**
8293     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8294     * @param app object of the crashing app, null for the system server
8295     * @param tag reported by the caller
8296     * @param crashInfo describing the context of the error
8297     * @return true if the process should exit immediately (WTF is fatal)
8298     */
8299    public boolean handleApplicationWtf(IBinder app, String tag,
8300            ApplicationErrorReport.CrashInfo crashInfo) {
8301        ProcessRecord r = findAppProcess(app, "WTF");
8302        final String processName = app == null ? "system_server"
8303                : (r == null ? "unknown" : r.processName);
8304
8305        EventLog.writeEvent(EventLogTags.AM_WTF,
8306                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8307                processName,
8308                r == null ? -1 : r.info.flags,
8309                tag, crashInfo.exceptionMessage);
8310
8311        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8312
8313        if (r != null && r.pid != Process.myPid() &&
8314                Settings.Global.getInt(mContext.getContentResolver(),
8315                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8316            crashApplication(r, crashInfo);
8317            return true;
8318        } else {
8319            return false;
8320        }
8321    }
8322
8323    /**
8324     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8325     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8326     */
8327    private ProcessRecord findAppProcess(IBinder app, String reason) {
8328        if (app == null) {
8329            return null;
8330        }
8331
8332        synchronized (this) {
8333            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8334                final int NA = apps.size();
8335                for (int ia=0; ia<NA; ia++) {
8336                    ProcessRecord p = apps.valueAt(ia);
8337                    if (p.thread != null && p.thread.asBinder() == app) {
8338                        return p;
8339                    }
8340                }
8341            }
8342
8343            Slog.w(TAG, "Can't find mystery application for " + reason
8344                    + " from pid=" + Binder.getCallingPid()
8345                    + " uid=" + Binder.getCallingUid() + ": " + app);
8346            return null;
8347        }
8348    }
8349
8350    /**
8351     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8352     * to append various headers to the dropbox log text.
8353     */
8354    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8355            StringBuilder sb) {
8356        // Watchdog thread ends up invoking this function (with
8357        // a null ProcessRecord) to add the stack file to dropbox.
8358        // Do not acquire a lock on this (am) in such cases, as it
8359        // could cause a potential deadlock, if and when watchdog
8360        // is invoked due to unavailability of lock on am and it
8361        // would prevent watchdog from killing system_server.
8362        if (process == null) {
8363            sb.append("Process: ").append(processName).append("\n");
8364            return;
8365        }
8366        // Note: ProcessRecord 'process' is guarded by the service
8367        // instance.  (notably process.pkgList, which could otherwise change
8368        // concurrently during execution of this method)
8369        synchronized (this) {
8370            sb.append("Process: ").append(processName).append("\n");
8371            int flags = process.info.flags;
8372            IPackageManager pm = AppGlobals.getPackageManager();
8373            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8374            for (String pkg : process.pkgList) {
8375                sb.append("Package: ").append(pkg);
8376                try {
8377                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8378                    if (pi != null) {
8379                        sb.append(" v").append(pi.versionCode);
8380                        if (pi.versionName != null) {
8381                            sb.append(" (").append(pi.versionName).append(")");
8382                        }
8383                    }
8384                } catch (RemoteException e) {
8385                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8386                }
8387                sb.append("\n");
8388            }
8389        }
8390    }
8391
8392    private static String processClass(ProcessRecord process) {
8393        if (process == null || process.pid == MY_PID) {
8394            return "system_server";
8395        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8396            return "system_app";
8397        } else {
8398            return "data_app";
8399        }
8400    }
8401
8402    /**
8403     * Write a description of an error (crash, WTF, ANR) to the drop box.
8404     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8405     * @param process which caused the error, null means the system server
8406     * @param activity which triggered the error, null if unknown
8407     * @param parent activity related to the error, null if unknown
8408     * @param subject line related to the error, null if absent
8409     * @param report in long form describing the error, null if absent
8410     * @param logFile to include in the report, null if none
8411     * @param crashInfo giving an application stack trace, null if absent
8412     */
8413    public void addErrorToDropBox(String eventType,
8414            ProcessRecord process, String processName, ActivityRecord activity,
8415            ActivityRecord parent, String subject,
8416            final String report, final File logFile,
8417            final ApplicationErrorReport.CrashInfo crashInfo) {
8418        // NOTE -- this must never acquire the ActivityManagerService lock,
8419        // otherwise the watchdog may be prevented from resetting the system.
8420
8421        final String dropboxTag = processClass(process) + "_" + eventType;
8422        final DropBoxManager dbox = (DropBoxManager)
8423                mContext.getSystemService(Context.DROPBOX_SERVICE);
8424
8425        // Exit early if the dropbox isn't configured to accept this report type.
8426        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8427
8428        final StringBuilder sb = new StringBuilder(1024);
8429        appendDropBoxProcessHeaders(process, processName, sb);
8430        if (activity != null) {
8431            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8432        }
8433        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8434            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8435        }
8436        if (parent != null && parent != activity) {
8437            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8438        }
8439        if (subject != null) {
8440            sb.append("Subject: ").append(subject).append("\n");
8441        }
8442        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8443        if (Debug.isDebuggerConnected()) {
8444            sb.append("Debugger: Connected\n");
8445        }
8446        sb.append("\n");
8447
8448        // Do the rest in a worker thread to avoid blocking the caller on I/O
8449        // (After this point, we shouldn't access AMS internal data structures.)
8450        Thread worker = new Thread("Error dump: " + dropboxTag) {
8451            @Override
8452            public void run() {
8453                if (report != null) {
8454                    sb.append(report);
8455                }
8456                if (logFile != null) {
8457                    try {
8458                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8459                    } catch (IOException e) {
8460                        Slog.e(TAG, "Error reading " + logFile, e);
8461                    }
8462                }
8463                if (crashInfo != null && crashInfo.stackTrace != null) {
8464                    sb.append(crashInfo.stackTrace);
8465                }
8466
8467                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8468                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8469                if (lines > 0) {
8470                    sb.append("\n");
8471
8472                    // Merge several logcat streams, and take the last N lines
8473                    InputStreamReader input = null;
8474                    try {
8475                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8476                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8477                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8478
8479                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8480                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8481                        input = new InputStreamReader(logcat.getInputStream());
8482
8483                        int num;
8484                        char[] buf = new char[8192];
8485                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8486                    } catch (IOException e) {
8487                        Slog.e(TAG, "Error running logcat", e);
8488                    } finally {
8489                        if (input != null) try { input.close(); } catch (IOException e) {}
8490                    }
8491                }
8492
8493                dbox.addText(dropboxTag, sb.toString());
8494            }
8495        };
8496
8497        if (process == null) {
8498            // If process is null, we are being called from some internal code
8499            // and may be about to die -- run this synchronously.
8500            worker.run();
8501        } else {
8502            worker.start();
8503        }
8504    }
8505
8506    /**
8507     * Bring up the "unexpected error" dialog box for a crashing app.
8508     * Deal with edge cases (intercepts from instrumented applications,
8509     * ActivityController, error intent receivers, that sort of thing).
8510     * @param r the application crashing
8511     * @param crashInfo describing the failure
8512     */
8513    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8514        long timeMillis = System.currentTimeMillis();
8515        String shortMsg = crashInfo.exceptionClassName;
8516        String longMsg = crashInfo.exceptionMessage;
8517        String stackTrace = crashInfo.stackTrace;
8518        if (shortMsg != null && longMsg != null) {
8519            longMsg = shortMsg + ": " + longMsg;
8520        } else if (shortMsg != null) {
8521            longMsg = shortMsg;
8522        }
8523
8524        AppErrorResult result = new AppErrorResult();
8525        synchronized (this) {
8526            if (mController != null) {
8527                try {
8528                    String name = r != null ? r.processName : null;
8529                    int pid = r != null ? r.pid : Binder.getCallingPid();
8530                    if (!mController.appCrashed(name, pid,
8531                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8532                        Slog.w(TAG, "Force-killing crashed app " + name
8533                                + " at watcher's request");
8534                        Process.killProcess(pid);
8535                        return;
8536                    }
8537                } catch (RemoteException e) {
8538                    mController = null;
8539                }
8540            }
8541
8542            final long origId = Binder.clearCallingIdentity();
8543
8544            // If this process is running instrumentation, finish it.
8545            if (r != null && r.instrumentationClass != null) {
8546                Slog.w(TAG, "Error in app " + r.processName
8547                      + " running instrumentation " + r.instrumentationClass + ":");
8548                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8549                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8550                Bundle info = new Bundle();
8551                info.putString("shortMsg", shortMsg);
8552                info.putString("longMsg", longMsg);
8553                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8554                Binder.restoreCallingIdentity(origId);
8555                return;
8556            }
8557
8558            // If we can't identify the process or it's already exceeded its crash quota,
8559            // quit right away without showing a crash dialog.
8560            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8561                Binder.restoreCallingIdentity(origId);
8562                return;
8563            }
8564
8565            Message msg = Message.obtain();
8566            msg.what = SHOW_ERROR_MSG;
8567            HashMap data = new HashMap();
8568            data.put("result", result);
8569            data.put("app", r);
8570            msg.obj = data;
8571            mHandler.sendMessage(msg);
8572
8573            Binder.restoreCallingIdentity(origId);
8574        }
8575
8576        int res = result.get();
8577
8578        Intent appErrorIntent = null;
8579        synchronized (this) {
8580            if (r != null && !r.isolated) {
8581                // XXX Can't keep track of crash time for isolated processes,
8582                // since they don't have a persistent identity.
8583                mProcessCrashTimes.put(r.info.processName, r.uid,
8584                        SystemClock.uptimeMillis());
8585            }
8586            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8587                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8588            }
8589        }
8590
8591        if (appErrorIntent != null) {
8592            try {
8593                mContext.startActivity(appErrorIntent);
8594            } catch (ActivityNotFoundException e) {
8595                Slog.w(TAG, "bug report receiver dissappeared", e);
8596            }
8597        }
8598    }
8599
8600    Intent createAppErrorIntentLocked(ProcessRecord r,
8601            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8602        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8603        if (report == null) {
8604            return null;
8605        }
8606        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8607        result.setComponent(r.errorReportReceiver);
8608        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8609        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8610        return result;
8611    }
8612
8613    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8614            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8615        if (r.errorReportReceiver == null) {
8616            return null;
8617        }
8618
8619        if (!r.crashing && !r.notResponding) {
8620            return null;
8621        }
8622
8623        ApplicationErrorReport report = new ApplicationErrorReport();
8624        report.packageName = r.info.packageName;
8625        report.installerPackageName = r.errorReportReceiver.getPackageName();
8626        report.processName = r.processName;
8627        report.time = timeMillis;
8628        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8629
8630        if (r.crashing) {
8631            report.type = ApplicationErrorReport.TYPE_CRASH;
8632            report.crashInfo = crashInfo;
8633        } else if (r.notResponding) {
8634            report.type = ApplicationErrorReport.TYPE_ANR;
8635            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8636
8637            report.anrInfo.activity = r.notRespondingReport.tag;
8638            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8639            report.anrInfo.info = r.notRespondingReport.longMsg;
8640        }
8641
8642        return report;
8643    }
8644
8645    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8646        enforceNotIsolatedCaller("getProcessesInErrorState");
8647        // assume our apps are happy - lazy create the list
8648        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8649
8650        final boolean allUsers = ActivityManager.checkUidPermission(
8651                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8652                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8653        int userId = UserHandle.getUserId(Binder.getCallingUid());
8654
8655        synchronized (this) {
8656
8657            // iterate across all processes
8658            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8659                ProcessRecord app = mLruProcesses.get(i);
8660                if (!allUsers && app.userId != userId) {
8661                    continue;
8662                }
8663                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8664                    // This one's in trouble, so we'll generate a report for it
8665                    // crashes are higher priority (in case there's a crash *and* an anr)
8666                    ActivityManager.ProcessErrorStateInfo report = null;
8667                    if (app.crashing) {
8668                        report = app.crashingReport;
8669                    } else if (app.notResponding) {
8670                        report = app.notRespondingReport;
8671                    }
8672
8673                    if (report != null) {
8674                        if (errList == null) {
8675                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8676                        }
8677                        errList.add(report);
8678                    } else {
8679                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8680                                " crashing = " + app.crashing +
8681                                " notResponding = " + app.notResponding);
8682                    }
8683                }
8684            }
8685        }
8686
8687        return errList;
8688    }
8689
8690    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8691        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8692            if (currApp != null) {
8693                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8694            }
8695            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8696        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8697            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8698        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8699            if (currApp != null) {
8700                currApp.lru = 0;
8701            }
8702            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8703        } else if (adj >= ProcessList.SERVICE_ADJ) {
8704            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8705        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8706            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8707        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8708            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8709        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8710            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8711        } else {
8712            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8713        }
8714    }
8715
8716    private void fillInProcMemInfo(ProcessRecord app,
8717            ActivityManager.RunningAppProcessInfo outInfo) {
8718        outInfo.pid = app.pid;
8719        outInfo.uid = app.info.uid;
8720        if (mHeavyWeightProcess == app) {
8721            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8722        }
8723        if (app.persistent) {
8724            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8725        }
8726        if (app.hasActivities) {
8727            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8728        }
8729        outInfo.lastTrimLevel = app.trimMemoryLevel;
8730        int adj = app.curAdj;
8731        outInfo.importance = oomAdjToImportance(adj, outInfo);
8732        outInfo.importanceReasonCode = app.adjTypeCode;
8733    }
8734
8735    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8736        enforceNotIsolatedCaller("getRunningAppProcesses");
8737        // Lazy instantiation of list
8738        List<ActivityManager.RunningAppProcessInfo> runList = null;
8739        final boolean allUsers = ActivityManager.checkUidPermission(
8740                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8741                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8742        int userId = UserHandle.getUserId(Binder.getCallingUid());
8743        synchronized (this) {
8744            // Iterate across all processes
8745            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8746                ProcessRecord app = mLruProcesses.get(i);
8747                if (!allUsers && app.userId != userId) {
8748                    continue;
8749                }
8750                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8751                    // Generate process state info for running application
8752                    ActivityManager.RunningAppProcessInfo currApp =
8753                        new ActivityManager.RunningAppProcessInfo(app.processName,
8754                                app.pid, app.getPackageList());
8755                    fillInProcMemInfo(app, currApp);
8756                    if (app.adjSource instanceof ProcessRecord) {
8757                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8758                        currApp.importanceReasonImportance = oomAdjToImportance(
8759                                app.adjSourceOom, null);
8760                    } else if (app.adjSource instanceof ActivityRecord) {
8761                        ActivityRecord r = (ActivityRecord)app.adjSource;
8762                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8763                    }
8764                    if (app.adjTarget instanceof ComponentName) {
8765                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8766                    }
8767                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8768                    //        + " lru=" + currApp.lru);
8769                    if (runList == null) {
8770                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8771                    }
8772                    runList.add(currApp);
8773                }
8774            }
8775        }
8776        return runList;
8777    }
8778
8779    public List<ApplicationInfo> getRunningExternalApplications() {
8780        enforceNotIsolatedCaller("getRunningExternalApplications");
8781        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8782        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8783        if (runningApps != null && runningApps.size() > 0) {
8784            Set<String> extList = new HashSet<String>();
8785            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8786                if (app.pkgList != null) {
8787                    for (String pkg : app.pkgList) {
8788                        extList.add(pkg);
8789                    }
8790                }
8791            }
8792            IPackageManager pm = AppGlobals.getPackageManager();
8793            for (String pkg : extList) {
8794                try {
8795                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8796                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8797                        retList.add(info);
8798                    }
8799                } catch (RemoteException e) {
8800                }
8801            }
8802        }
8803        return retList;
8804    }
8805
8806    @Override
8807    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8808        enforceNotIsolatedCaller("getMyMemoryState");
8809        synchronized (this) {
8810            ProcessRecord proc;
8811            synchronized (mPidsSelfLocked) {
8812                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8813            }
8814            fillInProcMemInfo(proc, outInfo);
8815        }
8816    }
8817
8818    @Override
8819    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8820        if (checkCallingPermission(android.Manifest.permission.DUMP)
8821                != PackageManager.PERMISSION_GRANTED) {
8822            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8823                    + Binder.getCallingPid()
8824                    + ", uid=" + Binder.getCallingUid()
8825                    + " without permission "
8826                    + android.Manifest.permission.DUMP);
8827            return;
8828        }
8829
8830        boolean dumpAll = false;
8831        boolean dumpClient = false;
8832        String dumpPackage = null;
8833
8834        int opti = 0;
8835        while (opti < args.length) {
8836            String opt = args[opti];
8837            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8838                break;
8839            }
8840            opti++;
8841            if ("-a".equals(opt)) {
8842                dumpAll = true;
8843            } else if ("-c".equals(opt)) {
8844                dumpClient = true;
8845            } else if ("-h".equals(opt)) {
8846                pw.println("Activity manager dump options:");
8847                pw.println("  [-a] [-c] [-h] [cmd] ...");
8848                pw.println("  cmd may be one of:");
8849                pw.println("    a[ctivities]: activity stack state");
8850                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8851                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8852                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8853                pw.println("    o[om]: out of memory management");
8854                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8855                pw.println("    provider [COMP_SPEC]: provider client-side state");
8856                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8857                pw.println("    service [COMP_SPEC]: service client-side state");
8858                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8859                pw.println("    all: dump all activities");
8860                pw.println("    top: dump the top activity");
8861                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8862                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8863                pw.println("    a partial substring in a component name, a");
8864                pw.println("    hex object identifier.");
8865                pw.println("  -a: include all available server state.");
8866                pw.println("  -c: include client state.");
8867                return;
8868            } else {
8869                pw.println("Unknown argument: " + opt + "; use -h for help");
8870            }
8871        }
8872
8873        long origId = Binder.clearCallingIdentity();
8874        boolean more = false;
8875        // Is the caller requesting to dump a particular piece of data?
8876        if (opti < args.length) {
8877            String cmd = args[opti];
8878            opti++;
8879            if ("activities".equals(cmd) || "a".equals(cmd)) {
8880                synchronized (this) {
8881                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8882                }
8883            } else if ("broadcasts".equals(cmd) || "b".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                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8898                }
8899            } else if ("intents".equals(cmd) || "i".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                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8914                }
8915            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8916                String[] newArgs;
8917                String name;
8918                if (opti >= args.length) {
8919                    name = null;
8920                    newArgs = EMPTY_STRING_ARRAY;
8921                } else {
8922                    name = args[opti];
8923                    opti++;
8924                    newArgs = new String[args.length - opti];
8925                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8926                            args.length - opti);
8927                }
8928                synchronized (this) {
8929                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8930                }
8931            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8932                synchronized (this) {
8933                    dumpOomLocked(fd, pw, args, opti, true);
8934                }
8935            } else if ("provider".equals(cmd)) {
8936                String[] newArgs;
8937                String name;
8938                if (opti >= args.length) {
8939                    name = null;
8940                    newArgs = EMPTY_STRING_ARRAY;
8941                } else {
8942                    name = args[opti];
8943                    opti++;
8944                    newArgs = new String[args.length - opti];
8945                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8946                }
8947                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8948                    pw.println("No providers match: " + name);
8949                    pw.println("Use -h for help.");
8950                }
8951            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8952                synchronized (this) {
8953                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8954                }
8955            } else if ("service".equals(cmd)) {
8956                String[] newArgs;
8957                String name;
8958                if (opti >= args.length) {
8959                    name = null;
8960                    newArgs = EMPTY_STRING_ARRAY;
8961                } else {
8962                    name = 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                }
8968                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8969                    pw.println("No services match: " + name);
8970                    pw.println("Use -h for help.");
8971                }
8972            } else if ("package".equals(cmd)) {
8973                String[] newArgs;
8974                if (opti >= args.length) {
8975                    pw.println("package: no package name specified");
8976                    pw.println("Use -h for help.");
8977                } else {
8978                    dumpPackage = args[opti];
8979                    opti++;
8980                    newArgs = new String[args.length - opti];
8981                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8982                            args.length - opti);
8983                    args = newArgs;
8984                    opti = 0;
8985                    more = true;
8986                }
8987            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8988                synchronized (this) {
8989                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8990                }
8991            } else {
8992                // Dumping a single activity?
8993                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8994                    pw.println("Bad activity command, or no activities match: " + cmd);
8995                    pw.println("Use -h for help.");
8996                }
8997            }
8998            if (!more) {
8999                Binder.restoreCallingIdentity(origId);
9000                return;
9001            }
9002        }
9003
9004        // No piece of data specified, dump everything.
9005        synchronized (this) {
9006            boolean needSep;
9007            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9008            if (needSep) {
9009                pw.println(" ");
9010            }
9011            if (dumpAll) {
9012                pw.println("-------------------------------------------------------------------------------");
9013            }
9014            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9015            if (needSep) {
9016                pw.println(" ");
9017            }
9018            if (dumpAll) {
9019                pw.println("-------------------------------------------------------------------------------");
9020            }
9021            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9022            if (needSep) {
9023                pw.println(" ");
9024            }
9025            if (dumpAll) {
9026                pw.println("-------------------------------------------------------------------------------");
9027            }
9028            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9029            if (needSep) {
9030                pw.println(" ");
9031            }
9032            if (dumpAll) {
9033                pw.println("-------------------------------------------------------------------------------");
9034            }
9035            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9036            if (needSep) {
9037                pw.println(" ");
9038            }
9039            if (dumpAll) {
9040                pw.println("-------------------------------------------------------------------------------");
9041            }
9042            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9043        }
9044        Binder.restoreCallingIdentity(origId);
9045    }
9046
9047    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9048            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9049        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9050        pw.println("  Main stack:");
9051        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9052                dumpPackage);
9053        pw.println(" ");
9054        pw.println("  Running activities (most recent first):");
9055        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9056                dumpPackage);
9057        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9058            pw.println(" ");
9059            pw.println("  Activities waiting for another to become visible:");
9060            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9061                    !dumpAll, false, dumpPackage);
9062        }
9063        if (mMainStack.mStoppingActivities.size() > 0) {
9064            pw.println(" ");
9065            pw.println("  Activities waiting to stop:");
9066            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9067                    !dumpAll, false, dumpPackage);
9068        }
9069        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9070            pw.println(" ");
9071            pw.println("  Activities waiting to sleep:");
9072            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9073                    !dumpAll, false, dumpPackage);
9074        }
9075        if (mMainStack.mFinishingActivities.size() > 0) {
9076            pw.println(" ");
9077            pw.println("  Activities waiting to finish:");
9078            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9079                    !dumpAll, false, dumpPackage);
9080        }
9081
9082        pw.println(" ");
9083        if (mMainStack.mPausingActivity != null) {
9084            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9085        }
9086        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9087        pw.println("  mFocusedActivity: " + mFocusedActivity);
9088        if (dumpAll) {
9089            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9090            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9091            pw.println("  mDismissKeyguardOnNextActivity: "
9092                    + mMainStack.mDismissKeyguardOnNextActivity);
9093        }
9094
9095        if (mRecentTasks.size() > 0) {
9096            pw.println();
9097            pw.println("  Recent tasks:");
9098
9099            final int N = mRecentTasks.size();
9100            for (int i=0; i<N; i++) {
9101                TaskRecord tr = mRecentTasks.get(i);
9102                if (dumpPackage != null) {
9103                    if (tr.realActivity == null ||
9104                            !dumpPackage.equals(tr.realActivity)) {
9105                        continue;
9106                    }
9107                }
9108                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9109                        pw.println(tr);
9110                if (dumpAll) {
9111                    mRecentTasks.get(i).dump(pw, "    ");
9112                }
9113            }
9114        }
9115
9116        if (dumpAll) {
9117            pw.println(" ");
9118            pw.println("  mCurTask: " + mCurTask);
9119        }
9120
9121        return true;
9122    }
9123
9124    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9125            int opti, boolean dumpAll, String dumpPackage) {
9126        boolean needSep = false;
9127        int numPers = 0;
9128
9129        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9130
9131        if (dumpAll) {
9132            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9133                final int NA = procs.size();
9134                for (int ia=0; ia<NA; ia++) {
9135                    ProcessRecord r = procs.valueAt(ia);
9136                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9137                        continue;
9138                    }
9139                    if (!needSep) {
9140                        pw.println("  All known processes:");
9141                        needSep = true;
9142                    }
9143                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9144                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9145                        pw.print(" "); pw.println(r);
9146                    r.dump(pw, "    ");
9147                    if (r.persistent) {
9148                        numPers++;
9149                    }
9150                }
9151            }
9152        }
9153
9154        if (mIsolatedProcesses.size() > 0) {
9155            if (needSep) pw.println(" ");
9156            needSep = true;
9157            pw.println("  Isolated process list (sorted by uid):");
9158            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9159                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9160                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9161                    continue;
9162                }
9163                pw.println(String.format("%sIsolated #%2d: %s",
9164                        "    ", i, r.toString()));
9165            }
9166        }
9167
9168        if (mLruProcesses.size() > 0) {
9169            if (needSep) pw.println(" ");
9170            needSep = true;
9171            pw.println("  Process LRU list (sorted by oom_adj):");
9172            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9173                    "Proc", "PERS", false, dumpPackage);
9174            needSep = true;
9175        }
9176
9177        if (dumpAll) {
9178            synchronized (mPidsSelfLocked) {
9179                boolean printed = false;
9180                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9181                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9182                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9183                        continue;
9184                    }
9185                    if (!printed) {
9186                        if (needSep) pw.println(" ");
9187                        needSep = true;
9188                        pw.println("  PID mappings:");
9189                        printed = true;
9190                    }
9191                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9192                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9193                }
9194            }
9195        }
9196
9197        if (mForegroundProcesses.size() > 0) {
9198            synchronized (mPidsSelfLocked) {
9199                boolean printed = false;
9200                for (int i=0; i<mForegroundProcesses.size(); i++) {
9201                    ProcessRecord r = mPidsSelfLocked.get(
9202                            mForegroundProcesses.valueAt(i).pid);
9203                    if (dumpPackage != null && (r == null
9204                            || !dumpPackage.equals(r.info.packageName))) {
9205                        continue;
9206                    }
9207                    if (!printed) {
9208                        if (needSep) pw.println(" ");
9209                        needSep = true;
9210                        pw.println("  Foreground Processes:");
9211                        printed = true;
9212                    }
9213                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9214                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9215                }
9216            }
9217        }
9218
9219        if (mPersistentStartingProcesses.size() > 0) {
9220            if (needSep) pw.println(" ");
9221            needSep = true;
9222            pw.println("  Persisent processes that are starting:");
9223            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9224                    "Starting Norm", "Restarting PERS", dumpPackage);
9225        }
9226
9227        if (mRemovedProcesses.size() > 0) {
9228            if (needSep) pw.println(" ");
9229            needSep = true;
9230            pw.println("  Processes that are being removed:");
9231            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9232                    "Removed Norm", "Removed PERS", dumpPackage);
9233        }
9234
9235        if (mProcessesOnHold.size() > 0) {
9236            if (needSep) pw.println(" ");
9237            needSep = true;
9238            pw.println("  Processes that are on old until the system is ready:");
9239            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9240                    "OnHold Norm", "OnHold PERS", dumpPackage);
9241        }
9242
9243        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9244
9245        if (mProcessCrashTimes.getMap().size() > 0) {
9246            boolean printed = false;
9247            long now = SystemClock.uptimeMillis();
9248            for (Map.Entry<String, SparseArray<Long>> procs
9249                    : mProcessCrashTimes.getMap().entrySet()) {
9250                String pname = procs.getKey();
9251                SparseArray<Long> uids = procs.getValue();
9252                final int N = uids.size();
9253                for (int i=0; i<N; i++) {
9254                    int puid = uids.keyAt(i);
9255                    ProcessRecord r = mProcessNames.get(pname, puid);
9256                    if (dumpPackage != null && (r == null
9257                            || !dumpPackage.equals(r.info.packageName))) {
9258                        continue;
9259                    }
9260                    if (!printed) {
9261                        if (needSep) pw.println(" ");
9262                        needSep = true;
9263                        pw.println("  Time since processes crashed:");
9264                        printed = true;
9265                    }
9266                    pw.print("    Process "); pw.print(pname);
9267                            pw.print(" uid "); pw.print(puid);
9268                            pw.print(": last crashed ");
9269                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9270                            pw.println(" ago");
9271                }
9272            }
9273        }
9274
9275        if (mBadProcesses.getMap().size() > 0) {
9276            boolean printed = false;
9277            for (Map.Entry<String, SparseArray<Long>> procs
9278                    : mBadProcesses.getMap().entrySet()) {
9279                String pname = procs.getKey();
9280                SparseArray<Long> uids = procs.getValue();
9281                final int N = uids.size();
9282                for (int i=0; i<N; i++) {
9283                    int puid = uids.keyAt(i);
9284                    ProcessRecord r = mProcessNames.get(pname, puid);
9285                    if (dumpPackage != null && (r == null
9286                            || !dumpPackage.equals(r.info.packageName))) {
9287                        continue;
9288                    }
9289                    if (!printed) {
9290                        if (needSep) pw.println(" ");
9291                        needSep = true;
9292                        pw.println("  Bad processes:");
9293                    }
9294                    pw.print("    Bad process "); pw.print(pname);
9295                            pw.print(" uid "); pw.print(puid);
9296                            pw.print(": crashed at time ");
9297                            pw.println(uids.valueAt(i));
9298                }
9299            }
9300        }
9301
9302        pw.println();
9303        pw.println("  mStartedUsers:");
9304        for (int i=0; i<mStartedUsers.size(); i++) {
9305            UserStartedState uss = mStartedUsers.valueAt(i);
9306            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9307                    pw.print(": "); uss.dump("", pw);
9308        }
9309        pw.print("  mUserLru: [");
9310        for (int i=0; i<mUserLru.size(); i++) {
9311            if (i > 0) pw.print(", ");
9312            pw.print(mUserLru.get(i));
9313        }
9314        pw.println("]");
9315        if (dumpAll) {
9316            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9317        }
9318        pw.println("  mHomeProcess: " + mHomeProcess);
9319        pw.println("  mPreviousProcess: " + mPreviousProcess);
9320        if (dumpAll) {
9321            StringBuilder sb = new StringBuilder(128);
9322            sb.append("  mPreviousProcessVisibleTime: ");
9323            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9324            pw.println(sb);
9325        }
9326        if (mHeavyWeightProcess != null) {
9327            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9328        }
9329        pw.println("  mConfiguration: " + mConfiguration);
9330        if (dumpAll) {
9331            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9332            if (mCompatModePackages.getPackages().size() > 0) {
9333                boolean printed = false;
9334                for (Map.Entry<String, Integer> entry
9335                        : mCompatModePackages.getPackages().entrySet()) {
9336                    String pkg = entry.getKey();
9337                    int mode = entry.getValue();
9338                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9339                        continue;
9340                    }
9341                    if (!printed) {
9342                        pw.println("  mScreenCompatPackages:");
9343                        printed = true;
9344                    }
9345                    pw.print("    "); pw.print(pkg); pw.print(": ");
9346                            pw.print(mode); pw.println();
9347                }
9348            }
9349        }
9350        if (mSleeping || mWentToSleep || mLockScreenShown) {
9351            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9352                    + " mLockScreenShown " + mLockScreenShown);
9353        }
9354        if (mShuttingDown) {
9355            pw.println("  mShuttingDown=" + mShuttingDown);
9356        }
9357        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9358                || mOrigWaitForDebugger) {
9359            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9360                    + " mDebugTransient=" + mDebugTransient
9361                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9362        }
9363        if (mOpenGlTraceApp != null) {
9364            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9365        }
9366        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9367                || mProfileFd != null) {
9368            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9369            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9370            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9371                    + mAutoStopProfiler);
9372        }
9373        if (mAlwaysFinishActivities || mController != null) {
9374            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9375                    + " mController=" + mController);
9376        }
9377        if (dumpAll) {
9378            pw.println("  Total persistent processes: " + numPers);
9379            pw.println("  mStartRunning=" + mStartRunning
9380                    + " mProcessesReady=" + mProcessesReady
9381                    + " mSystemReady=" + mSystemReady);
9382            pw.println("  mBooting=" + mBooting
9383                    + " mBooted=" + mBooted
9384                    + " mFactoryTest=" + mFactoryTest);
9385            pw.print("  mLastPowerCheckRealtime=");
9386                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9387                    pw.println("");
9388            pw.print("  mLastPowerCheckUptime=");
9389                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9390                    pw.println("");
9391            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9392            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9393            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9394            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9395                    + " mNumHiddenProcs=" + mNumHiddenProcs
9396                    + " mNumServiceProcs=" + mNumServiceProcs
9397                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9398        }
9399
9400        return true;
9401    }
9402
9403    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9404            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9405        if (mProcessesToGc.size() > 0) {
9406            boolean printed = false;
9407            long now = SystemClock.uptimeMillis();
9408            for (int i=0; i<mProcessesToGc.size(); i++) {
9409                ProcessRecord proc = mProcessesToGc.get(i);
9410                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9411                    continue;
9412                }
9413                if (!printed) {
9414                    if (needSep) pw.println(" ");
9415                    needSep = true;
9416                    pw.println("  Processes that are waiting to GC:");
9417                    printed = true;
9418                }
9419                pw.print("    Process "); pw.println(proc);
9420                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9421                        pw.print(", last gced=");
9422                        pw.print(now-proc.lastRequestedGc);
9423                        pw.print(" ms ago, last lowMem=");
9424                        pw.print(now-proc.lastLowMemory);
9425                        pw.println(" ms ago");
9426
9427            }
9428        }
9429        return needSep;
9430    }
9431
9432    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9433            int opti, boolean dumpAll) {
9434        boolean needSep = false;
9435
9436        if (mLruProcesses.size() > 0) {
9437            if (needSep) pw.println(" ");
9438            needSep = true;
9439            pw.println("  OOM levels:");
9440            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9441            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9442            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9443            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9444            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9445            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9446            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9447            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9448            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9449            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9450            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9451            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9452            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9453
9454            if (needSep) pw.println(" ");
9455            needSep = true;
9456            pw.println("  Process OOM control:");
9457            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9458                    "Proc", "PERS", true, null);
9459            needSep = true;
9460        }
9461
9462        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9463
9464        pw.println();
9465        pw.println("  mHomeProcess: " + mHomeProcess);
9466        pw.println("  mPreviousProcess: " + mPreviousProcess);
9467        if (mHeavyWeightProcess != null) {
9468            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9469        }
9470
9471        return true;
9472    }
9473
9474    /**
9475     * There are three ways to call this:
9476     *  - no provider specified: dump all the providers
9477     *  - a flattened component name that matched an existing provider was specified as the
9478     *    first arg: dump that one provider
9479     *  - the first arg isn't the flattened component name of an existing provider:
9480     *    dump all providers whose component contains the first arg as a substring
9481     */
9482    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9483            int opti, boolean dumpAll) {
9484        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9485    }
9486
9487    static class ItemMatcher {
9488        ArrayList<ComponentName> components;
9489        ArrayList<String> strings;
9490        ArrayList<Integer> objects;
9491        boolean all;
9492
9493        ItemMatcher() {
9494            all = true;
9495        }
9496
9497        void build(String name) {
9498            ComponentName componentName = ComponentName.unflattenFromString(name);
9499            if (componentName != null) {
9500                if (components == null) {
9501                    components = new ArrayList<ComponentName>();
9502                }
9503                components.add(componentName);
9504                all = false;
9505            } else {
9506                int objectId = 0;
9507                // Not a '/' separated full component name; maybe an object ID?
9508                try {
9509                    objectId = Integer.parseInt(name, 16);
9510                    if (objects == null) {
9511                        objects = new ArrayList<Integer>();
9512                    }
9513                    objects.add(objectId);
9514                    all = false;
9515                } catch (RuntimeException e) {
9516                    // Not an integer; just do string match.
9517                    if (strings == null) {
9518                        strings = new ArrayList<String>();
9519                    }
9520                    strings.add(name);
9521                    all = false;
9522                }
9523            }
9524        }
9525
9526        int build(String[] args, int opti) {
9527            for (; opti<args.length; opti++) {
9528                String name = args[opti];
9529                if ("--".equals(name)) {
9530                    return opti+1;
9531                }
9532                build(name);
9533            }
9534            return opti;
9535        }
9536
9537        boolean match(Object object, ComponentName comp) {
9538            if (all) {
9539                return true;
9540            }
9541            if (components != null) {
9542                for (int i=0; i<components.size(); i++) {
9543                    if (components.get(i).equals(comp)) {
9544                        return true;
9545                    }
9546                }
9547            }
9548            if (objects != null) {
9549                for (int i=0; i<objects.size(); i++) {
9550                    if (System.identityHashCode(object) == objects.get(i)) {
9551                        return true;
9552                    }
9553                }
9554            }
9555            if (strings != null) {
9556                String flat = comp.flattenToString();
9557                for (int i=0; i<strings.size(); i++) {
9558                    if (flat.contains(strings.get(i))) {
9559                        return true;
9560                    }
9561                }
9562            }
9563            return false;
9564        }
9565    }
9566
9567    /**
9568     * There are three things that cmd can be:
9569     *  - a flattened component name that matches an existing activity
9570     *  - the cmd arg isn't the flattened component name of an existing activity:
9571     *    dump all activity whose component contains the cmd as a substring
9572     *  - A hex number of the ActivityRecord object instance.
9573     */
9574    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9575            int opti, boolean dumpAll) {
9576        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9577
9578        if ("all".equals(name)) {
9579            synchronized (this) {
9580                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9581                    activities.add(r1);
9582                }
9583            }
9584        } else if ("top".equals(name)) {
9585            synchronized (this) {
9586                final int N = mMainStack.mHistory.size();
9587                if (N > 0) {
9588                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9589                }
9590            }
9591        } else {
9592            ItemMatcher matcher = new ItemMatcher();
9593            matcher.build(name);
9594
9595            synchronized (this) {
9596                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9597                    if (matcher.match(r1, r1.intent.getComponent())) {
9598                        activities.add(r1);
9599                    }
9600                }
9601            }
9602        }
9603
9604        if (activities.size() <= 0) {
9605            return false;
9606        }
9607
9608        String[] newArgs = new String[args.length - opti];
9609        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9610
9611        TaskRecord lastTask = null;
9612        boolean needSep = false;
9613        for (int i=activities.size()-1; i>=0; i--) {
9614            ActivityRecord r = (ActivityRecord)activities.get(i);
9615            if (needSep) {
9616                pw.println();
9617            }
9618            needSep = true;
9619            synchronized (this) {
9620                if (lastTask != r.task) {
9621                    lastTask = r.task;
9622                    pw.print("TASK "); pw.print(lastTask.affinity);
9623                            pw.print(" id="); pw.println(lastTask.taskId);
9624                    if (dumpAll) {
9625                        lastTask.dump(pw, "  ");
9626                    }
9627                }
9628            }
9629            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9630        }
9631        return true;
9632    }
9633
9634    /**
9635     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9636     * there is a thread associated with the activity.
9637     */
9638    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9639            final ActivityRecord r, String[] args, boolean dumpAll) {
9640        String innerPrefix = prefix + "  ";
9641        synchronized (this) {
9642            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9643                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9644                    pw.print(" pid=");
9645                    if (r.app != null) pw.println(r.app.pid);
9646                    else pw.println("(not running)");
9647            if (dumpAll) {
9648                r.dump(pw, innerPrefix);
9649            }
9650        }
9651        if (r.app != null && r.app.thread != null) {
9652            // flush anything that is already in the PrintWriter since the thread is going
9653            // to write to the file descriptor directly
9654            pw.flush();
9655            try {
9656                TransferPipe tp = new TransferPipe();
9657                try {
9658                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9659                            r.appToken, innerPrefix, args);
9660                    tp.go(fd);
9661                } finally {
9662                    tp.kill();
9663                }
9664            } catch (IOException e) {
9665                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9666            } catch (RemoteException e) {
9667                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9668            }
9669        }
9670    }
9671
9672    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9673            int opti, boolean dumpAll, String dumpPackage) {
9674        boolean needSep = false;
9675        boolean onlyHistory = false;
9676
9677        if ("history".equals(dumpPackage)) {
9678            onlyHistory = true;
9679            dumpPackage = null;
9680        }
9681
9682        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9683        if (!onlyHistory && dumpAll) {
9684            if (mRegisteredReceivers.size() > 0) {
9685                boolean printed = false;
9686                Iterator it = mRegisteredReceivers.values().iterator();
9687                while (it.hasNext()) {
9688                    ReceiverList r = (ReceiverList)it.next();
9689                    if (dumpPackage != null && (r.app == null ||
9690                            !dumpPackage.equals(r.app.info.packageName))) {
9691                        continue;
9692                    }
9693                    if (!printed) {
9694                        pw.println("  Registered Receivers:");
9695                        needSep = true;
9696                        printed = true;
9697                    }
9698                    pw.print("  * "); pw.println(r);
9699                    r.dump(pw, "    ");
9700                }
9701            }
9702
9703            if (mReceiverResolver.dump(pw, needSep ?
9704                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9705                    "    ", dumpPackage, false)) {
9706                needSep = true;
9707            }
9708        }
9709
9710        for (BroadcastQueue q : mBroadcastQueues) {
9711            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9712        }
9713
9714        needSep = true;
9715
9716        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9717            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9718                if (needSep) {
9719                    pw.println();
9720                }
9721                needSep = true;
9722                pw.print("  Sticky broadcasts for user ");
9723                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9724                StringBuilder sb = new StringBuilder(128);
9725                for (Map.Entry<String, ArrayList<Intent>> ent
9726                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9727                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9728                    if (dumpAll) {
9729                        pw.println(":");
9730                        ArrayList<Intent> intents = ent.getValue();
9731                        final int N = intents.size();
9732                        for (int i=0; i<N; i++) {
9733                            sb.setLength(0);
9734                            sb.append("    Intent: ");
9735                            intents.get(i).toShortString(sb, false, true, false, false);
9736                            pw.println(sb.toString());
9737                            Bundle bundle = intents.get(i).getExtras();
9738                            if (bundle != null) {
9739                                pw.print("      ");
9740                                pw.println(bundle.toString());
9741                            }
9742                        }
9743                    } else {
9744                        pw.println("");
9745                    }
9746                }
9747            }
9748        }
9749
9750        if (!onlyHistory && dumpAll) {
9751            pw.println();
9752            for (BroadcastQueue queue : mBroadcastQueues) {
9753                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9754                        + queue.mBroadcastsScheduled);
9755            }
9756            pw.println("  mHandler:");
9757            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9758            needSep = true;
9759        }
9760
9761        return needSep;
9762    }
9763
9764    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9765            int opti, boolean dumpAll, String dumpPackage) {
9766        boolean needSep = true;
9767
9768        ItemMatcher matcher = new ItemMatcher();
9769        matcher.build(args, opti);
9770
9771        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9772
9773        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9774
9775        if (mLaunchingProviders.size() > 0) {
9776            boolean printed = false;
9777            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9778                ContentProviderRecord r = mLaunchingProviders.get(i);
9779                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9780                    continue;
9781                }
9782                if (!printed) {
9783                    if (needSep) pw.println(" ");
9784                    needSep = true;
9785                    pw.println("  Launching content providers:");
9786                    printed = true;
9787                }
9788                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9789                        pw.println(r);
9790            }
9791        }
9792
9793        if (mGrantedUriPermissions.size() > 0) {
9794            if (needSep) pw.println();
9795            needSep = true;
9796            pw.println("Granted Uri Permissions:");
9797            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9798                int uid = mGrantedUriPermissions.keyAt(i);
9799                HashMap<Uri, UriPermission> perms
9800                        = mGrantedUriPermissions.valueAt(i);
9801                pw.print("  * UID "); pw.print(uid);
9802                        pw.println(" holds:");
9803                for (UriPermission perm : perms.values()) {
9804                    pw.print("    "); pw.println(perm);
9805                    if (dumpAll) {
9806                        perm.dump(pw, "      ");
9807                    }
9808                }
9809            }
9810            needSep = true;
9811        }
9812
9813        return needSep;
9814    }
9815
9816    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9817            int opti, boolean dumpAll, String dumpPackage) {
9818        boolean needSep = false;
9819
9820        if (mIntentSenderRecords.size() > 0) {
9821            boolean printed = false;
9822            Iterator<WeakReference<PendingIntentRecord>> it
9823                    = mIntentSenderRecords.values().iterator();
9824            while (it.hasNext()) {
9825                WeakReference<PendingIntentRecord> ref = it.next();
9826                PendingIntentRecord rec = ref != null ? ref.get(): null;
9827                if (dumpPackage != null && (rec == null
9828                        || !dumpPackage.equals(rec.key.packageName))) {
9829                    continue;
9830                }
9831                if (!printed) {
9832                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9833                    printed = true;
9834                }
9835                needSep = true;
9836                if (rec != null) {
9837                    pw.print("  * "); pw.println(rec);
9838                    if (dumpAll) {
9839                        rec.dump(pw, "    ");
9840                    }
9841                } else {
9842                    pw.print("  * "); pw.println(ref);
9843                }
9844            }
9845        }
9846
9847        return needSep;
9848    }
9849
9850    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9851            String prefix, String label, boolean complete, boolean brief, boolean client,
9852            String dumpPackage) {
9853        TaskRecord lastTask = null;
9854        boolean needNL = false;
9855        final String innerPrefix = prefix + "      ";
9856        final String[] args = new String[0];
9857        for (int i=list.size()-1; i>=0; i--) {
9858            final ActivityRecord r = (ActivityRecord)list.get(i);
9859            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9860                continue;
9861            }
9862            final boolean full = !brief && (complete || !r.isInHistory());
9863            if (needNL) {
9864                pw.println(" ");
9865                needNL = false;
9866            }
9867            if (lastTask != r.task) {
9868                lastTask = r.task;
9869                pw.print(prefix);
9870                pw.print(full ? "* " : "  ");
9871                pw.println(lastTask);
9872                if (full) {
9873                    lastTask.dump(pw, prefix + "  ");
9874                } else if (complete) {
9875                    // Complete + brief == give a summary.  Isn't that obvious?!?
9876                    if (lastTask.intent != null) {
9877                        pw.print(prefix); pw.print("  ");
9878                                pw.println(lastTask.intent.toInsecureStringWithClip());
9879                    }
9880                }
9881            }
9882            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9883            pw.print(" #"); pw.print(i); pw.print(": ");
9884            pw.println(r);
9885            if (full) {
9886                r.dump(pw, innerPrefix);
9887            } else if (complete) {
9888                // Complete + brief == give a summary.  Isn't that obvious?!?
9889                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9890                if (r.app != null) {
9891                    pw.print(innerPrefix); pw.println(r.app);
9892                }
9893            }
9894            if (client && r.app != null && r.app.thread != null) {
9895                // flush anything that is already in the PrintWriter since the thread is going
9896                // to write to the file descriptor directly
9897                pw.flush();
9898                try {
9899                    TransferPipe tp = new TransferPipe();
9900                    try {
9901                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9902                                r.appToken, innerPrefix, args);
9903                        // Short timeout, since blocking here can
9904                        // deadlock with the application.
9905                        tp.go(fd, 2000);
9906                    } finally {
9907                        tp.kill();
9908                    }
9909                } catch (IOException e) {
9910                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9911                } catch (RemoteException e) {
9912                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9913                }
9914                needNL = true;
9915            }
9916        }
9917    }
9918
9919    private static String buildOomTag(String prefix, String space, int val, int base) {
9920        if (val == base) {
9921            if (space == null) return prefix;
9922            return prefix + "  ";
9923        }
9924        return prefix + "+" + Integer.toString(val-base);
9925    }
9926
9927    private static final int dumpProcessList(PrintWriter pw,
9928            ActivityManagerService service, List list,
9929            String prefix, String normalLabel, String persistentLabel,
9930            String dumpPackage) {
9931        int numPers = 0;
9932        final int N = list.size()-1;
9933        for (int i=N; i>=0; i--) {
9934            ProcessRecord r = (ProcessRecord)list.get(i);
9935            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9936                continue;
9937            }
9938            pw.println(String.format("%s%s #%2d: %s",
9939                    prefix, (r.persistent ? persistentLabel : normalLabel),
9940                    i, r.toString()));
9941            if (r.persistent) {
9942                numPers++;
9943            }
9944        }
9945        return numPers;
9946    }
9947
9948    private static final boolean dumpProcessOomList(PrintWriter pw,
9949            ActivityManagerService service, List<ProcessRecord> origList,
9950            String prefix, String normalLabel, String persistentLabel,
9951            boolean inclDetails, String dumpPackage) {
9952
9953        ArrayList<Pair<ProcessRecord, Integer>> list
9954                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9955        for (int i=0; i<origList.size(); i++) {
9956            ProcessRecord r = origList.get(i);
9957            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9958                continue;
9959            }
9960            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9961        }
9962
9963        if (list.size() <= 0) {
9964            return false;
9965        }
9966
9967        Comparator<Pair<ProcessRecord, Integer>> comparator
9968                = new Comparator<Pair<ProcessRecord, Integer>>() {
9969            @Override
9970            public int compare(Pair<ProcessRecord, Integer> object1,
9971                    Pair<ProcessRecord, Integer> object2) {
9972                if (object1.first.setAdj != object2.first.setAdj) {
9973                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9974                }
9975                if (object1.second.intValue() != object2.second.intValue()) {
9976                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9977                }
9978                return 0;
9979            }
9980        };
9981
9982        Collections.sort(list, comparator);
9983
9984        final long curRealtime = SystemClock.elapsedRealtime();
9985        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9986        final long curUptime = SystemClock.uptimeMillis();
9987        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9988
9989        for (int i=list.size()-1; i>=0; i--) {
9990            ProcessRecord r = list.get(i).first;
9991            String oomAdj;
9992            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9993                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9994            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9995                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9996            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9997                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9998            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9999                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10000            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10001                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10002            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10003                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10004            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10005                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10006            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10007                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10008            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10009                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10010            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10011                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10012            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10013                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10014            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10015                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10016            } else {
10017                oomAdj = Integer.toString(r.setAdj);
10018            }
10019            String schedGroup;
10020            switch (r.setSchedGroup) {
10021                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10022                    schedGroup = "B";
10023                    break;
10024                case Process.THREAD_GROUP_DEFAULT:
10025                    schedGroup = "F";
10026                    break;
10027                default:
10028                    schedGroup = Integer.toString(r.setSchedGroup);
10029                    break;
10030            }
10031            String foreground;
10032            if (r.foregroundActivities) {
10033                foreground = "A";
10034            } else if (r.foregroundServices) {
10035                foreground = "S";
10036            } else {
10037                foreground = " ";
10038            }
10039            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10040                    prefix, (r.persistent ? persistentLabel : normalLabel),
10041                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10042                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10043            if (r.adjSource != null || r.adjTarget != null) {
10044                pw.print(prefix);
10045                pw.print("    ");
10046                if (r.adjTarget instanceof ComponentName) {
10047                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10048                } else if (r.adjTarget != null) {
10049                    pw.print(r.adjTarget.toString());
10050                } else {
10051                    pw.print("{null}");
10052                }
10053                pw.print("<=");
10054                if (r.adjSource instanceof ProcessRecord) {
10055                    pw.print("Proc{");
10056                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10057                    pw.println("}");
10058                } else if (r.adjSource != null) {
10059                    pw.println(r.adjSource.toString());
10060                } else {
10061                    pw.println("{null}");
10062                }
10063            }
10064            if (inclDetails) {
10065                pw.print(prefix);
10066                pw.print("    ");
10067                pw.print("oom: max="); pw.print(r.maxAdj);
10068                pw.print(" hidden="); pw.print(r.hiddenAdj);
10069                pw.print(" client="); pw.print(r.clientHiddenAdj);
10070                pw.print(" empty="); pw.print(r.emptyAdj);
10071                pw.print(" curRaw="); pw.print(r.curRawAdj);
10072                pw.print(" setRaw="); pw.print(r.setRawAdj);
10073                pw.print(" cur="); pw.print(r.curAdj);
10074                pw.print(" set="); pw.println(r.setAdj);
10075                pw.print(prefix);
10076                pw.print("    ");
10077                pw.print("keeping="); pw.print(r.keeping);
10078                pw.print(" hidden="); pw.print(r.hidden);
10079                pw.print(" empty="); pw.print(r.empty);
10080                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10081
10082                if (!r.keeping) {
10083                    if (r.lastWakeTime != 0) {
10084                        long wtime;
10085                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10086                        synchronized (stats) {
10087                            wtime = stats.getProcessWakeTime(r.info.uid,
10088                                    r.pid, curRealtime);
10089                        }
10090                        long timeUsed = wtime - r.lastWakeTime;
10091                        pw.print(prefix);
10092                        pw.print("    ");
10093                        pw.print("keep awake over ");
10094                        TimeUtils.formatDuration(realtimeSince, pw);
10095                        pw.print(" used ");
10096                        TimeUtils.formatDuration(timeUsed, pw);
10097                        pw.print(" (");
10098                        pw.print((timeUsed*100)/realtimeSince);
10099                        pw.println("%)");
10100                    }
10101                    if (r.lastCpuTime != 0) {
10102                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10103                        pw.print(prefix);
10104                        pw.print("    ");
10105                        pw.print("run cpu over ");
10106                        TimeUtils.formatDuration(uptimeSince, pw);
10107                        pw.print(" used ");
10108                        TimeUtils.formatDuration(timeUsed, pw);
10109                        pw.print(" (");
10110                        pw.print((timeUsed*100)/uptimeSince);
10111                        pw.println("%)");
10112                    }
10113                }
10114            }
10115        }
10116        return true;
10117    }
10118
10119    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10120        ArrayList<ProcessRecord> procs;
10121        synchronized (this) {
10122            if (args != null && args.length > start
10123                    && args[start].charAt(0) != '-') {
10124                procs = new ArrayList<ProcessRecord>();
10125                int pid = -1;
10126                try {
10127                    pid = Integer.parseInt(args[start]);
10128                } catch (NumberFormatException e) {
10129
10130                }
10131                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10132                    ProcessRecord proc = mLruProcesses.get(i);
10133                    if (proc.pid == pid) {
10134                        procs.add(proc);
10135                    } else if (proc.processName.equals(args[start])) {
10136                        procs.add(proc);
10137                    }
10138                }
10139                if (procs.size() <= 0) {
10140                    pw.println("No process found for: " + args[start]);
10141                    return null;
10142                }
10143            } else {
10144                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10145            }
10146        }
10147        return procs;
10148    }
10149
10150    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10151            PrintWriter pw, String[] args) {
10152        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10153        if (procs == null) {
10154            return;
10155        }
10156
10157        long uptime = SystemClock.uptimeMillis();
10158        long realtime = SystemClock.elapsedRealtime();
10159        pw.println("Applications Graphics Acceleration Info:");
10160        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10161
10162        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10163            ProcessRecord r = procs.get(i);
10164            if (r.thread != null) {
10165                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10166                pw.flush();
10167                try {
10168                    TransferPipe tp = new TransferPipe();
10169                    try {
10170                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10171                        tp.go(fd);
10172                    } finally {
10173                        tp.kill();
10174                    }
10175                } catch (IOException e) {
10176                    pw.println("Failure while dumping the app: " + r);
10177                    pw.flush();
10178                } catch (RemoteException e) {
10179                    pw.println("Got a RemoteException while dumping the app " + r);
10180                    pw.flush();
10181                }
10182            }
10183        }
10184    }
10185
10186    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10187        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10188        if (procs == null) {
10189            return;
10190        }
10191
10192        pw.println("Applications Database Info:");
10193
10194        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10195            ProcessRecord r = procs.get(i);
10196            if (r.thread != null) {
10197                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10198                pw.flush();
10199                try {
10200                    TransferPipe tp = new TransferPipe();
10201                    try {
10202                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10203                        tp.go(fd);
10204                    } finally {
10205                        tp.kill();
10206                    }
10207                } catch (IOException e) {
10208                    pw.println("Failure while dumping the app: " + r);
10209                    pw.flush();
10210                } catch (RemoteException e) {
10211                    pw.println("Got a RemoteException while dumping the app " + r);
10212                    pw.flush();
10213                }
10214            }
10215        }
10216    }
10217
10218    final static class MemItem {
10219        final String label;
10220        final String shortLabel;
10221        final long pss;
10222        final int id;
10223        ArrayList<MemItem> subitems;
10224
10225        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10226            label = _label;
10227            shortLabel = _shortLabel;
10228            pss = _pss;
10229            id = _id;
10230        }
10231    }
10232
10233    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10234            boolean sort) {
10235        if (sort) {
10236            Collections.sort(items, new Comparator<MemItem>() {
10237                @Override
10238                public int compare(MemItem lhs, MemItem rhs) {
10239                    if (lhs.pss < rhs.pss) {
10240                        return 1;
10241                    } else if (lhs.pss > rhs.pss) {
10242                        return -1;
10243                    }
10244                    return 0;
10245                }
10246            });
10247        }
10248
10249        for (int i=0; i<items.size(); i++) {
10250            MemItem mi = items.get(i);
10251            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10252            if (mi.subitems != null) {
10253                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10254            }
10255        }
10256    }
10257
10258    // These are in KB.
10259    static final long[] DUMP_MEM_BUCKETS = new long[] {
10260        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10261        120*1024, 160*1024, 200*1024,
10262        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10263        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10264    };
10265
10266    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10267            boolean stackLike) {
10268        int start = label.lastIndexOf('.');
10269        if (start >= 0) start++;
10270        else start = 0;
10271        int end = label.length();
10272        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10273            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10274                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10275                out.append(bucket);
10276                out.append(stackLike ? "MB." : "MB ");
10277                out.append(label, start, end);
10278                return;
10279            }
10280        }
10281        out.append(memKB/1024);
10282        out.append(stackLike ? "MB." : "MB ");
10283        out.append(label, start, end);
10284    }
10285
10286    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10287            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10288            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10289            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10290            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10291    };
10292    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10293            "System", "Persistent", "Foreground",
10294            "Visible", "Perceptible", "Heavy Weight",
10295            "Backup", "A Services", "Home", "Previous",
10296            "B Services", "Background"
10297    };
10298
10299    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10300            PrintWriter pw, String prefix, String[] args, boolean brief,
10301            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10302        boolean dumpAll = false;
10303        boolean oomOnly = false;
10304
10305        int opti = 0;
10306        while (opti < args.length) {
10307            String opt = args[opti];
10308            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10309                break;
10310            }
10311            opti++;
10312            if ("-a".equals(opt)) {
10313                dumpAll = true;
10314            } else if ("--oom".equals(opt)) {
10315                oomOnly = true;
10316            } else if ("-h".equals(opt)) {
10317                pw.println("meminfo dump options: [-a] [--oom] [process]");
10318                pw.println("  -a: include all available information for each process.");
10319                pw.println("  --oom: only show processes organized by oom adj.");
10320                pw.println("If [process] is specified it can be the name or ");
10321                pw.println("pid of a specific process to dump.");
10322                return;
10323            } else {
10324                pw.println("Unknown argument: " + opt + "; use -h for help");
10325            }
10326        }
10327
10328        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10329        if (procs == null) {
10330            return;
10331        }
10332
10333        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10334        long uptime = SystemClock.uptimeMillis();
10335        long realtime = SystemClock.elapsedRealtime();
10336
10337        if (procs.size() == 1 || isCheckinRequest) {
10338            dumpAll = true;
10339        }
10340
10341        if (isCheckinRequest) {
10342            // short checkin version
10343            pw.println(uptime + "," + realtime);
10344            pw.flush();
10345        } else {
10346            pw.println("Applications Memory Usage (kB):");
10347            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10348        }
10349
10350        String[] innerArgs = new String[args.length-opti];
10351        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10352
10353        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10354        long nativePss=0, dalvikPss=0, otherPss=0;
10355        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10356
10357        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10358        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10359                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10360
10361        long totalPss = 0;
10362
10363        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10364            ProcessRecord r = procs.get(i);
10365            if (r.thread != null) {
10366                if (!isCheckinRequest && dumpAll) {
10367                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10368                    pw.flush();
10369                }
10370                Debug.MemoryInfo mi = null;
10371                if (dumpAll) {
10372                    try {
10373                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10374                    } catch (RemoteException e) {
10375                        if (!isCheckinRequest) {
10376                            pw.println("Got RemoteException!");
10377                            pw.flush();
10378                        }
10379                    }
10380                } else {
10381                    mi = new Debug.MemoryInfo();
10382                    Debug.getMemoryInfo(r.pid, mi);
10383                }
10384
10385                if (!isCheckinRequest && mi != null) {
10386                    long myTotalPss = mi.getTotalPss();
10387                    totalPss += myTotalPss;
10388                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10389                            r.processName, myTotalPss, 0);
10390                    procMems.add(pssItem);
10391
10392                    nativePss += mi.nativePss;
10393                    dalvikPss += mi.dalvikPss;
10394                    otherPss += mi.otherPss;
10395                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10396                        long mem = mi.getOtherPss(j);
10397                        miscPss[j] += mem;
10398                        otherPss -= mem;
10399                    }
10400
10401                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10402                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10403                                || oomIndex == (oomPss.length-1)) {
10404                            oomPss[oomIndex] += myTotalPss;
10405                            if (oomProcs[oomIndex] == null) {
10406                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10407                            }
10408                            oomProcs[oomIndex].add(pssItem);
10409                            break;
10410                        }
10411                    }
10412                }
10413            }
10414        }
10415
10416        if (!isCheckinRequest && procs.size() > 1) {
10417            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10418
10419            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10420            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10421            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10422            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10423                String label = Debug.MemoryInfo.getOtherLabel(j);
10424                catMems.add(new MemItem(label, label, miscPss[j], j));
10425            }
10426
10427            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10428            for (int j=0; j<oomPss.length; j++) {
10429                if (oomPss[j] != 0) {
10430                    String label = DUMP_MEM_OOM_LABEL[j];
10431                    MemItem item = new MemItem(label, label, oomPss[j],
10432                            DUMP_MEM_OOM_ADJ[j]);
10433                    item.subitems = oomProcs[j];
10434                    oomMems.add(item);
10435                }
10436            }
10437
10438            if (outTag != null || outStack != null) {
10439                if (outTag != null) {
10440                    appendMemBucket(outTag, totalPss, "total", false);
10441                }
10442                if (outStack != null) {
10443                    appendMemBucket(outStack, totalPss, "total", true);
10444                }
10445                boolean firstLine = true;
10446                for (int i=0; i<oomMems.size(); i++) {
10447                    MemItem miCat = oomMems.get(i);
10448                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10449                        continue;
10450                    }
10451                    if (miCat.id < ProcessList.SERVICE_ADJ
10452                            || miCat.id == ProcessList.HOME_APP_ADJ
10453                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10454                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10455                            outTag.append(" / ");
10456                        }
10457                        if (outStack != null) {
10458                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10459                                if (firstLine) {
10460                                    outStack.append(":");
10461                                    firstLine = false;
10462                                }
10463                                outStack.append("\n\t at ");
10464                            } else {
10465                                outStack.append("$");
10466                            }
10467                        }
10468                        for (int j=0; j<miCat.subitems.size(); j++) {
10469                            MemItem mi = miCat.subitems.get(j);
10470                            if (j > 0) {
10471                                if (outTag != null) {
10472                                    outTag.append(" ");
10473                                }
10474                                if (outStack != null) {
10475                                    outStack.append("$");
10476                                }
10477                            }
10478                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10479                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10480                            }
10481                            if (outStack != null) {
10482                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10483                            }
10484                        }
10485                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10486                            outStack.append("(");
10487                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10488                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10489                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10490                                    outStack.append(":");
10491                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10492                                }
10493                            }
10494                            outStack.append(")");
10495                        }
10496                    }
10497                }
10498            }
10499
10500            if (!brief && !oomOnly) {
10501                pw.println();
10502                pw.println("Total PSS by process:");
10503                dumpMemItems(pw, "  ", procMems, true);
10504                pw.println();
10505            }
10506            pw.println("Total PSS by OOM adjustment:");
10507            dumpMemItems(pw, "  ", oomMems, false);
10508            if (!oomOnly) {
10509                PrintWriter out = categoryPw != null ? categoryPw : pw;
10510                out.println();
10511                out.println("Total PSS by category:");
10512                dumpMemItems(out, "  ", catMems, true);
10513            }
10514            pw.println();
10515            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10516            final int[] SINGLE_LONG_FORMAT = new int[] {
10517                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10518            };
10519            long[] longOut = new long[1];
10520            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10521                    SINGLE_LONG_FORMAT, null, longOut, null);
10522            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10523            longOut[0] = 0;
10524            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10525                    SINGLE_LONG_FORMAT, null, longOut, null);
10526            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10527            longOut[0] = 0;
10528            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10529                    SINGLE_LONG_FORMAT, null, longOut, null);
10530            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10531            longOut[0] = 0;
10532            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10533                    SINGLE_LONG_FORMAT, null, longOut, null);
10534            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10535            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10536                    pw.print(shared); pw.println(" kB");
10537            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10538                    pw.print(voltile); pw.println(" kB volatile");
10539        }
10540    }
10541
10542    /**
10543     * Searches array of arguments for the specified string
10544     * @param args array of argument strings
10545     * @param value value to search for
10546     * @return true if the value is contained in the array
10547     */
10548    private static boolean scanArgs(String[] args, String value) {
10549        if (args != null) {
10550            for (String arg : args) {
10551                if (value.equals(arg)) {
10552                    return true;
10553                }
10554            }
10555        }
10556        return false;
10557    }
10558
10559    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10560            ContentProviderRecord cpr, boolean always) {
10561        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10562
10563        if (!inLaunching || always) {
10564            synchronized (cpr) {
10565                cpr.launchingApp = null;
10566                cpr.notifyAll();
10567            }
10568            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10569            String names[] = cpr.info.authority.split(";");
10570            for (int j = 0; j < names.length; j++) {
10571                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10572            }
10573        }
10574
10575        for (int i=0; i<cpr.connections.size(); i++) {
10576            ContentProviderConnection conn = cpr.connections.get(i);
10577            if (conn.waiting) {
10578                // If this connection is waiting for the provider, then we don't
10579                // need to mess with its process unless we are always removing
10580                // or for some reason the provider is not currently launching.
10581                if (inLaunching && !always) {
10582                    continue;
10583                }
10584            }
10585            ProcessRecord capp = conn.client;
10586            conn.dead = true;
10587            if (conn.stableCount > 0) {
10588                if (!capp.persistent && capp.thread != null
10589                        && capp.pid != 0
10590                        && capp.pid != MY_PID) {
10591                    Slog.i(TAG, "Kill " + capp.processName
10592                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10593                            + " in dying process " + (proc != null ? proc.processName : "??"));
10594                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10595                            capp.processName, capp.setAdj, "dying provider "
10596                                    + cpr.name.toShortString());
10597                    Process.killProcessQuiet(capp.pid);
10598                }
10599            } else if (capp.thread != null && conn.provider.provider != null) {
10600                try {
10601                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10602                } catch (RemoteException e) {
10603                }
10604                // In the protocol here, we don't expect the client to correctly
10605                // clean up this connection, we'll just remove it.
10606                cpr.connections.remove(i);
10607                conn.client.conProviders.remove(conn);
10608            }
10609        }
10610
10611        if (inLaunching && always) {
10612            mLaunchingProviders.remove(cpr);
10613        }
10614        return inLaunching;
10615    }
10616
10617    /**
10618     * Main code for cleaning up a process when it has gone away.  This is
10619     * called both as a result of the process dying, or directly when stopping
10620     * a process when running in single process mode.
10621     */
10622    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10623            boolean restarting, boolean allowRestart, int index) {
10624        if (index >= 0) {
10625            mLruProcesses.remove(index);
10626        }
10627
10628        mProcessesToGc.remove(app);
10629
10630        // Dismiss any open dialogs.
10631        if (app.crashDialog != null) {
10632            app.crashDialog.dismiss();
10633            app.crashDialog = null;
10634        }
10635        if (app.anrDialog != null) {
10636            app.anrDialog.dismiss();
10637            app.anrDialog = null;
10638        }
10639        if (app.waitDialog != null) {
10640            app.waitDialog.dismiss();
10641            app.waitDialog = null;
10642        }
10643
10644        app.crashing = false;
10645        app.notResponding = false;
10646
10647        app.resetPackageList();
10648        app.unlinkDeathRecipient();
10649        app.thread = null;
10650        app.forcingToForeground = null;
10651        app.foregroundServices = false;
10652        app.foregroundActivities = false;
10653        app.hasShownUi = false;
10654        app.hasAboveClient = false;
10655
10656        mServices.killServicesLocked(app, allowRestart);
10657
10658        boolean restart = false;
10659
10660        // Remove published content providers.
10661        if (!app.pubProviders.isEmpty()) {
10662            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10663            while (it.hasNext()) {
10664                ContentProviderRecord cpr = it.next();
10665
10666                final boolean always = app.bad || !allowRestart;
10667                if (removeDyingProviderLocked(app, cpr, always) || always) {
10668                    // We left the provider in the launching list, need to
10669                    // restart it.
10670                    restart = true;
10671                }
10672
10673                cpr.provider = null;
10674                cpr.proc = null;
10675            }
10676            app.pubProviders.clear();
10677        }
10678
10679        // Take care of any launching providers waiting for this process.
10680        if (checkAppInLaunchingProvidersLocked(app, false)) {
10681            restart = true;
10682        }
10683
10684        // Unregister from connected content providers.
10685        if (!app.conProviders.isEmpty()) {
10686            for (int i=0; i<app.conProviders.size(); i++) {
10687                ContentProviderConnection conn = app.conProviders.get(i);
10688                conn.provider.connections.remove(conn);
10689            }
10690            app.conProviders.clear();
10691        }
10692
10693        // At this point there may be remaining entries in mLaunchingProviders
10694        // where we were the only one waiting, so they are no longer of use.
10695        // Look for these and clean up if found.
10696        // XXX Commented out for now.  Trying to figure out a way to reproduce
10697        // the actual situation to identify what is actually going on.
10698        if (false) {
10699            for (int i=0; i<mLaunchingProviders.size(); i++) {
10700                ContentProviderRecord cpr = (ContentProviderRecord)
10701                        mLaunchingProviders.get(i);
10702                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10703                    synchronized (cpr) {
10704                        cpr.launchingApp = null;
10705                        cpr.notifyAll();
10706                    }
10707                }
10708            }
10709        }
10710
10711        skipCurrentReceiverLocked(app);
10712
10713        // Unregister any receivers.
10714        if (app.receivers.size() > 0) {
10715            Iterator<ReceiverList> it = app.receivers.iterator();
10716            while (it.hasNext()) {
10717                removeReceiverLocked(it.next());
10718            }
10719            app.receivers.clear();
10720        }
10721
10722        // If the app is undergoing backup, tell the backup manager about it
10723        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10724            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10725            try {
10726                IBackupManager bm = IBackupManager.Stub.asInterface(
10727                        ServiceManager.getService(Context.BACKUP_SERVICE));
10728                bm.agentDisconnected(app.info.packageName);
10729            } catch (RemoteException e) {
10730                // can't happen; backup manager is local
10731            }
10732        }
10733
10734        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10735            ProcessChangeItem item = mPendingProcessChanges.get(i);
10736            if (item.pid == app.pid) {
10737                mPendingProcessChanges.remove(i);
10738                mAvailProcessChanges.add(item);
10739            }
10740        }
10741        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10742
10743        // If the caller is restarting this app, then leave it in its
10744        // current lists and let the caller take care of it.
10745        if (restarting) {
10746            return;
10747        }
10748
10749        if (!app.persistent || app.isolated) {
10750            if (DEBUG_PROCESSES) Slog.v(TAG,
10751                    "Removing non-persistent process during cleanup: " + app);
10752            mProcessNames.remove(app.processName, app.uid);
10753            mIsolatedProcesses.remove(app.uid);
10754            if (mHeavyWeightProcess == app) {
10755                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10756                        mHeavyWeightProcess.userId, 0));
10757                mHeavyWeightProcess = null;
10758            }
10759        } else if (!app.removed) {
10760            // This app is persistent, so we need to keep its record around.
10761            // If it is not already on the pending app list, add it there
10762            // and start a new process for it.
10763            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10764                mPersistentStartingProcesses.add(app);
10765                restart = true;
10766            }
10767        }
10768        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10769                "Clean-up removing on hold: " + app);
10770        mProcessesOnHold.remove(app);
10771
10772        if (app == mHomeProcess) {
10773            mHomeProcess = null;
10774        }
10775        if (app == mPreviousProcess) {
10776            mPreviousProcess = null;
10777        }
10778
10779        if (restart && !app.isolated) {
10780            // We have components that still need to be running in the
10781            // process, so re-launch it.
10782            mProcessNames.put(app.processName, app.uid, app);
10783            startProcessLocked(app, "restart", app.processName);
10784        } else if (app.pid > 0 && app.pid != MY_PID) {
10785            // Goodbye!
10786            synchronized (mPidsSelfLocked) {
10787                mPidsSelfLocked.remove(app.pid);
10788                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10789            }
10790            app.setPid(0);
10791        }
10792    }
10793
10794    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10795        // Look through the content providers we are waiting to have launched,
10796        // and if any run in this process then either schedule a restart of
10797        // the process or kill the client waiting for it if this process has
10798        // gone bad.
10799        int NL = mLaunchingProviders.size();
10800        boolean restart = false;
10801        for (int i=0; i<NL; i++) {
10802            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10803            if (cpr.launchingApp == app) {
10804                if (!alwaysBad && !app.bad) {
10805                    restart = true;
10806                } else {
10807                    removeDyingProviderLocked(app, cpr, true);
10808                    // cpr should have been removed from mLaunchingProviders
10809                    NL = mLaunchingProviders.size();
10810                    i--;
10811                }
10812            }
10813        }
10814        return restart;
10815    }
10816
10817    // =========================================================
10818    // SERVICES
10819    // =========================================================
10820
10821    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10822            int flags) {
10823        enforceNotIsolatedCaller("getServices");
10824        synchronized (this) {
10825            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10826        }
10827    }
10828
10829    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10830        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10831        synchronized (this) {
10832            return mServices.getRunningServiceControlPanelLocked(name);
10833        }
10834    }
10835
10836    public ComponentName startService(IApplicationThread caller, Intent service,
10837            String resolvedType, int userId) {
10838        enforceNotIsolatedCaller("startService");
10839        // Refuse possible leaked file descriptors
10840        if (service != null && service.hasFileDescriptors() == true) {
10841            throw new IllegalArgumentException("File descriptors passed in Intent");
10842        }
10843
10844        if (DEBUG_SERVICE)
10845            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10846        synchronized(this) {
10847            final int callingPid = Binder.getCallingPid();
10848            final int callingUid = Binder.getCallingUid();
10849            checkValidCaller(callingUid, userId);
10850            final long origId = Binder.clearCallingIdentity();
10851            ComponentName res = mServices.startServiceLocked(caller, service,
10852                    resolvedType, callingPid, callingUid, userId);
10853            Binder.restoreCallingIdentity(origId);
10854            return res;
10855        }
10856    }
10857
10858    ComponentName startServiceInPackage(int uid,
10859            Intent service, String resolvedType, int userId) {
10860        synchronized(this) {
10861            if (DEBUG_SERVICE)
10862                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10863            final long origId = Binder.clearCallingIdentity();
10864            ComponentName res = mServices.startServiceLocked(null, service,
10865                    resolvedType, -1, uid, userId);
10866            Binder.restoreCallingIdentity(origId);
10867            return res;
10868        }
10869    }
10870
10871    public int stopService(IApplicationThread caller, Intent service,
10872            String resolvedType, int userId) {
10873        enforceNotIsolatedCaller("stopService");
10874        // Refuse possible leaked file descriptors
10875        if (service != null && service.hasFileDescriptors() == true) {
10876            throw new IllegalArgumentException("File descriptors passed in Intent");
10877        }
10878
10879        checkValidCaller(Binder.getCallingUid(), userId);
10880
10881        synchronized(this) {
10882            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10883        }
10884    }
10885
10886    public IBinder peekService(Intent service, String resolvedType) {
10887        enforceNotIsolatedCaller("peekService");
10888        // Refuse possible leaked file descriptors
10889        if (service != null && service.hasFileDescriptors() == true) {
10890            throw new IllegalArgumentException("File descriptors passed in Intent");
10891        }
10892        synchronized(this) {
10893            return mServices.peekServiceLocked(service, resolvedType);
10894        }
10895    }
10896
10897    public boolean stopServiceToken(ComponentName className, IBinder token,
10898            int startId) {
10899        synchronized(this) {
10900            return mServices.stopServiceTokenLocked(className, token, startId);
10901        }
10902    }
10903
10904    public void setServiceForeground(ComponentName className, IBinder token,
10905            int id, Notification notification, boolean removeNotification) {
10906        synchronized(this) {
10907            mServices.setServiceForegroundLocked(className, token, id, notification,
10908                    removeNotification);
10909        }
10910    }
10911
10912    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10913            boolean requireFull, String name, String callerPackage) {
10914        final int callingUserId = UserHandle.getUserId(callingUid);
10915        if (callingUserId != userId) {
10916            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10917                if ((requireFull || checkComponentPermission(
10918                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10919                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10920                        && checkComponentPermission(
10921                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10922                                callingPid, callingUid, -1, true)
10923                                != PackageManager.PERMISSION_GRANTED) {
10924                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10925                        // In this case, they would like to just execute as their
10926                        // owner user instead of failing.
10927                        userId = callingUserId;
10928                    } else {
10929                        StringBuilder builder = new StringBuilder(128);
10930                        builder.append("Permission Denial: ");
10931                        builder.append(name);
10932                        if (callerPackage != null) {
10933                            builder.append(" from ");
10934                            builder.append(callerPackage);
10935                        }
10936                        builder.append(" asks to run as user ");
10937                        builder.append(userId);
10938                        builder.append(" but is calling from user ");
10939                        builder.append(UserHandle.getUserId(callingUid));
10940                        builder.append("; this requires ");
10941                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10942                        if (!requireFull) {
10943                            builder.append(" or ");
10944                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10945                        }
10946                        String msg = builder.toString();
10947                        Slog.w(TAG, msg);
10948                        throw new SecurityException(msg);
10949                    }
10950                }
10951            }
10952            if (userId == UserHandle.USER_CURRENT
10953                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10954                // Note that we may be accessing this outside of a lock...
10955                // shouldn't be a big deal, if this is being called outside
10956                // of a locked context there is intrinsically a race with
10957                // the value the caller will receive and someone else changing it.
10958                userId = mCurrentUserId;
10959            }
10960            if (!allowAll && userId < 0) {
10961                throw new IllegalArgumentException(
10962                        "Call does not support special user #" + userId);
10963            }
10964        }
10965        return userId;
10966    }
10967
10968    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10969            String className, int flags) {
10970        boolean result = false;
10971        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10972            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10973                if (ActivityManager.checkUidPermission(
10974                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10975                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10976                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10977                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10978                            + " requests FLAG_SINGLE_USER, but app does not hold "
10979                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10980                    Slog.w(TAG, msg);
10981                    throw new SecurityException(msg);
10982                }
10983                result = true;
10984            }
10985        } else if (componentProcessName == aInfo.packageName) {
10986            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10987        } else if ("system".equals(componentProcessName)) {
10988            result = true;
10989        }
10990        if (DEBUG_MU) {
10991            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10992                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10993        }
10994        return result;
10995    }
10996
10997    public int bindService(IApplicationThread caller, IBinder token,
10998            Intent service, String resolvedType,
10999            IServiceConnection connection, int flags, int userId) {
11000        enforceNotIsolatedCaller("bindService");
11001        // Refuse possible leaked file descriptors
11002        if (service != null && service.hasFileDescriptors() == true) {
11003            throw new IllegalArgumentException("File descriptors passed in Intent");
11004        }
11005
11006        synchronized(this) {
11007            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11008                    connection, flags, userId);
11009        }
11010    }
11011
11012    public boolean unbindService(IServiceConnection connection) {
11013        synchronized (this) {
11014            return mServices.unbindServiceLocked(connection);
11015        }
11016    }
11017
11018    public void publishService(IBinder token, Intent intent, IBinder service) {
11019        // Refuse possible leaked file descriptors
11020        if (intent != null && intent.hasFileDescriptors() == true) {
11021            throw new IllegalArgumentException("File descriptors passed in Intent");
11022        }
11023
11024        synchronized(this) {
11025            if (!(token instanceof ServiceRecord)) {
11026                throw new IllegalArgumentException("Invalid service token");
11027            }
11028            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11029        }
11030    }
11031
11032    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11033        // Refuse possible leaked file descriptors
11034        if (intent != null && intent.hasFileDescriptors() == true) {
11035            throw new IllegalArgumentException("File descriptors passed in Intent");
11036        }
11037
11038        synchronized(this) {
11039            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11040        }
11041    }
11042
11043    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11044        synchronized(this) {
11045            if (!(token instanceof ServiceRecord)) {
11046                throw new IllegalArgumentException("Invalid service token");
11047            }
11048            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11049        }
11050    }
11051
11052    // =========================================================
11053    // BACKUP AND RESTORE
11054    // =========================================================
11055
11056    // Cause the target app to be launched if necessary and its backup agent
11057    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11058    // activity manager to announce its creation.
11059    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11060        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11061        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11062
11063        synchronized(this) {
11064            // !!! TODO: currently no check here that we're already bound
11065            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11066            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11067            synchronized (stats) {
11068                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11069            }
11070
11071            // Backup agent is now in use, its package can't be stopped.
11072            try {
11073                AppGlobals.getPackageManager().setPackageStoppedState(
11074                        app.packageName, false, UserHandle.getUserId(app.uid));
11075            } catch (RemoteException e) {
11076            } catch (IllegalArgumentException e) {
11077                Slog.w(TAG, "Failed trying to unstop package "
11078                        + app.packageName + ": " + e);
11079            }
11080
11081            BackupRecord r = new BackupRecord(ss, app, backupMode);
11082            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11083                    ? new ComponentName(app.packageName, app.backupAgentName)
11084                    : new ComponentName("android", "FullBackupAgent");
11085            // startProcessLocked() returns existing proc's record if it's already running
11086            ProcessRecord proc = startProcessLocked(app.processName, app,
11087                    false, 0, "backup", hostingName, false, false);
11088            if (proc == null) {
11089                Slog.e(TAG, "Unable to start backup agent process " + r);
11090                return false;
11091            }
11092
11093            r.app = proc;
11094            mBackupTarget = r;
11095            mBackupAppName = app.packageName;
11096
11097            // Try not to kill the process during backup
11098            updateOomAdjLocked(proc);
11099
11100            // If the process is already attached, schedule the creation of the backup agent now.
11101            // If it is not yet live, this will be done when it attaches to the framework.
11102            if (proc.thread != null) {
11103                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11104                try {
11105                    proc.thread.scheduleCreateBackupAgent(app,
11106                            compatibilityInfoForPackageLocked(app), backupMode);
11107                } catch (RemoteException e) {
11108                    // Will time out on the backup manager side
11109                }
11110            } else {
11111                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11112            }
11113            // Invariants: at this point, the target app process exists and the application
11114            // is either already running or in the process of coming up.  mBackupTarget and
11115            // mBackupAppName describe the app, so that when it binds back to the AM we
11116            // know that it's scheduled for a backup-agent operation.
11117        }
11118
11119        return true;
11120    }
11121
11122    // A backup agent has just come up
11123    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11124        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11125                + " = " + agent);
11126
11127        synchronized(this) {
11128            if (!agentPackageName.equals(mBackupAppName)) {
11129                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11130                return;
11131            }
11132        }
11133
11134        long oldIdent = Binder.clearCallingIdentity();
11135        try {
11136            IBackupManager bm = IBackupManager.Stub.asInterface(
11137                    ServiceManager.getService(Context.BACKUP_SERVICE));
11138            bm.agentConnected(agentPackageName, agent);
11139        } catch (RemoteException e) {
11140            // can't happen; the backup manager service is local
11141        } catch (Exception e) {
11142            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11143            e.printStackTrace();
11144        } finally {
11145            Binder.restoreCallingIdentity(oldIdent);
11146        }
11147    }
11148
11149    // done with this agent
11150    public void unbindBackupAgent(ApplicationInfo appInfo) {
11151        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11152        if (appInfo == null) {
11153            Slog.w(TAG, "unbind backup agent for null app");
11154            return;
11155        }
11156
11157        synchronized(this) {
11158            if (mBackupAppName == null) {
11159                Slog.w(TAG, "Unbinding backup agent with no active backup");
11160                return;
11161            }
11162
11163            if (!mBackupAppName.equals(appInfo.packageName)) {
11164                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11165                return;
11166            }
11167
11168            ProcessRecord proc = mBackupTarget.app;
11169            mBackupTarget = null;
11170            mBackupAppName = null;
11171
11172            // Not backing this app up any more; reset its OOM adjustment
11173            updateOomAdjLocked(proc);
11174
11175            // If the app crashed during backup, 'thread' will be null here
11176            if (proc.thread != null) {
11177                try {
11178                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11179                            compatibilityInfoForPackageLocked(appInfo));
11180                } catch (Exception e) {
11181                    Slog.e(TAG, "Exception when unbinding backup agent:");
11182                    e.printStackTrace();
11183                }
11184            }
11185        }
11186    }
11187    // =========================================================
11188    // BROADCASTS
11189    // =========================================================
11190
11191    private final List getStickiesLocked(String action, IntentFilter filter,
11192            List cur, int userId) {
11193        final ContentResolver resolver = mContext.getContentResolver();
11194        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11195        if (stickies == null) {
11196            return cur;
11197        }
11198        final ArrayList<Intent> list = stickies.get(action);
11199        if (list == null) {
11200            return cur;
11201        }
11202        int N = list.size();
11203        for (int i=0; i<N; i++) {
11204            Intent intent = list.get(i);
11205            if (filter.match(resolver, intent, true, TAG) >= 0) {
11206                if (cur == null) {
11207                    cur = new ArrayList<Intent>();
11208                }
11209                cur.add(intent);
11210            }
11211        }
11212        return cur;
11213    }
11214
11215    boolean isPendingBroadcastProcessLocked(int pid) {
11216        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11217                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11218    }
11219
11220    void skipPendingBroadcastLocked(int pid) {
11221            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11222            for (BroadcastQueue queue : mBroadcastQueues) {
11223                queue.skipPendingBroadcastLocked(pid);
11224            }
11225    }
11226
11227    // The app just attached; send any pending broadcasts that it should receive
11228    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11229        boolean didSomething = false;
11230        for (BroadcastQueue queue : mBroadcastQueues) {
11231            didSomething |= queue.sendPendingBroadcastsLocked(app);
11232        }
11233        return didSomething;
11234    }
11235
11236    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11237            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11238        enforceNotIsolatedCaller("registerReceiver");
11239        int callingUid;
11240        int callingPid;
11241        synchronized(this) {
11242            ProcessRecord callerApp = null;
11243            if (caller != null) {
11244                callerApp = getRecordForAppLocked(caller);
11245                if (callerApp == null) {
11246                    throw new SecurityException(
11247                            "Unable to find app for caller " + caller
11248                            + " (pid=" + Binder.getCallingPid()
11249                            + ") when registering receiver " + receiver);
11250                }
11251                if (callerApp.info.uid != Process.SYSTEM_UID &&
11252                        !callerApp.pkgList.contains(callerPackage)) {
11253                    throw new SecurityException("Given caller package " + callerPackage
11254                            + " is not running in process " + callerApp);
11255                }
11256                callingUid = callerApp.info.uid;
11257                callingPid = callerApp.pid;
11258            } else {
11259                callerPackage = null;
11260                callingUid = Binder.getCallingUid();
11261                callingPid = Binder.getCallingPid();
11262            }
11263
11264            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11265                    true, true, "registerReceiver", callerPackage);
11266
11267            List allSticky = null;
11268
11269            // Look for any matching sticky broadcasts...
11270            Iterator actions = filter.actionsIterator();
11271            if (actions != null) {
11272                while (actions.hasNext()) {
11273                    String action = (String)actions.next();
11274                    allSticky = getStickiesLocked(action, filter, allSticky,
11275                            UserHandle.USER_ALL);
11276                    allSticky = getStickiesLocked(action, filter, allSticky,
11277                            UserHandle.getUserId(callingUid));
11278                }
11279            } else {
11280                allSticky = getStickiesLocked(null, filter, allSticky,
11281                        UserHandle.USER_ALL);
11282                allSticky = getStickiesLocked(null, filter, allSticky,
11283                        UserHandle.getUserId(callingUid));
11284            }
11285
11286            // The first sticky in the list is returned directly back to
11287            // the client.
11288            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11289
11290            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11291                    + ": " + sticky);
11292
11293            if (receiver == null) {
11294                return sticky;
11295            }
11296
11297            ReceiverList rl
11298                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11299            if (rl == null) {
11300                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11301                        userId, receiver);
11302                if (rl.app != null) {
11303                    rl.app.receivers.add(rl);
11304                } else {
11305                    try {
11306                        receiver.asBinder().linkToDeath(rl, 0);
11307                    } catch (RemoteException e) {
11308                        return sticky;
11309                    }
11310                    rl.linkedToDeath = true;
11311                }
11312                mRegisteredReceivers.put(receiver.asBinder(), rl);
11313            } else if (rl.uid != callingUid) {
11314                throw new IllegalArgumentException(
11315                        "Receiver requested to register for uid " + callingUid
11316                        + " was previously registered for uid " + rl.uid);
11317            } else if (rl.pid != callingPid) {
11318                throw new IllegalArgumentException(
11319                        "Receiver requested to register for pid " + callingPid
11320                        + " was previously registered for pid " + rl.pid);
11321            } else if (rl.userId != userId) {
11322                throw new IllegalArgumentException(
11323                        "Receiver requested to register for user " + userId
11324                        + " was previously registered for user " + rl.userId);
11325            }
11326            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11327                    permission, callingUid, userId);
11328            rl.add(bf);
11329            if (!bf.debugCheck()) {
11330                Slog.w(TAG, "==> For Dynamic broadast");
11331            }
11332            mReceiverResolver.addFilter(bf);
11333
11334            // Enqueue broadcasts for all existing stickies that match
11335            // this filter.
11336            if (allSticky != null) {
11337                ArrayList receivers = new ArrayList();
11338                receivers.add(bf);
11339
11340                int N = allSticky.size();
11341                for (int i=0; i<N; i++) {
11342                    Intent intent = (Intent)allSticky.get(i);
11343                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11344                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11345                            null, -1, -1, null, receivers, null, 0, null, null,
11346                            false, true, true, -1);
11347                    queue.enqueueParallelBroadcastLocked(r);
11348                    queue.scheduleBroadcastsLocked();
11349                }
11350            }
11351
11352            return sticky;
11353        }
11354    }
11355
11356    public void unregisterReceiver(IIntentReceiver receiver) {
11357        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11358
11359        final long origId = Binder.clearCallingIdentity();
11360        try {
11361            boolean doTrim = false;
11362
11363            synchronized(this) {
11364                ReceiverList rl
11365                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11366                if (rl != null) {
11367                    if (rl.curBroadcast != null) {
11368                        BroadcastRecord r = rl.curBroadcast;
11369                        final boolean doNext = finishReceiverLocked(
11370                                receiver.asBinder(), r.resultCode, r.resultData,
11371                                r.resultExtras, r.resultAbort, true);
11372                        if (doNext) {
11373                            doTrim = true;
11374                            r.queue.processNextBroadcast(false);
11375                        }
11376                    }
11377
11378                    if (rl.app != null) {
11379                        rl.app.receivers.remove(rl);
11380                    }
11381                    removeReceiverLocked(rl);
11382                    if (rl.linkedToDeath) {
11383                        rl.linkedToDeath = false;
11384                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11385                    }
11386                }
11387            }
11388
11389            // If we actually concluded any broadcasts, we might now be able
11390            // to trim the recipients' apps from our working set
11391            if (doTrim) {
11392                trimApplications();
11393                return;
11394            }
11395
11396        } finally {
11397            Binder.restoreCallingIdentity(origId);
11398        }
11399    }
11400
11401    void removeReceiverLocked(ReceiverList rl) {
11402        mRegisteredReceivers.remove(rl.receiver.asBinder());
11403        int N = rl.size();
11404        for (int i=0; i<N; i++) {
11405            mReceiverResolver.removeFilter(rl.get(i));
11406        }
11407    }
11408
11409    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11410        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11411            ProcessRecord r = mLruProcesses.get(i);
11412            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11413                try {
11414                    r.thread.dispatchPackageBroadcast(cmd, packages);
11415                } catch (RemoteException ex) {
11416                }
11417            }
11418        }
11419    }
11420
11421    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11422            int[] users) {
11423        List<ResolveInfo> receivers = null;
11424        try {
11425            HashSet<ComponentName> singleUserReceivers = null;
11426            boolean scannedFirstReceivers = false;
11427            for (int user : users) {
11428                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11429                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11430                if (newReceivers != null && newReceivers.size() == 0) {
11431                    newReceivers = null;
11432                }
11433                if (receivers == null) {
11434                    receivers = newReceivers;
11435                } else if (newReceivers != null) {
11436                    // We need to concatenate the additional receivers
11437                    // found with what we have do far.  This would be easy,
11438                    // but we also need to de-dup any receivers that are
11439                    // singleUser.
11440                    if (!scannedFirstReceivers) {
11441                        // Collect any single user receivers we had already retrieved.
11442                        scannedFirstReceivers = true;
11443                        for (int i=0; i<receivers.size(); i++) {
11444                            ResolveInfo ri = receivers.get(i);
11445                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11446                                ComponentName cn = new ComponentName(
11447                                        ri.activityInfo.packageName, ri.activityInfo.name);
11448                                if (singleUserReceivers == null) {
11449                                    singleUserReceivers = new HashSet<ComponentName>();
11450                                }
11451                                singleUserReceivers.add(cn);
11452                            }
11453                        }
11454                    }
11455                    // Add the new results to the existing results, tracking
11456                    // and de-dupping single user receivers.
11457                    for (int i=0; i<newReceivers.size(); i++) {
11458                        ResolveInfo ri = newReceivers.get(i);
11459                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11460                            ComponentName cn = new ComponentName(
11461                                    ri.activityInfo.packageName, ri.activityInfo.name);
11462                            if (singleUserReceivers == null) {
11463                                singleUserReceivers = new HashSet<ComponentName>();
11464                            }
11465                            if (!singleUserReceivers.contains(cn)) {
11466                                singleUserReceivers.add(cn);
11467                                receivers.add(ri);
11468                            }
11469                        } else {
11470                            receivers.add(ri);
11471                        }
11472                    }
11473                }
11474            }
11475        } catch (RemoteException ex) {
11476            // pm is in same process, this will never happen.
11477        }
11478        return receivers;
11479    }
11480
11481    private final int broadcastIntentLocked(ProcessRecord callerApp,
11482            String callerPackage, Intent intent, String resolvedType,
11483            IIntentReceiver resultTo, int resultCode, String resultData,
11484            Bundle map, String requiredPermission,
11485            boolean ordered, boolean sticky, int callingPid, int callingUid,
11486            int userId) {
11487        intent = new Intent(intent);
11488
11489        // By default broadcasts do not go to stopped apps.
11490        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11491
11492        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11493            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11494            + " ordered=" + ordered + " userid=" + userId);
11495        if ((resultTo != null) && !ordered) {
11496            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11497        }
11498
11499        userId = handleIncomingUser(callingPid, callingUid, userId,
11500                true, false, "broadcast", callerPackage);
11501
11502        // Make sure that the user who is receiving this broadcast is started.
11503        // If not, we will just skip it.
11504        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11505            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11506                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11507                Slog.w(TAG, "Skipping broadcast of " + intent
11508                        + ": user " + userId + " is stopped");
11509                return ActivityManager.BROADCAST_SUCCESS;
11510            }
11511        }
11512
11513        /*
11514         * Prevent non-system code (defined here to be non-persistent
11515         * processes) from sending protected broadcasts.
11516         */
11517        int callingAppId = UserHandle.getAppId(callingUid);
11518        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11519            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11520            callingUid == 0) {
11521            // Always okay.
11522        } else if (callerApp == null || !callerApp.persistent) {
11523            try {
11524                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11525                        intent.getAction())) {
11526                    String msg = "Permission Denial: not allowed to send broadcast "
11527                            + intent.getAction() + " from pid="
11528                            + callingPid + ", uid=" + callingUid;
11529                    Slog.w(TAG, msg);
11530                    throw new SecurityException(msg);
11531                }
11532            } catch (RemoteException e) {
11533                Slog.w(TAG, "Remote exception", e);
11534                return ActivityManager.BROADCAST_SUCCESS;
11535            }
11536        }
11537
11538        // Handle special intents: if this broadcast is from the package
11539        // manager about a package being removed, we need to remove all of
11540        // its activities from the history stack.
11541        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11542                intent.getAction());
11543        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11544                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11545                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11546                || uidRemoved) {
11547            if (checkComponentPermission(
11548                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11549                    callingPid, callingUid, -1, true)
11550                    == PackageManager.PERMISSION_GRANTED) {
11551                if (uidRemoved) {
11552                    final Bundle intentExtras = intent.getExtras();
11553                    final int uid = intentExtras != null
11554                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11555                    if (uid >= 0) {
11556                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11557                        synchronized (bs) {
11558                            bs.removeUidStatsLocked(uid);
11559                        }
11560                    }
11561                } else {
11562                    // If resources are unavailable just force stop all
11563                    // those packages and flush the attribute cache as well.
11564                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11565                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11566                        if (list != null && (list.length > 0)) {
11567                            for (String pkg : list) {
11568                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11569                            }
11570                            sendPackageBroadcastLocked(
11571                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11572                        }
11573                    } else {
11574                        Uri data = intent.getData();
11575                        String ssp;
11576                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11577                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11578                                forceStopPackageLocked(ssp,
11579                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11580                                        false, userId);
11581                            }
11582                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11583                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11584                                        new String[] {ssp}, userId);
11585                            }
11586                        }
11587                    }
11588                }
11589            } else {
11590                String msg = "Permission Denial: " + intent.getAction()
11591                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11592                        + ", uid=" + callingUid + ")"
11593                        + " requires "
11594                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11595                Slog.w(TAG, msg);
11596                throw new SecurityException(msg);
11597            }
11598
11599        // Special case for adding a package: by default turn on compatibility
11600        // mode.
11601        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11602            Uri data = intent.getData();
11603            String ssp;
11604            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11605                mCompatModePackages.handlePackageAddedLocked(ssp,
11606                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11607            }
11608        }
11609
11610        /*
11611         * If this is the time zone changed action, queue up a message that will reset the timezone
11612         * of all currently running processes. This message will get queued up before the broadcast
11613         * happens.
11614         */
11615        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11616            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11617        }
11618
11619        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11620            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11621        }
11622
11623        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11624            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11625            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11626        }
11627
11628        // Add to the sticky list if requested.
11629        if (sticky) {
11630            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11631                    callingPid, callingUid)
11632                    != PackageManager.PERMISSION_GRANTED) {
11633                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11634                        + callingPid + ", uid=" + callingUid
11635                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11636                Slog.w(TAG, msg);
11637                throw new SecurityException(msg);
11638            }
11639            if (requiredPermission != null) {
11640                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11641                        + " and enforce permission " + requiredPermission);
11642                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11643            }
11644            if (intent.getComponent() != null) {
11645                throw new SecurityException(
11646                        "Sticky broadcasts can't target a specific component");
11647            }
11648            // We use userId directly here, since the "all" target is maintained
11649            // as a separate set of sticky broadcasts.
11650            if (userId != UserHandle.USER_ALL) {
11651                // But first, if this is not a broadcast to all users, then
11652                // make sure it doesn't conflict with an existing broadcast to
11653                // all users.
11654                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11655                        UserHandle.USER_ALL);
11656                if (stickies != null) {
11657                    ArrayList<Intent> list = stickies.get(intent.getAction());
11658                    if (list != null) {
11659                        int N = list.size();
11660                        int i;
11661                        for (i=0; i<N; i++) {
11662                            if (intent.filterEquals(list.get(i))) {
11663                                throw new IllegalArgumentException(
11664                                        "Sticky broadcast " + intent + " for user "
11665                                        + userId + " conflicts with existing global broadcast");
11666                            }
11667                        }
11668                    }
11669                }
11670            }
11671            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11672            if (stickies == null) {
11673                stickies = new HashMap<String, ArrayList<Intent>>();
11674                mStickyBroadcasts.put(userId, stickies);
11675            }
11676            ArrayList<Intent> list = stickies.get(intent.getAction());
11677            if (list == null) {
11678                list = new ArrayList<Intent>();
11679                stickies.put(intent.getAction(), list);
11680            }
11681            int N = list.size();
11682            int i;
11683            for (i=0; i<N; i++) {
11684                if (intent.filterEquals(list.get(i))) {
11685                    // This sticky already exists, replace it.
11686                    list.set(i, new Intent(intent));
11687                    break;
11688                }
11689            }
11690            if (i >= N) {
11691                list.add(new Intent(intent));
11692            }
11693        }
11694
11695        int[] users;
11696        if (userId == UserHandle.USER_ALL) {
11697            // Caller wants broadcast to go to all started users.
11698            users = mStartedUserArray;
11699        } else {
11700            // Caller wants broadcast to go to one specific user.
11701            users = mCurrentUserArray;
11702        }
11703
11704        // Figure out who all will receive this broadcast.
11705        List receivers = null;
11706        List<BroadcastFilter> registeredReceivers = null;
11707        // Need to resolve the intent to interested receivers...
11708        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11709                 == 0) {
11710            receivers = collectReceiverComponents(intent, resolvedType, users);
11711        }
11712        if (intent.getComponent() == null) {
11713            registeredReceivers = mReceiverResolver.queryIntent(intent,
11714                    resolvedType, false, userId);
11715        }
11716
11717        final boolean replacePending =
11718                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11719
11720        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11721                + " replacePending=" + replacePending);
11722
11723        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11724        if (!ordered && NR > 0) {
11725            // If we are not serializing this broadcast, then send the
11726            // registered receivers separately so they don't wait for the
11727            // components to be launched.
11728            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11729            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11730                    callerPackage, callingPid, callingUid, requiredPermission,
11731                    registeredReceivers, resultTo, resultCode, resultData, map,
11732                    ordered, sticky, false, userId);
11733            if (DEBUG_BROADCAST) Slog.v(
11734                    TAG, "Enqueueing parallel broadcast " + r);
11735            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11736            if (!replaced) {
11737                queue.enqueueParallelBroadcastLocked(r);
11738                queue.scheduleBroadcastsLocked();
11739            }
11740            registeredReceivers = null;
11741            NR = 0;
11742        }
11743
11744        // Merge into one list.
11745        int ir = 0;
11746        if (receivers != null) {
11747            // A special case for PACKAGE_ADDED: do not allow the package
11748            // being added to see this broadcast.  This prevents them from
11749            // using this as a back door to get run as soon as they are
11750            // installed.  Maybe in the future we want to have a special install
11751            // broadcast or such for apps, but we'd like to deliberately make
11752            // this decision.
11753            String skipPackages[] = null;
11754            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11755                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11756                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11757                Uri data = intent.getData();
11758                if (data != null) {
11759                    String pkgName = data.getSchemeSpecificPart();
11760                    if (pkgName != null) {
11761                        skipPackages = new String[] { pkgName };
11762                    }
11763                }
11764            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11765                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11766            }
11767            if (skipPackages != null && (skipPackages.length > 0)) {
11768                for (String skipPackage : skipPackages) {
11769                    if (skipPackage != null) {
11770                        int NT = receivers.size();
11771                        for (int it=0; it<NT; it++) {
11772                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11773                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11774                                receivers.remove(it);
11775                                it--;
11776                                NT--;
11777                            }
11778                        }
11779                    }
11780                }
11781            }
11782
11783            int NT = receivers != null ? receivers.size() : 0;
11784            int it = 0;
11785            ResolveInfo curt = null;
11786            BroadcastFilter curr = null;
11787            while (it < NT && ir < NR) {
11788                if (curt == null) {
11789                    curt = (ResolveInfo)receivers.get(it);
11790                }
11791                if (curr == null) {
11792                    curr = registeredReceivers.get(ir);
11793                }
11794                if (curr.getPriority() >= curt.priority) {
11795                    // Insert this broadcast record into the final list.
11796                    receivers.add(it, curr);
11797                    ir++;
11798                    curr = null;
11799                    it++;
11800                    NT++;
11801                } else {
11802                    // Skip to the next ResolveInfo in the final list.
11803                    it++;
11804                    curt = null;
11805                }
11806            }
11807        }
11808        while (ir < NR) {
11809            if (receivers == null) {
11810                receivers = new ArrayList();
11811            }
11812            receivers.add(registeredReceivers.get(ir));
11813            ir++;
11814        }
11815
11816        if ((receivers != null && receivers.size() > 0)
11817                || resultTo != null) {
11818            BroadcastQueue queue = broadcastQueueForIntent(intent);
11819            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11820                    callerPackage, callingPid, callingUid, requiredPermission,
11821                    receivers, resultTo, resultCode, resultData, map, ordered,
11822                    sticky, false, userId);
11823            if (DEBUG_BROADCAST) Slog.v(
11824                    TAG, "Enqueueing ordered broadcast " + r
11825                    + ": prev had " + queue.mOrderedBroadcasts.size());
11826            if (DEBUG_BROADCAST) {
11827                int seq = r.intent.getIntExtra("seq", -1);
11828                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11829            }
11830            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11831            if (!replaced) {
11832                queue.enqueueOrderedBroadcastLocked(r);
11833                queue.scheduleBroadcastsLocked();
11834            }
11835        }
11836
11837        return ActivityManager.BROADCAST_SUCCESS;
11838    }
11839
11840    final Intent verifyBroadcastLocked(Intent intent) {
11841        // Refuse possible leaked file descriptors
11842        if (intent != null && intent.hasFileDescriptors() == true) {
11843            throw new IllegalArgumentException("File descriptors passed in Intent");
11844        }
11845
11846        int flags = intent.getFlags();
11847
11848        if (!mProcessesReady) {
11849            // if the caller really truly claims to know what they're doing, go
11850            // ahead and allow the broadcast without launching any receivers
11851            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11852                intent = new Intent(intent);
11853                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11854            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11855                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11856                        + " before boot completion");
11857                throw new IllegalStateException("Cannot broadcast before boot completed");
11858            }
11859        }
11860
11861        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11862            throw new IllegalArgumentException(
11863                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11864        }
11865
11866        return intent;
11867    }
11868
11869    public final int broadcastIntent(IApplicationThread caller,
11870            Intent intent, String resolvedType, IIntentReceiver resultTo,
11871            int resultCode, String resultData, Bundle map,
11872            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11873        enforceNotIsolatedCaller("broadcastIntent");
11874        synchronized(this) {
11875            intent = verifyBroadcastLocked(intent);
11876
11877            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11878            final int callingPid = Binder.getCallingPid();
11879            final int callingUid = Binder.getCallingUid();
11880            final long origId = Binder.clearCallingIdentity();
11881            int res = broadcastIntentLocked(callerApp,
11882                    callerApp != null ? callerApp.info.packageName : null,
11883                    intent, resolvedType, resultTo,
11884                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11885                    callingPid, callingUid, userId);
11886            Binder.restoreCallingIdentity(origId);
11887            return res;
11888        }
11889    }
11890
11891    int broadcastIntentInPackage(String packageName, int uid,
11892            Intent intent, String resolvedType, IIntentReceiver resultTo,
11893            int resultCode, String resultData, Bundle map,
11894            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11895        synchronized(this) {
11896            intent = verifyBroadcastLocked(intent);
11897
11898            final long origId = Binder.clearCallingIdentity();
11899            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11900                    resultTo, resultCode, resultData, map, requiredPermission,
11901                    serialized, sticky, -1, uid, userId);
11902            Binder.restoreCallingIdentity(origId);
11903            return res;
11904        }
11905    }
11906
11907    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11908        // Refuse possible leaked file descriptors
11909        if (intent != null && intent.hasFileDescriptors() == true) {
11910            throw new IllegalArgumentException("File descriptors passed in Intent");
11911        }
11912
11913        userId = handleIncomingUser(Binder.getCallingPid(),
11914                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11915
11916        synchronized(this) {
11917            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11918                    != PackageManager.PERMISSION_GRANTED) {
11919                String msg = "Permission Denial: unbroadcastIntent() from pid="
11920                        + Binder.getCallingPid()
11921                        + ", uid=" + Binder.getCallingUid()
11922                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11923                Slog.w(TAG, msg);
11924                throw new SecurityException(msg);
11925            }
11926            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11927            if (stickies != null) {
11928                ArrayList<Intent> list = stickies.get(intent.getAction());
11929                if (list != null) {
11930                    int N = list.size();
11931                    int i;
11932                    for (i=0; i<N; i++) {
11933                        if (intent.filterEquals(list.get(i))) {
11934                            list.remove(i);
11935                            break;
11936                        }
11937                    }
11938                    if (list.size() <= 0) {
11939                        stickies.remove(intent.getAction());
11940                    }
11941                }
11942                if (stickies.size() <= 0) {
11943                    mStickyBroadcasts.remove(userId);
11944                }
11945            }
11946        }
11947    }
11948
11949    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11950            String resultData, Bundle resultExtras, boolean resultAbort,
11951            boolean explicit) {
11952        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11953        if (r == null) {
11954            Slog.w(TAG, "finishReceiver called but not found on queue");
11955            return false;
11956        }
11957
11958        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11959                explicit);
11960    }
11961
11962    public void finishReceiver(IBinder who, int resultCode, String resultData,
11963            Bundle resultExtras, boolean resultAbort) {
11964        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11965
11966        // Refuse possible leaked file descriptors
11967        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11968            throw new IllegalArgumentException("File descriptors passed in Bundle");
11969        }
11970
11971        final long origId = Binder.clearCallingIdentity();
11972        try {
11973            boolean doNext = false;
11974            BroadcastRecord r = null;
11975
11976            synchronized(this) {
11977                r = broadcastRecordForReceiverLocked(who);
11978                if (r != null) {
11979                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11980                        resultData, resultExtras, resultAbort, true);
11981                }
11982            }
11983
11984            if (doNext) {
11985                r.queue.processNextBroadcast(false);
11986            }
11987            trimApplications();
11988        } finally {
11989            Binder.restoreCallingIdentity(origId);
11990        }
11991    }
11992
11993    // =========================================================
11994    // INSTRUMENTATION
11995    // =========================================================
11996
11997    public boolean startInstrumentation(ComponentName className,
11998            String profileFile, int flags, Bundle arguments,
11999            IInstrumentationWatcher watcher, int userId) {
12000        enforceNotIsolatedCaller("startInstrumentation");
12001        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12002                userId, false, true, "startInstrumentation", null);
12003        // Refuse possible leaked file descriptors
12004        if (arguments != null && arguments.hasFileDescriptors()) {
12005            throw new IllegalArgumentException("File descriptors passed in Bundle");
12006        }
12007
12008        synchronized(this) {
12009            InstrumentationInfo ii = null;
12010            ApplicationInfo ai = null;
12011            try {
12012                ii = mContext.getPackageManager().getInstrumentationInfo(
12013                    className, STOCK_PM_FLAGS);
12014                ai = AppGlobals.getPackageManager().getApplicationInfo(
12015                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12016            } catch (PackageManager.NameNotFoundException e) {
12017            } catch (RemoteException e) {
12018            }
12019            if (ii == null) {
12020                reportStartInstrumentationFailure(watcher, className,
12021                        "Unable to find instrumentation info for: " + className);
12022                return false;
12023            }
12024            if (ai == null) {
12025                reportStartInstrumentationFailure(watcher, className,
12026                        "Unable to find instrumentation target package: " + ii.targetPackage);
12027                return false;
12028            }
12029
12030            int match = mContext.getPackageManager().checkSignatures(
12031                    ii.targetPackage, ii.packageName);
12032            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12033                String msg = "Permission Denial: starting instrumentation "
12034                        + className + " from pid="
12035                        + Binder.getCallingPid()
12036                        + ", uid=" + Binder.getCallingPid()
12037                        + " not allowed because package " + ii.packageName
12038                        + " does not have a signature matching the target "
12039                        + ii.targetPackage;
12040                reportStartInstrumentationFailure(watcher, className, msg);
12041                throw new SecurityException(msg);
12042            }
12043
12044            final long origId = Binder.clearCallingIdentity();
12045            // Instrumentation can kill and relaunch even persistent processes
12046            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12047            ProcessRecord app = addAppLocked(ai, false);
12048            app.instrumentationClass = className;
12049            app.instrumentationInfo = ai;
12050            app.instrumentationProfileFile = profileFile;
12051            app.instrumentationArguments = arguments;
12052            app.instrumentationWatcher = watcher;
12053            app.instrumentationResultClass = className;
12054            Binder.restoreCallingIdentity(origId);
12055        }
12056
12057        return true;
12058    }
12059
12060    /**
12061     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12062     * error to the logs, but if somebody is watching, send the report there too.  This enables
12063     * the "am" command to report errors with more information.
12064     *
12065     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12066     * @param cn The component name of the instrumentation.
12067     * @param report The error report.
12068     */
12069    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12070            ComponentName cn, String report) {
12071        Slog.w(TAG, report);
12072        try {
12073            if (watcher != null) {
12074                Bundle results = new Bundle();
12075                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12076                results.putString("Error", report);
12077                watcher.instrumentationStatus(cn, -1, results);
12078            }
12079        } catch (RemoteException e) {
12080            Slog.w(TAG, e);
12081        }
12082    }
12083
12084    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12085        if (app.instrumentationWatcher != null) {
12086            try {
12087                // NOTE:  IInstrumentationWatcher *must* be oneway here
12088                app.instrumentationWatcher.instrumentationFinished(
12089                    app.instrumentationClass,
12090                    resultCode,
12091                    results);
12092            } catch (RemoteException e) {
12093            }
12094        }
12095        app.instrumentationWatcher = null;
12096        app.instrumentationClass = null;
12097        app.instrumentationInfo = null;
12098        app.instrumentationProfileFile = null;
12099        app.instrumentationArguments = null;
12100
12101        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12102    }
12103
12104    public void finishInstrumentation(IApplicationThread target,
12105            int resultCode, Bundle results) {
12106        int userId = UserHandle.getCallingUserId();
12107        // Refuse possible leaked file descriptors
12108        if (results != null && results.hasFileDescriptors()) {
12109            throw new IllegalArgumentException("File descriptors passed in Intent");
12110        }
12111
12112        synchronized(this) {
12113            ProcessRecord app = getRecordForAppLocked(target);
12114            if (app == null) {
12115                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12116                return;
12117            }
12118            final long origId = Binder.clearCallingIdentity();
12119            finishInstrumentationLocked(app, resultCode, results);
12120            Binder.restoreCallingIdentity(origId);
12121        }
12122    }
12123
12124    // =========================================================
12125    // CONFIGURATION
12126    // =========================================================
12127
12128    public ConfigurationInfo getDeviceConfigurationInfo() {
12129        ConfigurationInfo config = new ConfigurationInfo();
12130        synchronized (this) {
12131            config.reqTouchScreen = mConfiguration.touchscreen;
12132            config.reqKeyboardType = mConfiguration.keyboard;
12133            config.reqNavigation = mConfiguration.navigation;
12134            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12135                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12136                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12137            }
12138            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12139                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12140                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12141            }
12142            config.reqGlEsVersion = GL_ES_VERSION;
12143        }
12144        return config;
12145    }
12146
12147    public Configuration getConfiguration() {
12148        Configuration ci;
12149        synchronized(this) {
12150            ci = new Configuration(mConfiguration);
12151        }
12152        return ci;
12153    }
12154
12155    public void updatePersistentConfiguration(Configuration values) {
12156        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12157                "updateConfiguration()");
12158        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12159                "updateConfiguration()");
12160        if (values == null) {
12161            throw new NullPointerException("Configuration must not be null");
12162        }
12163
12164        synchronized(this) {
12165            final long origId = Binder.clearCallingIdentity();
12166            updateConfigurationLocked(values, null, true, false);
12167            Binder.restoreCallingIdentity(origId);
12168        }
12169    }
12170
12171    public void updateConfiguration(Configuration values) {
12172        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12173                "updateConfiguration()");
12174
12175        synchronized(this) {
12176            if (values == null && mWindowManager != null) {
12177                // sentinel: fetch the current configuration from the window manager
12178                values = mWindowManager.computeNewConfiguration();
12179            }
12180
12181            if (mWindowManager != null) {
12182                mProcessList.applyDisplaySize(mWindowManager);
12183            }
12184
12185            final long origId = Binder.clearCallingIdentity();
12186            if (values != null) {
12187                Settings.System.clearConfiguration(values);
12188            }
12189            updateConfigurationLocked(values, null, false, false);
12190            Binder.restoreCallingIdentity(origId);
12191        }
12192    }
12193
12194    /**
12195     * Do either or both things: (1) change the current configuration, and (2)
12196     * make sure the given activity is running with the (now) current
12197     * configuration.  Returns true if the activity has been left running, or
12198     * false if <var>starting</var> is being destroyed to match the new
12199     * configuration.
12200     * @param persistent TODO
12201     */
12202    boolean updateConfigurationLocked(Configuration values,
12203            ActivityRecord starting, boolean persistent, boolean initLocale) {
12204        // do nothing if we are headless
12205        if (mHeadless) return true;
12206
12207        int changes = 0;
12208
12209        boolean kept = true;
12210
12211        if (values != null) {
12212            Configuration newConfig = new Configuration(mConfiguration);
12213            changes = newConfig.updateFrom(values);
12214            if (changes != 0) {
12215                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12216                    Slog.i(TAG, "Updating configuration to: " + values);
12217                }
12218
12219                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12220
12221                if (values.locale != null && !initLocale) {
12222                    saveLocaleLocked(values.locale,
12223                                     !values.locale.equals(mConfiguration.locale),
12224                                     values.userSetLocale);
12225                }
12226
12227                mConfigurationSeq++;
12228                if (mConfigurationSeq <= 0) {
12229                    mConfigurationSeq = 1;
12230                }
12231                newConfig.seq = mConfigurationSeq;
12232                mConfiguration = newConfig;
12233                Slog.i(TAG, "Config changed: " + newConfig);
12234
12235                final Configuration configCopy = new Configuration(mConfiguration);
12236
12237                // TODO: If our config changes, should we auto dismiss any currently
12238                // showing dialogs?
12239                mShowDialogs = shouldShowDialogs(newConfig);
12240
12241                AttributeCache ac = AttributeCache.instance();
12242                if (ac != null) {
12243                    ac.updateConfiguration(configCopy);
12244                }
12245
12246                // Make sure all resources in our process are updated
12247                // right now, so that anyone who is going to retrieve
12248                // resource values after we return will be sure to get
12249                // the new ones.  This is especially important during
12250                // boot, where the first config change needs to guarantee
12251                // all resources have that config before following boot
12252                // code is executed.
12253                mSystemThread.applyConfigurationToResources(configCopy);
12254
12255                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12256                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12257                    msg.obj = new Configuration(configCopy);
12258                    mHandler.sendMessage(msg);
12259                }
12260
12261                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12262                    ProcessRecord app = mLruProcesses.get(i);
12263                    try {
12264                        if (app.thread != null) {
12265                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12266                                    + app.processName + " new config " + mConfiguration);
12267                            app.thread.scheduleConfigurationChanged(configCopy);
12268                        }
12269                    } catch (Exception e) {
12270                    }
12271                }
12272                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12273                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12274                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12275                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12276                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12277                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12278                    broadcastIntentLocked(null, null,
12279                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12280                            null, null, 0, null, null,
12281                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12282                }
12283            }
12284        }
12285
12286        if (changes != 0 && starting == null) {
12287            // If the configuration changed, and the caller is not already
12288            // in the process of starting an activity, then find the top
12289            // activity to check if its configuration needs to change.
12290            starting = mMainStack.topRunningActivityLocked(null);
12291        }
12292
12293        if (starting != null) {
12294            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12295            // And we need to make sure at this point that all other activities
12296            // are made visible with the correct configuration.
12297            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12298        }
12299
12300        if (values != null && mWindowManager != null) {
12301            mWindowManager.setNewConfiguration(mConfiguration);
12302        }
12303
12304        return kept;
12305    }
12306
12307    /**
12308     * Decide based on the configuration whether we should shouw the ANR,
12309     * crash, etc dialogs.  The idea is that if there is no affordnace to
12310     * press the on-screen buttons, we shouldn't show the dialog.
12311     *
12312     * A thought: SystemUI might also want to get told about this, the Power
12313     * dialog / global actions also might want different behaviors.
12314     */
12315    private static final boolean shouldShowDialogs(Configuration config) {
12316        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12317                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12318    }
12319
12320    /**
12321     * Save the locale.  You must be inside a synchronized (this) block.
12322     */
12323    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12324        if(isDiff) {
12325            SystemProperties.set("user.language", l.getLanguage());
12326            SystemProperties.set("user.region", l.getCountry());
12327        }
12328
12329        if(isPersist) {
12330            SystemProperties.set("persist.sys.language", l.getLanguage());
12331            SystemProperties.set("persist.sys.country", l.getCountry());
12332            SystemProperties.set("persist.sys.localevar", l.getVariant());
12333        }
12334    }
12335
12336    @Override
12337    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12338        ActivityRecord srec = ActivityRecord.forToken(token);
12339        return srec != null && srec.task.affinity != null &&
12340                srec.task.affinity.equals(destAffinity);
12341    }
12342
12343    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12344            Intent resultData) {
12345        ComponentName dest = destIntent.getComponent();
12346
12347        synchronized (this) {
12348            ActivityRecord srec = ActivityRecord.forToken(token);
12349            if (srec == null) {
12350                return false;
12351            }
12352            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12353            final int start = history.indexOf(srec);
12354            if (start < 0) {
12355                // Current activity is not in history stack; do nothing.
12356                return false;
12357            }
12358            int finishTo = start - 1;
12359            ActivityRecord parent = null;
12360            boolean foundParentInTask = false;
12361            if (dest != null) {
12362                TaskRecord tr = srec.task;
12363                for (int i = start - 1; i >= 0; i--) {
12364                    ActivityRecord r = history.get(i);
12365                    if (tr != r.task) {
12366                        // Couldn't find parent in the same task; stop at the one above this.
12367                        // (Root of current task; in-app "home" behavior)
12368                        // Always at least finish the current activity.
12369                        finishTo = Math.min(start - 1, i + 1);
12370                        parent = history.get(finishTo);
12371                        break;
12372                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12373                            r.info.name.equals(dest.getClassName())) {
12374                        finishTo = i;
12375                        parent = r;
12376                        foundParentInTask = true;
12377                        break;
12378                    }
12379                }
12380            }
12381
12382            if (mController != null) {
12383                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12384                if (next != null) {
12385                    // ask watcher if this is allowed
12386                    boolean resumeOK = true;
12387                    try {
12388                        resumeOK = mController.activityResuming(next.packageName);
12389                    } catch (RemoteException e) {
12390                        mController = null;
12391                    }
12392
12393                    if (!resumeOK) {
12394                        return false;
12395                    }
12396                }
12397            }
12398            final long origId = Binder.clearCallingIdentity();
12399            for (int i = start; i > finishTo; i--) {
12400                ActivityRecord r = history.get(i);
12401                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12402                        "navigate-up", true);
12403                // Only return the supplied result for the first activity finished
12404                resultCode = Activity.RESULT_CANCELED;
12405                resultData = null;
12406            }
12407
12408            if (parent != null && foundParentInTask) {
12409                final int parentLaunchMode = parent.info.launchMode;
12410                final int destIntentFlags = destIntent.getFlags();
12411                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12412                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12413                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12414                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12415                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12416                } else {
12417                    try {
12418                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12419                                destIntent.getComponent(), 0, srec.userId);
12420                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12421                                null, aInfo, parent.appToken, null,
12422                                0, -1, parent.launchedFromUid, 0, null, true, null);
12423                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12424                    } catch (RemoteException e) {
12425                        foundParentInTask = false;
12426                    }
12427                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12428                            resultData, "navigate-up", true);
12429                }
12430            }
12431            Binder.restoreCallingIdentity(origId);
12432            return foundParentInTask;
12433        }
12434    }
12435
12436    public int getLaunchedFromUid(IBinder activityToken) {
12437        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12438        if (srec == null) {
12439            return -1;
12440        }
12441        return srec.launchedFromUid;
12442    }
12443
12444    // =========================================================
12445    // LIFETIME MANAGEMENT
12446    // =========================================================
12447
12448    // Returns which broadcast queue the app is the current [or imminent] receiver
12449    // on, or 'null' if the app is not an active broadcast recipient.
12450    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12451        BroadcastRecord r = app.curReceiver;
12452        if (r != null) {
12453            return r.queue;
12454        }
12455
12456        // It's not the current receiver, but it might be starting up to become one
12457        synchronized (this) {
12458            for (BroadcastQueue queue : mBroadcastQueues) {
12459                r = queue.mPendingBroadcast;
12460                if (r != null && r.curApp == app) {
12461                    // found it; report which queue it's in
12462                    return queue;
12463                }
12464            }
12465        }
12466
12467        return null;
12468    }
12469
12470    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12471            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12472        if (mAdjSeq == app.adjSeq) {
12473            // This adjustment has already been computed.  If we are calling
12474            // from the top, we may have already computed our adjustment with
12475            // an earlier hidden adjustment that isn't really for us... if
12476            // so, use the new hidden adjustment.
12477            if (!recursed && app.hidden) {
12478                if (app.hasActivities) {
12479                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12480                } else if (app.hasClientActivities) {
12481                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12482                } else {
12483                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12484                }
12485            }
12486            return app.curRawAdj;
12487        }
12488
12489        if (app.thread == null) {
12490            app.adjSeq = mAdjSeq;
12491            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12492            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12493        }
12494
12495        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12496        app.adjSource = null;
12497        app.adjTarget = null;
12498        app.empty = false;
12499        app.hidden = false;
12500        app.hasClientActivities = false;
12501
12502        final int activitiesSize = app.activities.size();
12503
12504        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12505            // The max adjustment doesn't allow this app to be anything
12506            // below foreground, so it is not worth doing work for it.
12507            app.adjType = "fixed";
12508            app.adjSeq = mAdjSeq;
12509            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12510            app.hasActivities = false;
12511            app.foregroundActivities = false;
12512            app.keeping = true;
12513            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12514            // System process can do UI, and when they do we want to have
12515            // them trim their memory after the user leaves the UI.  To
12516            // facilitate this, here we need to determine whether or not it
12517            // is currently showing UI.
12518            app.systemNoUi = true;
12519            if (app == TOP_APP) {
12520                app.systemNoUi = false;
12521                app.hasActivities = true;
12522            } else if (activitiesSize > 0) {
12523                for (int j = 0; j < activitiesSize; j++) {
12524                    final ActivityRecord r = app.activities.get(j);
12525                    if (r.visible) {
12526                        app.systemNoUi = false;
12527                    }
12528                    if (r.app == app) {
12529                        app.hasActivities = true;
12530                    }
12531                }
12532            }
12533            return (app.curAdj=app.maxAdj);
12534        }
12535
12536        app.keeping = false;
12537        app.systemNoUi = false;
12538        app.hasActivities = false;
12539
12540        // Determine the importance of the process, starting with most
12541        // important to least, and assign an appropriate OOM adjustment.
12542        int adj;
12543        int schedGroup;
12544        boolean foregroundActivities = false;
12545        boolean interesting = false;
12546        BroadcastQueue queue;
12547        if (app == TOP_APP) {
12548            // The last app on the list is the foreground app.
12549            adj = ProcessList.FOREGROUND_APP_ADJ;
12550            schedGroup = Process.THREAD_GROUP_DEFAULT;
12551            app.adjType = "top-activity";
12552            foregroundActivities = true;
12553            interesting = true;
12554            app.hasActivities = true;
12555        } else if (app.instrumentationClass != null) {
12556            // Don't want to kill running instrumentation.
12557            adj = ProcessList.FOREGROUND_APP_ADJ;
12558            schedGroup = Process.THREAD_GROUP_DEFAULT;
12559            app.adjType = "instrumentation";
12560            interesting = true;
12561        } else if ((queue = isReceivingBroadcast(app)) != null) {
12562            // An app that is currently receiving a broadcast also
12563            // counts as being in the foreground for OOM killer purposes.
12564            // It's placed in a sched group based on the nature of the
12565            // broadcast as reflected by which queue it's active in.
12566            adj = ProcessList.FOREGROUND_APP_ADJ;
12567            schedGroup = (queue == mFgBroadcastQueue)
12568                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12569            app.adjType = "broadcast";
12570        } else if (app.executingServices.size() > 0) {
12571            // An app that is currently executing a service callback also
12572            // counts as being in the foreground.
12573            adj = ProcessList.FOREGROUND_APP_ADJ;
12574            schedGroup = Process.THREAD_GROUP_DEFAULT;
12575            app.adjType = "exec-service";
12576        } else {
12577            // Assume process is hidden (has activities); we will correct
12578            // later if this is not the case.
12579            adj = hiddenAdj;
12580            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12581            app.hidden = true;
12582            app.adjType = "bg-act";
12583        }
12584
12585        boolean hasStoppingActivities = false;
12586
12587        // Examine all activities if not already foreground.
12588        if (!foregroundActivities && activitiesSize > 0) {
12589            for (int j = 0; j < activitiesSize; j++) {
12590                final ActivityRecord r = app.activities.get(j);
12591                if (r.visible) {
12592                    // App has a visible activity; only upgrade adjustment.
12593                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12594                        adj = ProcessList.VISIBLE_APP_ADJ;
12595                        app.adjType = "visible";
12596                    }
12597                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12598                    app.hidden = false;
12599                    app.hasActivities = true;
12600                    foregroundActivities = true;
12601                    break;
12602                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12603                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12604                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12605                        app.adjType = "pausing";
12606                    }
12607                    app.hidden = false;
12608                    foregroundActivities = true;
12609                } else if (r.state == ActivityState.STOPPING) {
12610                    // We will apply the actual adjustment later, because
12611                    // we want to allow this process to immediately go through
12612                    // any memory trimming that is in effect.
12613                    app.hidden = false;
12614                    foregroundActivities = true;
12615                    hasStoppingActivities = true;
12616                }
12617                if (r.app == app) {
12618                    app.hasActivities = true;
12619                }
12620            }
12621        }
12622
12623        if (adj == hiddenAdj && !app.hasActivities) {
12624            if (app.hasClientActivities) {
12625                adj = clientHiddenAdj;
12626                app.adjType = "bg-client-act";
12627            } else {
12628                // Whoops, this process is completely empty as far as we know
12629                // at this point.
12630                adj = emptyAdj;
12631                app.empty = true;
12632                app.adjType = "bg-empty";
12633            }
12634        }
12635
12636        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12637            if (app.foregroundServices) {
12638                // The user is aware of this app, so make it visible.
12639                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12640                app.hidden = false;
12641                app.adjType = "fg-service";
12642                schedGroup = Process.THREAD_GROUP_DEFAULT;
12643            } else if (app.forcingToForeground != null) {
12644                // The user is aware of this app, so make it visible.
12645                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12646                app.hidden = false;
12647                app.adjType = "force-fg";
12648                app.adjSource = app.forcingToForeground;
12649                schedGroup = Process.THREAD_GROUP_DEFAULT;
12650            }
12651        }
12652
12653        if (app.foregroundServices) {
12654            interesting = true;
12655        }
12656
12657        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12658            // We don't want to kill the current heavy-weight process.
12659            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12660            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12661            app.hidden = false;
12662            app.adjType = "heavy";
12663        }
12664
12665        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12666            // This process is hosting what we currently consider to be the
12667            // home app, so we don't want to let it go into the background.
12668            adj = ProcessList.HOME_APP_ADJ;
12669            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12670            app.hidden = false;
12671            app.adjType = "home";
12672        }
12673
12674        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12675                && app.activities.size() > 0) {
12676            // This was the previous process that showed UI to the user.
12677            // We want to try to keep it around more aggressively, to give
12678            // a good experience around switching between two apps.
12679            adj = ProcessList.PREVIOUS_APP_ADJ;
12680            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12681            app.hidden = false;
12682            app.adjType = "previous";
12683        }
12684
12685        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12686                + " reason=" + app.adjType);
12687
12688        // By default, we use the computed adjustment.  It may be changed if
12689        // there are applications dependent on our services or providers, but
12690        // this gives us a baseline and makes sure we don't get into an
12691        // infinite recursion.
12692        app.adjSeq = mAdjSeq;
12693        app.curRawAdj = app.nonStoppingAdj = adj;
12694
12695        if (mBackupTarget != null && app == mBackupTarget.app) {
12696            // If possible we want to avoid killing apps while they're being backed up
12697            if (adj > ProcessList.BACKUP_APP_ADJ) {
12698                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12699                adj = ProcessList.BACKUP_APP_ADJ;
12700                app.adjType = "backup";
12701                app.hidden = false;
12702            }
12703        }
12704
12705        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12706                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12707            final long now = SystemClock.uptimeMillis();
12708            // This process is more important if the top activity is
12709            // bound to the service.
12710            Iterator<ServiceRecord> jt = app.services.iterator();
12711            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12712                ServiceRecord s = jt.next();
12713                if (s.startRequested) {
12714                    if (app.hasShownUi && app != mHomeProcess) {
12715                        // If this process has shown some UI, let it immediately
12716                        // go to the LRU list because it may be pretty heavy with
12717                        // UI stuff.  We'll tag it with a label just to help
12718                        // debug and understand what is going on.
12719                        if (adj > ProcessList.SERVICE_ADJ) {
12720                            app.adjType = "started-bg-ui-services";
12721                        }
12722                    } else {
12723                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12724                            // This service has seen some activity within
12725                            // recent memory, so we will keep its process ahead
12726                            // of the background processes.
12727                            if (adj > ProcessList.SERVICE_ADJ) {
12728                                adj = ProcessList.SERVICE_ADJ;
12729                                app.adjType = "started-services";
12730                                app.hidden = false;
12731                            }
12732                        }
12733                        // If we have let the service slide into the background
12734                        // state, still have some text describing what it is doing
12735                        // even though the service no longer has an impact.
12736                        if (adj > ProcessList.SERVICE_ADJ) {
12737                            app.adjType = "started-bg-services";
12738                        }
12739                    }
12740                    // Don't kill this process because it is doing work; it
12741                    // has said it is doing work.
12742                    app.keeping = true;
12743                }
12744                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12745                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12746                    Iterator<ArrayList<ConnectionRecord>> kt
12747                            = s.connections.values().iterator();
12748                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12749                        ArrayList<ConnectionRecord> clist = kt.next();
12750                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12751                            // XXX should compute this based on the max of
12752                            // all connected clients.
12753                            ConnectionRecord cr = clist.get(i);
12754                            if (cr.binding.client == app) {
12755                                // Binding to ourself is not interesting.
12756                                continue;
12757                            }
12758                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12759                                ProcessRecord client = cr.binding.client;
12760                                int clientAdj = adj;
12761                                int myHiddenAdj = hiddenAdj;
12762                                if (myHiddenAdj > client.hiddenAdj) {
12763                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12764                                        myHiddenAdj = client.hiddenAdj;
12765                                    } else {
12766                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12767                                    }
12768                                }
12769                                int myClientHiddenAdj = clientHiddenAdj;
12770                                if (myClientHiddenAdj > client.clientHiddenAdj) {
12771                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12772                                        myClientHiddenAdj = client.clientHiddenAdj;
12773                                    } else {
12774                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12775                                    }
12776                                }
12777                                int myEmptyAdj = emptyAdj;
12778                                if (myEmptyAdj > client.emptyAdj) {
12779                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12780                                        myEmptyAdj = client.emptyAdj;
12781                                    } else {
12782                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12783                                    }
12784                                }
12785                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12786                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12787                                String adjType = null;
12788                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12789                                    // Not doing bind OOM management, so treat
12790                                    // this guy more like a started service.
12791                                    if (app.hasShownUi && app != mHomeProcess) {
12792                                        // If this process has shown some UI, let it immediately
12793                                        // go to the LRU list because it may be pretty heavy with
12794                                        // UI stuff.  We'll tag it with a label just to help
12795                                        // debug and understand what is going on.
12796                                        if (adj > clientAdj) {
12797                                            adjType = "bound-bg-ui-services";
12798                                        }
12799                                        app.hidden = false;
12800                                        clientAdj = adj;
12801                                    } else {
12802                                        if (now >= (s.lastActivity
12803                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12804                                            // This service has not seen activity within
12805                                            // recent memory, so allow it to drop to the
12806                                            // LRU list if there is no other reason to keep
12807                                            // it around.  We'll also tag it with a label just
12808                                            // to help debug and undertand what is going on.
12809                                            if (adj > clientAdj) {
12810                                                adjType = "bound-bg-services";
12811                                            }
12812                                            clientAdj = adj;
12813                                        }
12814                                    }
12815                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12816                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12817                                        // If this connection is keeping the service
12818                                        // created, then we want to try to better follow
12819                                        // its memory management semantics for activities.
12820                                        // That is, if it is sitting in the background
12821                                        // LRU list as a hidden process (with activities),
12822                                        // we don't want the service it is connected to
12823                                        // to go into the empty LRU and quickly get killed,
12824                                        // because I'll we'll do is just end up restarting
12825                                        // the service.
12826                                        app.hasClientActivities |= client.hasActivities;
12827                                    }
12828                                }
12829                                if (adj > clientAdj) {
12830                                    // If this process has recently shown UI, and
12831                                    // the process that is binding to it is less
12832                                    // important than being visible, then we don't
12833                                    // care about the binding as much as we care
12834                                    // about letting this process get into the LRU
12835                                    // list to be killed and restarted if needed for
12836                                    // memory.
12837                                    if (app.hasShownUi && app != mHomeProcess
12838                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12839                                        adjType = "bound-bg-ui-services";
12840                                    } else {
12841                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12842                                                |Context.BIND_IMPORTANT)) != 0) {
12843                                            adj = clientAdj;
12844                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12845                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12846                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12847                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12848                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12849                                            adj = clientAdj;
12850                                        } else {
12851                                            app.pendingUiClean = true;
12852                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12853                                                adj = ProcessList.VISIBLE_APP_ADJ;
12854                                            }
12855                                        }
12856                                        if (!client.hidden) {
12857                                            app.hidden = false;
12858                                        }
12859                                        if (client.keeping) {
12860                                            app.keeping = true;
12861                                        }
12862                                        adjType = "service";
12863                                    }
12864                                }
12865                                if (adjType != null) {
12866                                    app.adjType = adjType;
12867                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12868                                            .REASON_SERVICE_IN_USE;
12869                                    app.adjSource = cr.binding.client;
12870                                    app.adjSourceOom = clientAdj;
12871                                    app.adjTarget = s.name;
12872                                }
12873                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12874                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12875                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12876                                    }
12877                                }
12878                            }
12879                            final ActivityRecord a = cr.activity;
12880                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12881                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12882                                        (a.visible || a.state == ActivityState.RESUMED
12883                                         || a.state == ActivityState.PAUSING)) {
12884                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12885                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12886                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12887                                    }
12888                                    app.hidden = false;
12889                                    app.adjType = "service";
12890                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12891                                            .REASON_SERVICE_IN_USE;
12892                                    app.adjSource = a;
12893                                    app.adjSourceOom = adj;
12894                                    app.adjTarget = s.name;
12895                                }
12896                            }
12897                        }
12898                    }
12899                }
12900            }
12901
12902            // Finally, if this process has active services running in it, we
12903            // would like to avoid killing it unless it would prevent the current
12904            // application from running.  By default we put the process in
12905            // with the rest of the background processes; as we scan through
12906            // its services we may bump it up from there.
12907            if (adj > hiddenAdj) {
12908                adj = hiddenAdj;
12909                app.hidden = false;
12910                app.adjType = "bg-services";
12911            }
12912        }
12913
12914        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12915                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12916            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12917            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12918                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12919                ContentProviderRecord cpr = jt.next();
12920                for (int i = cpr.connections.size()-1;
12921                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12922                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12923                        i--) {
12924                    ContentProviderConnection conn = cpr.connections.get(i);
12925                    ProcessRecord client = conn.client;
12926                    if (client == app) {
12927                        // Being our own client is not interesting.
12928                        continue;
12929                    }
12930                    int myHiddenAdj = hiddenAdj;
12931                    if (myHiddenAdj > client.hiddenAdj) {
12932                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12933                            myHiddenAdj = client.hiddenAdj;
12934                        } else {
12935                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12936                        }
12937                    }
12938                    int myClientHiddenAdj = clientHiddenAdj;
12939                    if (myClientHiddenAdj > client.clientHiddenAdj) {
12940                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
12941                            myClientHiddenAdj = client.clientHiddenAdj;
12942                        } else {
12943                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12944                        }
12945                    }
12946                    int myEmptyAdj = emptyAdj;
12947                    if (myEmptyAdj > client.emptyAdj) {
12948                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12949                            myEmptyAdj = client.emptyAdj;
12950                        } else {
12951                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12952                        }
12953                    }
12954                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12955                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12956                    if (adj > clientAdj) {
12957                        if (app.hasShownUi && app != mHomeProcess
12958                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12959                            app.adjType = "bg-ui-provider";
12960                        } else {
12961                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12962                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12963                            app.adjType = "provider";
12964                        }
12965                        if (!client.hidden) {
12966                            app.hidden = false;
12967                        }
12968                        if (client.keeping) {
12969                            app.keeping = true;
12970                        }
12971                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12972                                .REASON_PROVIDER_IN_USE;
12973                        app.adjSource = client;
12974                        app.adjSourceOom = clientAdj;
12975                        app.adjTarget = cpr.name;
12976                    }
12977                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12978                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12979                    }
12980                }
12981                // If the provider has external (non-framework) process
12982                // dependencies, ensure that its adjustment is at least
12983                // FOREGROUND_APP_ADJ.
12984                if (cpr.hasExternalProcessHandles()) {
12985                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12986                        adj = ProcessList.FOREGROUND_APP_ADJ;
12987                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12988                        app.hidden = false;
12989                        app.keeping = true;
12990                        app.adjType = "provider";
12991                        app.adjTarget = cpr.name;
12992                    }
12993                }
12994            }
12995        }
12996
12997        if (adj == ProcessList.SERVICE_ADJ) {
12998            if (doingAll) {
12999                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13000                mNewNumServiceProcs++;
13001            }
13002            if (app.serviceb) {
13003                adj = ProcessList.SERVICE_B_ADJ;
13004            }
13005        } else {
13006            app.serviceb = false;
13007        }
13008
13009        app.nonStoppingAdj = adj;
13010
13011        if (hasStoppingActivities) {
13012            // Only upgrade adjustment.
13013            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13014                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13015                app.adjType = "stopping";
13016            }
13017        }
13018
13019        app.curRawAdj = adj;
13020
13021        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13022        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13023        if (adj > app.maxAdj) {
13024            adj = app.maxAdj;
13025            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13026                schedGroup = Process.THREAD_GROUP_DEFAULT;
13027            }
13028        }
13029        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13030            app.keeping = true;
13031        }
13032
13033        if (app.hasAboveClient) {
13034            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13035            // then we need to drop its adjustment to be lower than the service's
13036            // in order to honor the request.  We want to drop it by one adjustment
13037            // level...  but there is special meaning applied to various levels so
13038            // we will skip some of them.
13039            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13040                // System process will not get dropped, ever
13041            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13042                adj = ProcessList.VISIBLE_APP_ADJ;
13043            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13044                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13045            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13046                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13047            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13048                adj++;
13049            }
13050        }
13051
13052        int importance = app.memImportance;
13053        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13054            app.curAdj = adj;
13055            app.curSchedGroup = schedGroup;
13056            if (!interesting) {
13057                // For this reporting, if there is not something explicitly
13058                // interesting in this process then we will push it to the
13059                // background importance.
13060                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13061            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13062                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13063            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13064                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13065            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13066                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13067            } else if (adj >= ProcessList.SERVICE_ADJ) {
13068                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13069            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13070                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13071            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13072                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13073            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13074                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13075            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13076                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13077            } else {
13078                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13079            }
13080        }
13081
13082        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13083        if (foregroundActivities != app.foregroundActivities) {
13084            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13085        }
13086        if (changes != 0) {
13087            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13088            app.memImportance = importance;
13089            app.foregroundActivities = foregroundActivities;
13090            int i = mPendingProcessChanges.size()-1;
13091            ProcessChangeItem item = null;
13092            while (i >= 0) {
13093                item = mPendingProcessChanges.get(i);
13094                if (item.pid == app.pid) {
13095                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13096                    break;
13097                }
13098                i--;
13099            }
13100            if (i < 0) {
13101                // No existing item in pending changes; need a new one.
13102                final int NA = mAvailProcessChanges.size();
13103                if (NA > 0) {
13104                    item = mAvailProcessChanges.remove(NA-1);
13105                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13106                } else {
13107                    item = new ProcessChangeItem();
13108                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13109                }
13110                item.changes = 0;
13111                item.pid = app.pid;
13112                item.uid = app.info.uid;
13113                if (mPendingProcessChanges.size() == 0) {
13114                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13115                            "*** Enqueueing dispatch processes changed!");
13116                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13117                }
13118                mPendingProcessChanges.add(item);
13119            }
13120            item.changes |= changes;
13121            item.importance = importance;
13122            item.foregroundActivities = foregroundActivities;
13123            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13124                    + Integer.toHexString(System.identityHashCode(item))
13125                    + " " + app.toShortString() + ": changes=" + item.changes
13126                    + " importance=" + item.importance
13127                    + " foreground=" + item.foregroundActivities
13128                    + " type=" + app.adjType + " source=" + app.adjSource
13129                    + " target=" + app.adjTarget);
13130        }
13131
13132        return app.curRawAdj;
13133    }
13134
13135    /**
13136     * Ask a given process to GC right now.
13137     */
13138    final void performAppGcLocked(ProcessRecord app) {
13139        try {
13140            app.lastRequestedGc = SystemClock.uptimeMillis();
13141            if (app.thread != null) {
13142                if (app.reportLowMemory) {
13143                    app.reportLowMemory = false;
13144                    app.thread.scheduleLowMemory();
13145                } else {
13146                    app.thread.processInBackground();
13147                }
13148            }
13149        } catch (Exception e) {
13150            // whatever.
13151        }
13152    }
13153
13154    /**
13155     * Returns true if things are idle enough to perform GCs.
13156     */
13157    private final boolean canGcNowLocked() {
13158        boolean processingBroadcasts = false;
13159        for (BroadcastQueue q : mBroadcastQueues) {
13160            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13161                processingBroadcasts = true;
13162            }
13163        }
13164        return !processingBroadcasts
13165                && (mSleeping || (mMainStack.mResumedActivity != null &&
13166                        mMainStack.mResumedActivity.idle));
13167    }
13168
13169    /**
13170     * Perform GCs on all processes that are waiting for it, but only
13171     * if things are idle.
13172     */
13173    final void performAppGcsLocked() {
13174        final int N = mProcessesToGc.size();
13175        if (N <= 0) {
13176            return;
13177        }
13178        if (canGcNowLocked()) {
13179            while (mProcessesToGc.size() > 0) {
13180                ProcessRecord proc = mProcessesToGc.remove(0);
13181                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13182                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13183                            <= SystemClock.uptimeMillis()) {
13184                        // To avoid spamming the system, we will GC processes one
13185                        // at a time, waiting a few seconds between each.
13186                        performAppGcLocked(proc);
13187                        scheduleAppGcsLocked();
13188                        return;
13189                    } else {
13190                        // It hasn't been long enough since we last GCed this
13191                        // process...  put it in the list to wait for its time.
13192                        addProcessToGcListLocked(proc);
13193                        break;
13194                    }
13195                }
13196            }
13197
13198            scheduleAppGcsLocked();
13199        }
13200    }
13201
13202    /**
13203     * If all looks good, perform GCs on all processes waiting for them.
13204     */
13205    final void performAppGcsIfAppropriateLocked() {
13206        if (canGcNowLocked()) {
13207            performAppGcsLocked();
13208            return;
13209        }
13210        // Still not idle, wait some more.
13211        scheduleAppGcsLocked();
13212    }
13213
13214    /**
13215     * Schedule the execution of all pending app GCs.
13216     */
13217    final void scheduleAppGcsLocked() {
13218        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13219
13220        if (mProcessesToGc.size() > 0) {
13221            // Schedule a GC for the time to the next process.
13222            ProcessRecord proc = mProcessesToGc.get(0);
13223            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13224
13225            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13226            long now = SystemClock.uptimeMillis();
13227            if (when < (now+GC_TIMEOUT)) {
13228                when = now + GC_TIMEOUT;
13229            }
13230            mHandler.sendMessageAtTime(msg, when);
13231        }
13232    }
13233
13234    /**
13235     * Add a process to the array of processes waiting to be GCed.  Keeps the
13236     * list in sorted order by the last GC time.  The process can't already be
13237     * on the list.
13238     */
13239    final void addProcessToGcListLocked(ProcessRecord proc) {
13240        boolean added = false;
13241        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13242            if (mProcessesToGc.get(i).lastRequestedGc <
13243                    proc.lastRequestedGc) {
13244                added = true;
13245                mProcessesToGc.add(i+1, proc);
13246                break;
13247            }
13248        }
13249        if (!added) {
13250            mProcessesToGc.add(0, proc);
13251        }
13252    }
13253
13254    /**
13255     * Set up to ask a process to GC itself.  This will either do it
13256     * immediately, or put it on the list of processes to gc the next
13257     * time things are idle.
13258     */
13259    final void scheduleAppGcLocked(ProcessRecord app) {
13260        long now = SystemClock.uptimeMillis();
13261        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13262            return;
13263        }
13264        if (!mProcessesToGc.contains(app)) {
13265            addProcessToGcListLocked(app);
13266            scheduleAppGcsLocked();
13267        }
13268    }
13269
13270    final void checkExcessivePowerUsageLocked(boolean doKills) {
13271        updateCpuStatsNow();
13272
13273        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13274        boolean doWakeKills = doKills;
13275        boolean doCpuKills = doKills;
13276        if (mLastPowerCheckRealtime == 0) {
13277            doWakeKills = false;
13278        }
13279        if (mLastPowerCheckUptime == 0) {
13280            doCpuKills = false;
13281        }
13282        if (stats.isScreenOn()) {
13283            doWakeKills = false;
13284        }
13285        final long curRealtime = SystemClock.elapsedRealtime();
13286        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13287        final long curUptime = SystemClock.uptimeMillis();
13288        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13289        mLastPowerCheckRealtime = curRealtime;
13290        mLastPowerCheckUptime = curUptime;
13291        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13292            doWakeKills = false;
13293        }
13294        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13295            doCpuKills = false;
13296        }
13297        int i = mLruProcesses.size();
13298        while (i > 0) {
13299            i--;
13300            ProcessRecord app = mLruProcesses.get(i);
13301            if (!app.keeping) {
13302                long wtime;
13303                synchronized (stats) {
13304                    wtime = stats.getProcessWakeTime(app.info.uid,
13305                            app.pid, curRealtime);
13306                }
13307                long wtimeUsed = wtime - app.lastWakeTime;
13308                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13309                if (DEBUG_POWER) {
13310                    StringBuilder sb = new StringBuilder(128);
13311                    sb.append("Wake for ");
13312                    app.toShortString(sb);
13313                    sb.append(": over ");
13314                    TimeUtils.formatDuration(realtimeSince, sb);
13315                    sb.append(" used ");
13316                    TimeUtils.formatDuration(wtimeUsed, sb);
13317                    sb.append(" (");
13318                    sb.append((wtimeUsed*100)/realtimeSince);
13319                    sb.append("%)");
13320                    Slog.i(TAG, sb.toString());
13321                    sb.setLength(0);
13322                    sb.append("CPU for ");
13323                    app.toShortString(sb);
13324                    sb.append(": over ");
13325                    TimeUtils.formatDuration(uptimeSince, sb);
13326                    sb.append(" used ");
13327                    TimeUtils.formatDuration(cputimeUsed, sb);
13328                    sb.append(" (");
13329                    sb.append((cputimeUsed*100)/uptimeSince);
13330                    sb.append("%)");
13331                    Slog.i(TAG, sb.toString());
13332                }
13333                // If a process has held a wake lock for more
13334                // than 50% of the time during this period,
13335                // that sounds bad.  Kill!
13336                if (doWakeKills && realtimeSince > 0
13337                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13338                    synchronized (stats) {
13339                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13340                                realtimeSince, wtimeUsed);
13341                    }
13342                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13343                            + " (pid " + app.pid + "): held " + wtimeUsed
13344                            + " during " + realtimeSince);
13345                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13346                            app.processName, app.setAdj, "excessive wake lock");
13347                    Process.killProcessQuiet(app.pid);
13348                } else if (doCpuKills && uptimeSince > 0
13349                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13350                    synchronized (stats) {
13351                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13352                                uptimeSince, cputimeUsed);
13353                    }
13354                    Slog.w(TAG, "Excessive CPU in " + app.processName
13355                            + " (pid " + app.pid + "): used " + cputimeUsed
13356                            + " during " + uptimeSince);
13357                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13358                            app.processName, app.setAdj, "excessive cpu");
13359                    Process.killProcessQuiet(app.pid);
13360                } else {
13361                    app.lastWakeTime = wtime;
13362                    app.lastCpuTime = app.curCpuTime;
13363                }
13364            }
13365        }
13366    }
13367
13368    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13369            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13370        app.hiddenAdj = hiddenAdj;
13371        app.clientHiddenAdj = clientHiddenAdj;
13372        app.emptyAdj = emptyAdj;
13373
13374        if (app.thread == null) {
13375            return false;
13376        }
13377
13378        final boolean wasKeeping = app.keeping;
13379
13380        boolean success = true;
13381
13382        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13383
13384        if (app.curRawAdj != app.setRawAdj) {
13385            if (wasKeeping && !app.keeping) {
13386                // This app is no longer something we want to keep.  Note
13387                // its current wake lock time to later know to kill it if
13388                // it is not behaving well.
13389                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13390                synchronized (stats) {
13391                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13392                            app.pid, SystemClock.elapsedRealtime());
13393                }
13394                app.lastCpuTime = app.curCpuTime;
13395            }
13396
13397            app.setRawAdj = app.curRawAdj;
13398        }
13399
13400        if (app.curAdj != app.setAdj) {
13401            if (Process.setOomAdj(app.pid, app.curAdj)) {
13402                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13403                    TAG, "Set " + app.pid + " " + app.processName +
13404                    " adj " + app.curAdj + ": " + app.adjType);
13405                app.setAdj = app.curAdj;
13406            } else {
13407                success = false;
13408                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13409            }
13410        }
13411        if (app.setSchedGroup != app.curSchedGroup) {
13412            app.setSchedGroup = app.curSchedGroup;
13413            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13414                    "Setting process group of " + app.processName
13415                    + " to " + app.curSchedGroup);
13416            if (app.waitingToKill != null &&
13417                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13418                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13419                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13420                        app.processName, app.setAdj, app.waitingToKill);
13421                app.killedBackground = true;
13422                Process.killProcessQuiet(app.pid);
13423                success = false;
13424            } else {
13425                if (true) {
13426                    long oldId = Binder.clearCallingIdentity();
13427                    try {
13428                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13429                    } catch (Exception e) {
13430                        Slog.w(TAG, "Failed setting process group of " + app.pid
13431                                + " to " + app.curSchedGroup);
13432                        e.printStackTrace();
13433                    } finally {
13434                        Binder.restoreCallingIdentity(oldId);
13435                    }
13436                } else {
13437                    if (app.thread != null) {
13438                        try {
13439                            app.thread.setSchedulingGroup(app.curSchedGroup);
13440                        } catch (RemoteException e) {
13441                        }
13442                    }
13443                }
13444            }
13445        }
13446        return success;
13447    }
13448
13449    private final ActivityRecord resumedAppLocked() {
13450        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13451        if (resumedActivity == null || resumedActivity.app == null) {
13452            resumedActivity = mMainStack.mPausingActivity;
13453            if (resumedActivity == null || resumedActivity.app == null) {
13454                resumedActivity = mMainStack.topRunningActivityLocked(null);
13455            }
13456        }
13457        return resumedActivity;
13458    }
13459
13460    final boolean updateOomAdjLocked(ProcessRecord app) {
13461        final ActivityRecord TOP_ACT = resumedAppLocked();
13462        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13463        int curAdj = app.curAdj;
13464        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13465            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13466
13467        mAdjSeq++;
13468
13469        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13470                app.emptyAdj, TOP_APP, false);
13471        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13472            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13473        if (nowHidden != wasHidden) {
13474            // Changed to/from hidden state, so apps after it in the LRU
13475            // list may also be changed.
13476            updateOomAdjLocked();
13477        }
13478        return success;
13479    }
13480
13481    final void updateOomAdjLocked() {
13482        final ActivityRecord TOP_ACT = resumedAppLocked();
13483        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13484        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13485
13486        if (false) {
13487            RuntimeException e = new RuntimeException();
13488            e.fillInStackTrace();
13489            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13490        }
13491
13492        mAdjSeq++;
13493        mNewNumServiceProcs = 0;
13494
13495        final int emptyProcessLimit;
13496        final int hiddenProcessLimit;
13497        if (mProcessLimit <= 0) {
13498            emptyProcessLimit = hiddenProcessLimit = 0;
13499        } else if (mProcessLimit == 1) {
13500            emptyProcessLimit = 1;
13501            hiddenProcessLimit = 0;
13502        } else {
13503            emptyProcessLimit = (mProcessLimit*2)/3;
13504            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13505        }
13506
13507        // Let's determine how many processes we have running vs.
13508        // how many slots we have for background processes; we may want
13509        // to put multiple processes in a slot of there are enough of
13510        // them.
13511        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13512                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13513        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13514        if (numEmptyProcs > hiddenProcessLimit) {
13515            // If there are more empty processes than our limit on hidden
13516            // processes, then use the hidden process limit for the factor.
13517            // This ensures that the really old empty processes get pushed
13518            // down to the bottom, so if we are running low on memory we will
13519            // have a better chance at keeping around more hidden processes
13520            // instead of a gazillion empty processes.
13521            numEmptyProcs = hiddenProcessLimit;
13522        }
13523        int emptyFactor = numEmptyProcs/numSlots;
13524        if (emptyFactor < 1) emptyFactor = 1;
13525        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13526        if (hiddenFactor < 1) hiddenFactor = 1;
13527        int stepHidden = 0;
13528        int stepEmpty = 0;
13529        int numHidden = 0;
13530        int numEmpty = 0;
13531        int numTrimming = 0;
13532
13533        mNumNonHiddenProcs = 0;
13534        mNumHiddenProcs = 0;
13535
13536        // First update the OOM adjustment for each of the
13537        // application processes based on their current state.
13538        int i = mLruProcesses.size();
13539        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13540        int nextHiddenAdj = curHiddenAdj+1;
13541        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13542        int nextEmptyAdj = curEmptyAdj+2;
13543        int curClientHiddenAdj = curEmptyAdj;
13544        while (i > 0) {
13545            i--;
13546            ProcessRecord app = mLruProcesses.get(i);
13547            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13548            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13549            if (!app.killedBackground) {
13550                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13551                    // This process was assigned as a hidden process...  step the
13552                    // hidden level.
13553                    mNumHiddenProcs++;
13554                    if (curHiddenAdj != nextHiddenAdj) {
13555                        stepHidden++;
13556                        if (stepHidden >= hiddenFactor) {
13557                            stepHidden = 0;
13558                            curHiddenAdj = nextHiddenAdj;
13559                            nextHiddenAdj += 2;
13560                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13561                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13562                            }
13563                            if (curClientHiddenAdj <= curHiddenAdj) {
13564                                curClientHiddenAdj = curHiddenAdj + 1;
13565                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13566                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13567                                }
13568                            }
13569                        }
13570                    }
13571                    numHidden++;
13572                    if (numHidden > hiddenProcessLimit) {
13573                        Slog.i(TAG, "No longer want " + app.processName
13574                                + " (pid " + app.pid + "): hidden #" + numHidden);
13575                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13576                                app.processName, app.setAdj, "too many background");
13577                        app.killedBackground = true;
13578                        Process.killProcessQuiet(app.pid);
13579                    }
13580                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13581                    // This process has a client that has activities.  We will have
13582                    // given it the current hidden adj; here we will just leave it
13583                    // without stepping the hidden adj.
13584                    curClientHiddenAdj++;
13585                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13586                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13587                    }
13588                } else {
13589                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13590                        // This process was assigned as an empty process...  step the
13591                        // empty level.
13592                        if (curEmptyAdj != nextEmptyAdj) {
13593                            stepEmpty++;
13594                            if (stepEmpty >= emptyFactor) {
13595                                stepEmpty = 0;
13596                                curEmptyAdj = nextEmptyAdj;
13597                                nextEmptyAdj += 2;
13598                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13599                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13600                                }
13601                            }
13602                        }
13603                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13604                        mNumNonHiddenProcs++;
13605                    }
13606                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13607                            && !app.hasClientActivities) {
13608                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13609                                && app.lastActivityTime < oldTime) {
13610                            Slog.i(TAG, "No longer want " + app.processName
13611                                    + " (pid " + app.pid + "): empty for "
13612                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13613                                            / 1000) + "s");
13614                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13615                                    app.processName, app.setAdj, "old background process");
13616                            app.killedBackground = true;
13617                            Process.killProcessQuiet(app.pid);
13618                        } else {
13619                            numEmpty++;
13620                            if (numEmpty > emptyProcessLimit) {
13621                                Slog.i(TAG, "No longer want " + app.processName
13622                                        + " (pid " + app.pid + "): empty #" + numEmpty);
13623                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13624                                        app.processName, app.setAdj, "too many background");
13625                                app.killedBackground = true;
13626                                Process.killProcessQuiet(app.pid);
13627                            }
13628                        }
13629                    }
13630                }
13631                if (app.isolated && app.services.size() <= 0) {
13632                    // If this is an isolated process, and there are no
13633                    // services running in it, then the process is no longer
13634                    // needed.  We agressively kill these because we can by
13635                    // definition not re-use the same process again, and it is
13636                    // good to avoid having whatever code was running in them
13637                    // left sitting around after no longer needed.
13638                    Slog.i(TAG, "Isolated process " + app.processName
13639                            + " (pid " + app.pid + ") no longer needed");
13640                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13641                            app.processName, app.setAdj, "isolated not needed");
13642                    app.killedBackground = true;
13643                    Process.killProcessQuiet(app.pid);
13644                }
13645                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13646                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13647                        && !app.killedBackground) {
13648                    numTrimming++;
13649                }
13650            }
13651        }
13652
13653        mNumServiceProcs = mNewNumServiceProcs;
13654
13655        // Now determine the memory trimming level of background processes.
13656        // Unfortunately we need to start at the back of the list to do this
13657        // properly.  We only do this if the number of background apps we
13658        // are managing to keep around is less than half the maximum we desire;
13659        // if we are keeping a good number around, we'll let them use whatever
13660        // memory they want.
13661        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13662                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13663            final int numHiddenAndEmpty = numHidden + numEmpty;
13664            final int N = mLruProcesses.size();
13665            int factor = numTrimming/3;
13666            int minFactor = 2;
13667            if (mHomeProcess != null) minFactor++;
13668            if (mPreviousProcess != null) minFactor++;
13669            if (factor < minFactor) factor = minFactor;
13670            int step = 0;
13671            int fgTrimLevel;
13672            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13673                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13674            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13675                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13676            } else {
13677                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13678            }
13679            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13680            for (i=0; i<N; i++) {
13681                ProcessRecord app = mLruProcesses.get(i);
13682                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13683                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13684                        && !app.killedBackground) {
13685                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13686                        try {
13687                            app.thread.scheduleTrimMemory(curLevel);
13688                        } catch (RemoteException e) {
13689                        }
13690                        if (false) {
13691                            // For now we won't do this; our memory trimming seems
13692                            // to be good enough at this point that destroying
13693                            // activities causes more harm than good.
13694                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13695                                    && app != mHomeProcess && app != mPreviousProcess) {
13696                                // Need to do this on its own message because the stack may not
13697                                // be in a consistent state at this point.
13698                                // For these apps we will also finish their activities
13699                                // to help them free memory.
13700                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13701                            }
13702                        }
13703                    }
13704                    app.trimMemoryLevel = curLevel;
13705                    step++;
13706                    if (step >= factor) {
13707                        step = 0;
13708                        switch (curLevel) {
13709                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13710                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13711                                break;
13712                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13713                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13714                                break;
13715                        }
13716                    }
13717                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13718                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13719                            && app.thread != null) {
13720                        try {
13721                            app.thread.scheduleTrimMemory(
13722                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13723                        } catch (RemoteException e) {
13724                        }
13725                    }
13726                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13727                } else {
13728                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13729                            && app.pendingUiClean) {
13730                        // If this application is now in the background and it
13731                        // had done UI, then give it the special trim level to
13732                        // have it free UI resources.
13733                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13734                        if (app.trimMemoryLevel < level && app.thread != null) {
13735                            try {
13736                                app.thread.scheduleTrimMemory(level);
13737                            } catch (RemoteException e) {
13738                            }
13739                        }
13740                        app.pendingUiClean = false;
13741                    }
13742                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13743                        try {
13744                            app.thread.scheduleTrimMemory(fgTrimLevel);
13745                        } catch (RemoteException e) {
13746                        }
13747                    }
13748                    app.trimMemoryLevel = fgTrimLevel;
13749                }
13750            }
13751        } else {
13752            final int N = mLruProcesses.size();
13753            for (i=0; i<N; i++) {
13754                ProcessRecord app = mLruProcesses.get(i);
13755                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13756                        && app.pendingUiClean) {
13757                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13758                            && app.thread != null) {
13759                        try {
13760                            app.thread.scheduleTrimMemory(
13761                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13762                        } catch (RemoteException e) {
13763                        }
13764                    }
13765                    app.pendingUiClean = false;
13766                }
13767                app.trimMemoryLevel = 0;
13768            }
13769        }
13770
13771        if (mAlwaysFinishActivities) {
13772            // Need to do this on its own message because the stack may not
13773            // be in a consistent state at this point.
13774            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13775        }
13776    }
13777
13778    final void trimApplications() {
13779        synchronized (this) {
13780            int i;
13781
13782            // First remove any unused application processes whose package
13783            // has been removed.
13784            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13785                final ProcessRecord app = mRemovedProcesses.get(i);
13786                if (app.activities.size() == 0
13787                        && app.curReceiver == null && app.services.size() == 0) {
13788                    Slog.i(
13789                        TAG, "Exiting empty application process "
13790                        + app.processName + " ("
13791                        + (app.thread != null ? app.thread.asBinder() : null)
13792                        + ")\n");
13793                    if (app.pid > 0 && app.pid != MY_PID) {
13794                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13795                                app.processName, app.setAdj, "empty");
13796                        Process.killProcessQuiet(app.pid);
13797                    } else {
13798                        try {
13799                            app.thread.scheduleExit();
13800                        } catch (Exception e) {
13801                            // Ignore exceptions.
13802                        }
13803                    }
13804                    cleanUpApplicationRecordLocked(app, false, true, -1);
13805                    mRemovedProcesses.remove(i);
13806
13807                    if (app.persistent) {
13808                        if (app.persistent) {
13809                            addAppLocked(app.info, false);
13810                        }
13811                    }
13812                }
13813            }
13814
13815            // Now update the oom adj for all processes.
13816            updateOomAdjLocked();
13817        }
13818    }
13819
13820    /** This method sends the specified signal to each of the persistent apps */
13821    public void signalPersistentProcesses(int sig) throws RemoteException {
13822        if (sig != Process.SIGNAL_USR1) {
13823            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13824        }
13825
13826        synchronized (this) {
13827            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13828                    != PackageManager.PERMISSION_GRANTED) {
13829                throw new SecurityException("Requires permission "
13830                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13831            }
13832
13833            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13834                ProcessRecord r = mLruProcesses.get(i);
13835                if (r.thread != null && r.persistent) {
13836                    Process.sendSignal(r.pid, sig);
13837                }
13838            }
13839        }
13840    }
13841
13842    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13843        if (proc == null || proc == mProfileProc) {
13844            proc = mProfileProc;
13845            path = mProfileFile;
13846            profileType = mProfileType;
13847            clearProfilerLocked();
13848        }
13849        if (proc == null) {
13850            return;
13851        }
13852        try {
13853            proc.thread.profilerControl(false, path, null, profileType);
13854        } catch (RemoteException e) {
13855            throw new IllegalStateException("Process disappeared");
13856        }
13857    }
13858
13859    private void clearProfilerLocked() {
13860        if (mProfileFd != null) {
13861            try {
13862                mProfileFd.close();
13863            } catch (IOException e) {
13864            }
13865        }
13866        mProfileApp = null;
13867        mProfileProc = null;
13868        mProfileFile = null;
13869        mProfileType = 0;
13870        mAutoStopProfiler = false;
13871    }
13872
13873    public boolean profileControl(String process, int userId, boolean start,
13874            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13875
13876        try {
13877            synchronized (this) {
13878                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13879                // its own permission.
13880                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13881                        != PackageManager.PERMISSION_GRANTED) {
13882                    throw new SecurityException("Requires permission "
13883                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13884                }
13885
13886                if (start && fd == null) {
13887                    throw new IllegalArgumentException("null fd");
13888                }
13889
13890                ProcessRecord proc = null;
13891                if (process != null) {
13892                    proc = findProcessLocked(process, userId, "profileControl");
13893                }
13894
13895                if (start && (proc == null || proc.thread == null)) {
13896                    throw new IllegalArgumentException("Unknown process: " + process);
13897                }
13898
13899                if (start) {
13900                    stopProfilerLocked(null, null, 0);
13901                    setProfileApp(proc.info, proc.processName, path, fd, false);
13902                    mProfileProc = proc;
13903                    mProfileType = profileType;
13904                    try {
13905                        fd = fd.dup();
13906                    } catch (IOException e) {
13907                        fd = null;
13908                    }
13909                    proc.thread.profilerControl(start, path, fd, profileType);
13910                    fd = null;
13911                    mProfileFd = null;
13912                } else {
13913                    stopProfilerLocked(proc, path, profileType);
13914                    if (fd != null) {
13915                        try {
13916                            fd.close();
13917                        } catch (IOException e) {
13918                        }
13919                    }
13920                }
13921
13922                return true;
13923            }
13924        } catch (RemoteException e) {
13925            throw new IllegalStateException("Process disappeared");
13926        } finally {
13927            if (fd != null) {
13928                try {
13929                    fd.close();
13930                } catch (IOException e) {
13931                }
13932            }
13933        }
13934    }
13935
13936    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13937        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13938                userId, true, true, callName, null);
13939        ProcessRecord proc = null;
13940        try {
13941            int pid = Integer.parseInt(process);
13942            synchronized (mPidsSelfLocked) {
13943                proc = mPidsSelfLocked.get(pid);
13944            }
13945        } catch (NumberFormatException e) {
13946        }
13947
13948        if (proc == null) {
13949            HashMap<String, SparseArray<ProcessRecord>> all
13950                    = mProcessNames.getMap();
13951            SparseArray<ProcessRecord> procs = all.get(process);
13952            if (procs != null && procs.size() > 0) {
13953                proc = procs.valueAt(0);
13954                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13955                    for (int i=1; i<procs.size(); i++) {
13956                        ProcessRecord thisProc = procs.valueAt(i);
13957                        if (thisProc.userId == userId) {
13958                            proc = thisProc;
13959                            break;
13960                        }
13961                    }
13962                }
13963            }
13964        }
13965
13966        return proc;
13967    }
13968
13969    public boolean dumpHeap(String process, int userId, boolean managed,
13970            String path, ParcelFileDescriptor fd) throws RemoteException {
13971
13972        try {
13973            synchronized (this) {
13974                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13975                // its own permission (same as profileControl).
13976                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13977                        != PackageManager.PERMISSION_GRANTED) {
13978                    throw new SecurityException("Requires permission "
13979                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13980                }
13981
13982                if (fd == null) {
13983                    throw new IllegalArgumentException("null fd");
13984                }
13985
13986                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13987                if (proc == null || proc.thread == null) {
13988                    throw new IllegalArgumentException("Unknown process: " + process);
13989                }
13990
13991                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13992                if (!isDebuggable) {
13993                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13994                        throw new SecurityException("Process not debuggable: " + proc);
13995                    }
13996                }
13997
13998                proc.thread.dumpHeap(managed, path, fd);
13999                fd = null;
14000                return true;
14001            }
14002        } catch (RemoteException e) {
14003            throw new IllegalStateException("Process disappeared");
14004        } finally {
14005            if (fd != null) {
14006                try {
14007                    fd.close();
14008                } catch (IOException e) {
14009                }
14010            }
14011        }
14012    }
14013
14014    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14015    public void monitor() {
14016        synchronized (this) { }
14017    }
14018
14019    void onCoreSettingsChange(Bundle settings) {
14020        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14021            ProcessRecord processRecord = mLruProcesses.get(i);
14022            try {
14023                if (processRecord.thread != null) {
14024                    processRecord.thread.setCoreSettings(settings);
14025                }
14026            } catch (RemoteException re) {
14027                /* ignore */
14028            }
14029        }
14030    }
14031
14032    // Multi-user methods
14033
14034    @Override
14035    public boolean switchUser(int userId) {
14036        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14037                != PackageManager.PERMISSION_GRANTED) {
14038            String msg = "Permission Denial: switchUser() from pid="
14039                    + Binder.getCallingPid()
14040                    + ", uid=" + Binder.getCallingUid()
14041                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14042            Slog.w(TAG, msg);
14043            throw new SecurityException(msg);
14044        }
14045
14046        final long ident = Binder.clearCallingIdentity();
14047        try {
14048            synchronized (this) {
14049                final int oldUserId = mCurrentUserId;
14050                if (oldUserId == userId) {
14051                    return true;
14052                }
14053
14054                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14055                if (userInfo == null) {
14056                    Slog.w(TAG, "No user info for user #" + userId);
14057                    return false;
14058                }
14059
14060                mWindowManager.lockNow();
14061                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14062                        R.anim.screen_user_enter);
14063
14064                // If the user we are switching to is not currently started, then
14065                // we need to start it now.
14066                if (mStartedUsers.get(userId) == null) {
14067                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14068                    updateStartedUserArrayLocked();
14069                }
14070
14071                mCurrentUserId = userId;
14072                mCurrentUserArray = new int[] { userId };
14073                final Integer userIdInt = Integer.valueOf(userId);
14074                mUserLru.remove(userIdInt);
14075                mUserLru.add(userIdInt);
14076
14077                mWindowManager.setCurrentUser(userId);
14078
14079                final UserStartedState uss = mStartedUsers.get(userId);
14080
14081                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14082                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14083                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14084                        oldUserId, userId, uss));
14085                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14086                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14087                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14088                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14089                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14090                broadcastIntentLocked(null, null, intent,
14091                        null, null, 0, null, null, null,
14092                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14093
14094                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14095                    if (userId != 0) {
14096                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
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                                        synchronized (ActivityManagerService.this) {
14103                                            getUserManagerLocked().makeInitialized(userInfo.id);
14104                                        }
14105                                    }
14106                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14107                                userId);
14108                    } else {
14109                        getUserManagerLocked().makeInitialized(userInfo.id);
14110                    }
14111                }
14112
14113                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14114                if (!haveActivities) {
14115                    startHomeActivityLocked(userId);
14116                }
14117
14118                getUserManagerLocked().userForeground(userId);
14119                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14120            }
14121        } finally {
14122            Binder.restoreCallingIdentity(ident);
14123        }
14124
14125        return true;
14126    }
14127
14128    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14129        long ident = Binder.clearCallingIdentity();
14130        try {
14131            Intent intent;
14132            if (oldUserId >= 0) {
14133                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14134                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
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.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14144                broadcastIntentLocked(null, null, intent,
14145                        null, null, 0, null, null, null,
14146                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14147                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14148                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14149                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14150                broadcastIntentLocked(null, null, intent,
14151                        null, null, 0, null, null,
14152                        android.Manifest.permission.MANAGE_USERS,
14153                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14154            }
14155        } finally {
14156            Binder.restoreCallingIdentity(ident);
14157        }
14158    }
14159
14160    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14161            final int newUserId) {
14162        final int N = mUserSwitchObservers.beginBroadcast();
14163        if (N > 0) {
14164            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14165                int mCount = 0;
14166                @Override
14167                public void sendResult(Bundle data) throws RemoteException {
14168                    synchronized (ActivityManagerService.this) {
14169                        if (mCurUserSwitchCallback == this) {
14170                            mCount++;
14171                            if (mCount == N) {
14172                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14173                            }
14174                        }
14175                    }
14176                }
14177            };
14178            synchronized (this) {
14179                mCurUserSwitchCallback = callback;
14180            }
14181            for (int i=0; i<N; i++) {
14182                try {
14183                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14184                            newUserId, callback);
14185                } catch (RemoteException e) {
14186                }
14187            }
14188        } else {
14189            synchronized (this) {
14190                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14191            }
14192        }
14193        mUserSwitchObservers.finishBroadcast();
14194    }
14195
14196    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14197        synchronized (this) {
14198            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14199            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14200        }
14201    }
14202
14203    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14204        mCurUserSwitchCallback = null;
14205        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14206        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14207                oldUserId, newUserId, uss));
14208    }
14209
14210    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14211        final int N = mUserSwitchObservers.beginBroadcast();
14212        for (int i=0; i<N; i++) {
14213            try {
14214                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14215            } catch (RemoteException e) {
14216            }
14217        }
14218        mUserSwitchObservers.finishBroadcast();
14219        synchronized (this) {
14220            mWindowManager.stopFreezingScreen();
14221        }
14222    }
14223
14224    void finishUserSwitch(UserStartedState uss) {
14225        synchronized (this) {
14226            if (uss.mState == UserStartedState.STATE_BOOTING
14227                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14228                uss.mState = UserStartedState.STATE_RUNNING;
14229                final int userId = uss.mHandle.getIdentifier();
14230                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14231                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14232                broadcastIntentLocked(null, null, intent,
14233                        null, null, 0, null, null,
14234                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14235                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14236            }
14237            int num = mUserLru.size();
14238            int i = 0;
14239            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14240                Integer oldUserId = mUserLru.get(i);
14241                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14242                if (oldUss == null) {
14243                    // Shouldn't happen, but be sane if it does.
14244                    mUserLru.remove(i);
14245                    num--;
14246                    continue;
14247                }
14248                if (oldUss.mState == UserStartedState.STATE_STOPPING) {
14249                    // This user is already stopping, doesn't count.
14250                    num--;
14251                    i++;
14252                    continue;
14253                }
14254                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14255                    // Owner and current can't be stopped, but count as running.
14256                    i++;
14257                    continue;
14258                }
14259                // This is a user to be stopped.
14260                stopUserLocked(oldUserId, null);
14261                num--;
14262                i++;
14263            }
14264        }
14265    }
14266
14267    @Override
14268    public int stopUser(final int userId, final IStopUserCallback callback) {
14269        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14270                != PackageManager.PERMISSION_GRANTED) {
14271            String msg = "Permission Denial: switchUser() from pid="
14272                    + Binder.getCallingPid()
14273                    + ", uid=" + Binder.getCallingUid()
14274                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14275            Slog.w(TAG, msg);
14276            throw new SecurityException(msg);
14277        }
14278        if (userId <= 0) {
14279            throw new IllegalArgumentException("Can't stop primary user " + userId);
14280        }
14281        synchronized (this) {
14282            return stopUserLocked(userId, callback);
14283        }
14284    }
14285
14286    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14287        if (mCurrentUserId == userId) {
14288            return ActivityManager.USER_OP_IS_CURRENT;
14289        }
14290
14291        final UserStartedState uss = mStartedUsers.get(userId);
14292        if (uss == null) {
14293            // User is not started, nothing to do...  but we do need to
14294            // callback if requested.
14295            if (callback != null) {
14296                mHandler.post(new Runnable() {
14297                    @Override
14298                    public void run() {
14299                        try {
14300                            callback.userStopped(userId);
14301                        } catch (RemoteException e) {
14302                        }
14303                    }
14304                });
14305            }
14306            return ActivityManager.USER_OP_SUCCESS;
14307        }
14308
14309        if (callback != null) {
14310            uss.mStopCallbacks.add(callback);
14311        }
14312
14313        if (uss.mState != UserStartedState.STATE_STOPPING) {
14314            uss.mState = UserStartedState.STATE_STOPPING;
14315
14316            long ident = Binder.clearCallingIdentity();
14317            try {
14318                // Inform of user switch
14319                Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14320                final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14321                    @Override
14322                    public void performReceive(Intent intent, int resultCode, String data,
14323                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14324                        finishUserStop(uss);
14325                    }
14326                };
14327                broadcastIntentLocked(null, null, intent,
14328                        null, resultReceiver, 0, null, null, null,
14329                        true, false, MY_PID, Process.SYSTEM_UID, userId);
14330            } finally {
14331                Binder.restoreCallingIdentity(ident);
14332            }
14333        }
14334
14335        return ActivityManager.USER_OP_SUCCESS;
14336    }
14337
14338    void finishUserStop(UserStartedState uss) {
14339        final int userId = uss.mHandle.getIdentifier();
14340        boolean stopped;
14341        ArrayList<IStopUserCallback> callbacks;
14342        synchronized (this) {
14343            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14344            if (uss.mState != UserStartedState.STATE_STOPPING
14345                    || mStartedUsers.get(userId) != uss) {
14346                stopped = false;
14347            } else {
14348                stopped = true;
14349                // User can no longer run.
14350                mStartedUsers.remove(userId);
14351                mUserLru.remove(Integer.valueOf(userId));
14352                updateStartedUserArrayLocked();
14353
14354                // Clean up all state and processes associated with the user.
14355                // Kill all the processes for the user.
14356                forceStopUserLocked(userId);
14357            }
14358        }
14359
14360        for (int i=0; i<callbacks.size(); i++) {
14361            try {
14362                if (stopped) callbacks.get(i).userStopped(userId);
14363                else callbacks.get(i).userStopAborted(userId);
14364            } catch (RemoteException e) {
14365            }
14366        }
14367    }
14368
14369    @Override
14370    public UserInfo getCurrentUser() {
14371        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14372                != PackageManager.PERMISSION_GRANTED) && (
14373                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14374                != PackageManager.PERMISSION_GRANTED)) {
14375            String msg = "Permission Denial: getCurrentUser() from pid="
14376                    + Binder.getCallingPid()
14377                    + ", uid=" + Binder.getCallingUid()
14378                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14379            Slog.w(TAG, msg);
14380            throw new SecurityException(msg);
14381        }
14382        synchronized (this) {
14383            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14384        }
14385    }
14386
14387    int getCurrentUserIdLocked() {
14388        return mCurrentUserId;
14389    }
14390
14391    @Override
14392    public boolean isUserRunning(int userId) {
14393        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14394                != PackageManager.PERMISSION_GRANTED) {
14395            String msg = "Permission Denial: isUserRunning() from pid="
14396                    + Binder.getCallingPid()
14397                    + ", uid=" + Binder.getCallingUid()
14398                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14399            Slog.w(TAG, msg);
14400            throw new SecurityException(msg);
14401        }
14402        synchronized (this) {
14403            return isUserRunningLocked(userId);
14404        }
14405    }
14406
14407    boolean isUserRunningLocked(int userId) {
14408        UserStartedState state = mStartedUsers.get(userId);
14409        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14410    }
14411
14412    @Override
14413    public int[] getRunningUserIds() {
14414        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14415                != PackageManager.PERMISSION_GRANTED) {
14416            String msg = "Permission Denial: isUserRunning() from pid="
14417                    + Binder.getCallingPid()
14418                    + ", uid=" + Binder.getCallingUid()
14419                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14420            Slog.w(TAG, msg);
14421            throw new SecurityException(msg);
14422        }
14423        synchronized (this) {
14424            return mStartedUserArray;
14425        }
14426    }
14427
14428    private void updateStartedUserArrayLocked() {
14429        mStartedUserArray = new int[mStartedUsers.size()];
14430        for (int i=0; i<mStartedUsers.size();  i++) {
14431            mStartedUserArray[i] = mStartedUsers.keyAt(i);
14432        }
14433    }
14434
14435    @Override
14436    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14437        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14438                != PackageManager.PERMISSION_GRANTED) {
14439            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14440                    + Binder.getCallingPid()
14441                    + ", uid=" + Binder.getCallingUid()
14442                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14443            Slog.w(TAG, msg);
14444            throw new SecurityException(msg);
14445        }
14446
14447        mUserSwitchObservers.register(observer);
14448    }
14449
14450    @Override
14451    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14452        mUserSwitchObservers.unregister(observer);
14453    }
14454
14455    private boolean userExists(int userId) {
14456        if (userId == 0) {
14457            return true;
14458        }
14459        UserManagerService ums = getUserManagerLocked();
14460        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14461    }
14462
14463    int[] getUsersLocked() {
14464        UserManagerService ums = getUserManagerLocked();
14465        return ums != null ? ums.getUserIds() : new int[] { 0 };
14466    }
14467
14468    UserManagerService getUserManagerLocked() {
14469        if (mUserManager == null) {
14470            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14471            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14472        }
14473        return mUserManager;
14474    }
14475
14476    private void checkValidCaller(int uid, int userId) {
14477        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14478
14479        throw new SecurityException("Caller uid=" + uid
14480                + " is not privileged to communicate with user=" + userId);
14481    }
14482
14483    private int applyUserId(int uid, int userId) {
14484        return UserHandle.getUid(userId, uid);
14485    }
14486
14487    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14488        if (info == null) return null;
14489        ApplicationInfo newInfo = new ApplicationInfo(info);
14490        newInfo.uid = applyUserId(info.uid, userId);
14491        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14492                + info.packageName;
14493        return newInfo;
14494    }
14495
14496    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14497        if (aInfo == null
14498                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14499            return aInfo;
14500        }
14501
14502        ActivityInfo info = new ActivityInfo(aInfo);
14503        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14504        return info;
14505    }
14506}
14507