ActivityManagerService.java revision 7d19e0242faac8017033dabb872cdf1542fa184c
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.wm.WindowManagerService;
31
32import dalvik.system.Zygote;
33
34import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
37import android.app.ActivityOptions;
38import android.app.ActivityThread;
39import android.app.AlertDialog;
40import android.app.AppGlobals;
41import android.app.ApplicationErrorReport;
42import android.app.Dialog;
43import android.app.IActivityController;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
46import android.app.INotificationManager;
47import android.app.IProcessObserver;
48import android.app.IServiceConnection;
49import android.app.IThumbnailReceiver;
50import android.app.Instrumentation;
51import android.app.Notification;
52import android.app.NotificationManager;
53import android.app.PendingIntent;
54import android.app.Service;
55import android.app.backup.IBackupManager;
56import android.content.ActivityNotFoundException;
57import android.content.BroadcastReceiver;
58import android.content.ClipData;
59import android.content.ComponentCallbacks2;
60import android.content.ComponentName;
61import android.content.ContentProvider;
62import android.content.ContentResolver;
63import android.content.Context;
64import android.content.DialogInterface;
65import android.content.IContentProvider;
66import android.content.IIntentReceiver;
67import android.content.IIntentSender;
68import android.content.Intent;
69import android.content.IntentFilter;
70import android.content.IntentSender;
71import android.content.pm.ActivityInfo;
72import android.content.pm.ApplicationInfo;
73import android.content.pm.ConfigurationInfo;
74import android.content.pm.IPackageDataObserver;
75import android.content.pm.IPackageManager;
76import android.content.pm.InstrumentationInfo;
77import android.content.pm.PackageInfo;
78import android.content.pm.PackageManager;
79import android.content.pm.PackageManager.NameNotFoundException;
80import android.content.pm.PathPermission;
81import android.content.pm.ProviderInfo;
82import android.content.pm.ResolveInfo;
83import android.content.pm.ServiceInfo;
84import android.content.pm.UserInfo;
85import android.content.res.CompatibilityInfo;
86import android.content.res.Configuration;
87import android.graphics.Bitmap;
88import android.net.Proxy;
89import android.net.ProxyProperties;
90import android.net.Uri;
91import android.os.Binder;
92import android.os.Build;
93import android.os.Bundle;
94import android.os.Debug;
95import android.os.DropBoxManager;
96import android.os.Environment;
97import android.os.FileObserver;
98import android.os.FileUtils;
99import android.os.Handler;
100import android.os.IBinder;
101import android.os.IPermissionController;
102import android.os.Looper;
103import android.os.Message;
104import android.os.Parcel;
105import android.os.ParcelFileDescriptor;
106import android.os.Process;
107import android.os.RemoteCallbackList;
108import android.os.RemoteException;
109import android.os.ServiceManager;
110import android.os.StrictMode;
111import android.os.SystemClock;
112import android.os.SystemProperties;
113import android.os.UserId;
114import android.provider.Settings;
115import android.text.format.Time;
116import android.util.EventLog;
117import android.util.Log;
118import android.util.Pair;
119import android.util.PrintWriterPrinter;
120import android.util.Slog;
121import android.util.SparseArray;
122import android.util.SparseIntArray;
123import android.util.TimeUtils;
124import android.view.Gravity;
125import android.view.LayoutInflater;
126import android.view.View;
127import android.view.WindowManager;
128import android.view.WindowManagerPolicy;
129
130import java.io.BufferedInputStream;
131import java.io.BufferedOutputStream;
132import java.io.BufferedReader;
133import java.io.DataInputStream;
134import java.io.DataOutputStream;
135import java.io.File;
136import java.io.FileDescriptor;
137import java.io.FileInputStream;
138import java.io.FileNotFoundException;
139import java.io.FileOutputStream;
140import java.io.IOException;
141import java.io.InputStreamReader;
142import java.io.PrintWriter;
143import java.io.StringWriter;
144import java.lang.ref.WeakReference;
145import java.util.ArrayList;
146import java.util.Collection;
147import java.util.Collections;
148import java.util.Comparator;
149import java.util.HashMap;
150import java.util.HashSet;
151import java.util.Iterator;
152import java.util.List;
153import java.util.Locale;
154import java.util.Map;
155import java.util.Map.Entry;
156import java.util.Set;
157import java.util.concurrent.atomic.AtomicBoolean;
158import java.util.concurrent.atomic.AtomicLong;
159
160public final class ActivityManagerService extends ActivityManagerNative
161        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
162    private static final String USER_DATA_DIR = "/data/user/";
163    static final String TAG = "ActivityManager";
164    static final String TAG_MU = "ActivityManagerServiceMU";
165    static final boolean DEBUG = false;
166    static final boolean localLOGV = DEBUG;
167    static final boolean DEBUG_SWITCH = localLOGV || false;
168    static final boolean DEBUG_TASKS = localLOGV || false;
169    static final boolean DEBUG_PAUSE = localLOGV || false;
170    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
171    static final boolean DEBUG_TRANSITION = localLOGV || false;
172    static final boolean DEBUG_BROADCAST = localLOGV || false;
173    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_SERVICE = localLOGV || false;
176    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
177    static final boolean DEBUG_VISBILITY = localLOGV || false;
178    static final boolean DEBUG_PROCESSES = localLOGV || false;
179    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
180    static final boolean DEBUG_PROVIDER = localLOGV || false;
181    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
182    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
183    static final boolean DEBUG_RESULTS = localLOGV || false;
184    static final boolean DEBUG_BACKUP = localLOGV || false;
185    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
186    static final boolean DEBUG_POWER = localLOGV || false;
187    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
188    static final boolean DEBUG_MU = localLOGV || false;
189    static final boolean VALIDATE_TOKENS = false;
190    static final boolean SHOW_ACTIVITY_START_TIME = true;
191
192    // Control over CPU and battery monitoring.
193    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
194    static final boolean MONITOR_CPU_USAGE = true;
195    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
196    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
197    static final boolean MONITOR_THREAD_CPU_USAGE = false;
198
199    // The flags that are set for all calls we make to the package manager.
200    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
201
202    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
203
204    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
205
206    // Maximum number of recent tasks that we can remember.
207    static final int MAX_RECENT_TASKS = 20;
208
209    // Amount of time after a call to stopAppSwitches() during which we will
210    // prevent further untrusted switches from happening.
211    static final long APP_SWITCH_DELAY_TIME = 5*1000;
212
213    // How long we wait for a launched process to attach to the activity manager
214    // before we decide it's never going to come up for real.
215    static final int PROC_START_TIMEOUT = 10*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real, when the process was
219    // started with a wrapper for instrumentation (such as Valgrind) because it
220    // could take much longer than usual.
221    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
222
223    // How long to wait after going idle before forcing apps to GC.
224    static final int GC_TIMEOUT = 5*1000;
225
226    // The minimum amount of time between successive GC requests for a process.
227    static final int GC_MIN_INTERVAL = 60*1000;
228
229    // The rate at which we check for apps using excessive power -- 15 mins.
230    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
231
232    // The minimum sample duration we will allow before deciding we have
233    // enough data on wake locks to start killing things.
234    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on CPU usage to start killing things.
238    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // How long we allow a receiver to run before giving up on it.
241    static final int BROADCAST_FG_TIMEOUT = 10*1000;
242    static final int BROADCAST_BG_TIMEOUT = 60*1000;
243
244    // How long we wait until we timeout on key dispatching.
245    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
246
247    // How long we wait until we timeout on key dispatching during instrumentation.
248    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
249
250    static final int MY_PID = Process.myPid();
251
252    static final String[] EMPTY_STRING_ARRAY = new String[0];
253
254    public ActivityStack mMainStack;
255
256    private final boolean mHeadless;
257
258    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
259    // default actuion automatically.  Important for devices without direct input
260    // devices.
261    private boolean mShowDialogs = true;
262
263    /**
264     * Description of a request to start a new activity, which has been held
265     * due to app switches being disabled.
266     */
267    static class PendingActivityLaunch {
268        ActivityRecord r;
269        ActivityRecord sourceRecord;
270        int startFlags;
271    }
272
273    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274            = new ArrayList<PendingActivityLaunch>();
275
276
277    BroadcastQueue mFgBroadcastQueue;
278    BroadcastQueue mBgBroadcastQueue;
279    // Convenient for easy iteration over the queues. Foreground is first
280    // so that dispatch of foreground broadcasts gets precedence.
281    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
282
283    BroadcastQueue broadcastQueueForIntent(Intent intent) {
284        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
285        if (DEBUG_BACKGROUND_BROADCAST) {
286            Slog.i(TAG, "Broadcast intent " + intent + " on "
287                    + (isFg ? "foreground" : "background")
288                    + " queue");
289        }
290        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
291    }
292
293    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
294        for (BroadcastQueue queue : mBroadcastQueues) {
295            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
296            if (r != null) {
297                return r;
298            }
299        }
300        return null;
301    }
302
303    /**
304     * Activity we have told the window manager to have key focus.
305     */
306    ActivityRecord mFocusedActivity = null;
307    /**
308     * List of intents that were used to start the most recent tasks.
309     */
310    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
311
312    /**
313     * Process management.
314     */
315    final ProcessList mProcessList = new ProcessList();
316
317    /**
318     * All of the applications we currently have running organized by name.
319     * The keys are strings of the application package name (as
320     * returned by the package manager), and the keys are ApplicationRecord
321     * objects.
322     */
323    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
324
325    /**
326     * The currently running isolated processes.
327     */
328    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
329
330    /**
331     * Counter for assigning isolated process uids, to avoid frequently reusing the
332     * same ones.
333     */
334    int mNextIsolatedProcessUid = 0;
335
336    /**
337     * The currently running heavy-weight process, if any.
338     */
339    ProcessRecord mHeavyWeightProcess = null;
340
341    /**
342     * The last time that various processes have crashed.
343     */
344    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
345
346    /**
347     * Set of applications that we consider to be bad, and will reject
348     * incoming broadcasts from (which the user has no control over).
349     * Processes are added to this set when they have crashed twice within
350     * a minimum amount of time; they are removed from it when they are
351     * later restarted (hopefully due to some user action).  The value is the
352     * time it was added to the list.
353     */
354    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
355
356    /**
357     * All of the processes we currently have running organized by pid.
358     * The keys are the pid running the application.
359     *
360     * <p>NOTE: This object is protected by its own lock, NOT the global
361     * activity manager lock!
362     */
363    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
364
365    /**
366     * All of the processes that have been forced to be foreground.  The key
367     * is the pid of the caller who requested it (we hold a death
368     * link on it).
369     */
370    abstract class ForegroundToken implements IBinder.DeathRecipient {
371        int pid;
372        IBinder token;
373    }
374    final SparseArray<ForegroundToken> mForegroundProcesses
375            = new SparseArray<ForegroundToken>();
376
377    /**
378     * List of records for processes that someone had tried to start before the
379     * system was ready.  We don't start them at that point, but ensure they
380     * are started by the time booting is complete.
381     */
382    final ArrayList<ProcessRecord> mProcessesOnHold
383            = new ArrayList<ProcessRecord>();
384
385    /**
386     * List of persistent applications that are in the process
387     * of being started.
388     */
389    final ArrayList<ProcessRecord> mPersistentStartingProcesses
390            = new ArrayList<ProcessRecord>();
391
392    /**
393     * Processes that are being forcibly torn down.
394     */
395    final ArrayList<ProcessRecord> mRemovedProcesses
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of running applications, sorted by recent usage.
400     * The first entry in the list is the least recently used.
401     * It contains ApplicationRecord objects.  This list does NOT include
402     * any persistent application records (since we never want to exit them).
403     */
404    final ArrayList<ProcessRecord> mLruProcesses
405            = new ArrayList<ProcessRecord>();
406
407    /**
408     * List of processes that should gc as soon as things are idle.
409     */
410    final ArrayList<ProcessRecord> mProcessesToGc
411            = new ArrayList<ProcessRecord>();
412
413    /**
414     * This is the process holding what we currently consider to be
415     * the "home" activity.
416     */
417    ProcessRecord mHomeProcess;
418
419    /**
420     * This is the process holding the activity the user last visited that
421     * is in a different process from the one they are currently in.
422     */
423    ProcessRecord mPreviousProcess;
424
425    /**
426     * The time at which the previous process was last visible.
427     */
428    long mPreviousProcessVisibleTime;
429
430    /**
431     * Packages that the user has asked to have run in screen size
432     * compatibility mode instead of filling the screen.
433     */
434    final CompatModePackages mCompatModePackages;
435
436    /**
437     * Set of PendingResultRecord objects that are currently active.
438     */
439    final HashSet mPendingResultRecords = new HashSet();
440
441    /**
442     * Set of IntentSenderRecord objects that are currently active.
443     */
444    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
445            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
446
447    /**
448     * Fingerprints (hashCode()) of stack traces that we've
449     * already logged DropBox entries for.  Guarded by itself.  If
450     * something (rogue user app) forces this over
451     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
452     */
453    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
454    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
455
456    /**
457     * Strict Mode background batched logging state.
458     *
459     * The string buffer is guarded by itself, and its lock is also
460     * used to determine if another batched write is already
461     * in-flight.
462     */
463    private final StringBuilder mStrictModeBuffer = new StringBuilder();
464
465    /**
466     * Keeps track of all IIntentReceivers that have been registered for
467     * broadcasts.  Hash keys are the receiver IBinder, hash value is
468     * a ReceiverList.
469     */
470    final HashMap mRegisteredReceivers = new HashMap();
471
472    /**
473     * Resolver for broadcast intents to registered receivers.
474     * Holds BroadcastFilter (subclass of IntentFilter).
475     */
476    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
477            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
478        @Override
479        protected boolean allowFilterResult(
480                BroadcastFilter filter, List<BroadcastFilter> dest) {
481            IBinder target = filter.receiverList.receiver.asBinder();
482            for (int i=dest.size()-1; i>=0; i--) {
483                if (dest.get(i).receiverList.receiver.asBinder() == target) {
484                    return false;
485                }
486            }
487            return true;
488        }
489
490        @Override
491        protected BroadcastFilter[] newArray(int size) {
492            return new BroadcastFilter[size];
493        }
494
495        @Override
496        protected String packageForFilter(BroadcastFilter filter) {
497            return filter.packageName;
498        }
499    };
500
501    /**
502     * State of all active sticky broadcasts.  Keys are the action of the
503     * sticky Intent, values are an ArrayList of all broadcasted intents with
504     * that action (which should usually be one).
505     */
506    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
507            new HashMap<String, ArrayList<Intent>>();
508
509    final ActiveServices mServices;
510
511    /**
512     * Backup/restore process management
513     */
514    String mBackupAppName = null;
515    BackupRecord mBackupTarget = null;
516
517    /**
518     * List of PendingThumbnailsRecord objects of clients who are still
519     * waiting to receive all of the thumbnails for a task.
520     */
521    final ArrayList mPendingThumbnails = new ArrayList();
522
523    /**
524     * List of HistoryRecord objects that have been finished and must
525     * still report back to a pending thumbnail receiver.
526     */
527    final ArrayList mCancelledThumbnails = new ArrayList();
528
529    final ProviderMap mProviderMap = new ProviderMap();
530
531    /**
532     * List of content providers who have clients waiting for them.  The
533     * application is currently being launched and the provider will be
534     * removed from this list once it is published.
535     */
536    final ArrayList<ContentProviderRecord> mLaunchingProviders
537            = new ArrayList<ContentProviderRecord>();
538
539    /**
540     * Global set of specific Uri permissions that have been granted.
541     */
542    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
543            = new SparseArray<HashMap<Uri, UriPermission>>();
544
545    CoreSettingsObserver mCoreSettingsObserver;
546
547    /**
548     * Thread-local storage used to carry caller permissions over through
549     * indirect content-provider access.
550     * @see #ActivityManagerService.openContentUri()
551     */
552    private class Identity {
553        public int pid;
554        public int uid;
555
556        Identity(int _pid, int _uid) {
557            pid = _pid;
558            uid = _uid;
559        }
560    }
561
562    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
563
564    /**
565     * All information we have collected about the runtime performance of
566     * any user id that can impact battery performance.
567     */
568    final BatteryStatsService mBatteryStatsService;
569
570    /**
571     * information about component usage
572     */
573    final UsageStatsService mUsageStatsService;
574
575    /**
576     * Current configuration information.  HistoryRecord objects are given
577     * a reference to this object to indicate which configuration they are
578     * currently running in, so this object must be kept immutable.
579     */
580    Configuration mConfiguration = new Configuration();
581
582    /**
583     * Current sequencing integer of the configuration, for skipping old
584     * configurations.
585     */
586    int mConfigurationSeq = 0;
587
588    /**
589     * Hardware-reported OpenGLES version.
590     */
591    final int GL_ES_VERSION;
592
593    /**
594     * List of initialization arguments to pass to all processes when binding applications to them.
595     * For example, references to the commonly used services.
596     */
597    HashMap<String, IBinder> mAppBindArgs;
598
599    /**
600     * Temporary to avoid allocations.  Protected by main lock.
601     */
602    final StringBuilder mStringBuilder = new StringBuilder(256);
603
604    /**
605     * Used to control how we initialize the service.
606     */
607    boolean mStartRunning = false;
608    ComponentName mTopComponent;
609    String mTopAction;
610    String mTopData;
611    boolean mProcessesReady = false;
612    boolean mSystemReady = false;
613    boolean mBooting = false;
614    boolean mWaitingUpdate = false;
615    boolean mDidUpdate = false;
616    boolean mOnBattery = false;
617    boolean mLaunchWarningShown = false;
618
619    Context mContext;
620
621    int mFactoryTest;
622
623    boolean mCheckedForSetup;
624
625    /**
626     * The time at which we will allow normal application switches again,
627     * after a call to {@link #stopAppSwitches()}.
628     */
629    long mAppSwitchesAllowedTime;
630
631    /**
632     * This is set to true after the first switch after mAppSwitchesAllowedTime
633     * is set; any switches after that will clear the time.
634     */
635    boolean mDidAppSwitch;
636
637    /**
638     * Last time (in realtime) at which we checked for power usage.
639     */
640    long mLastPowerCheckRealtime;
641
642    /**
643     * Last time (in uptime) at which we checked for power usage.
644     */
645    long mLastPowerCheckUptime;
646
647    /**
648     * Set while we are wanting to sleep, to prevent any
649     * activities from being started/resumed.
650     */
651    boolean mSleeping = false;
652
653    /**
654     * State of external calls telling us if the device is asleep.
655     */
656    boolean mWentToSleep = false;
657
658    /**
659     * State of external call telling us if the lock screen is shown.
660     */
661    boolean mLockScreenShown = false;
662
663    /**
664     * Set if we are shutting down the system, similar to sleeping.
665     */
666    boolean mShuttingDown = false;
667
668    /**
669     * Task identifier that activities are currently being started
670     * in.  Incremented each time a new task is created.
671     * todo: Replace this with a TokenSpace class that generates non-repeating
672     * integers that won't wrap.
673     */
674    int mCurTask = 1;
675
676    /**
677     * Current sequence id for oom_adj computation traversal.
678     */
679    int mAdjSeq = 0;
680
681    /**
682     * Current sequence id for process LRU updating.
683     */
684    int mLruSeq = 0;
685
686    /**
687     * Keep track of the number of service processes we last found, to
688     * determine on the next iteration which should be B services.
689     */
690    int mNumServiceProcs = 0;
691    int mNewNumServiceProcs = 0;
692
693    /**
694     * System monitoring: number of processes that died since the last
695     * N procs were started.
696     */
697    int[] mProcDeaths = new int[20];
698
699    /**
700     * This is set if we had to do a delayed dexopt of an app before launching
701     * it, to increasing the ANR timeouts in that case.
702     */
703    boolean mDidDexOpt;
704
705    String mDebugApp = null;
706    boolean mWaitForDebugger = false;
707    boolean mDebugTransient = false;
708    String mOrigDebugApp = null;
709    boolean mOrigWaitForDebugger = false;
710    boolean mAlwaysFinishActivities = false;
711    IActivityController mController = null;
712    String mProfileApp = null;
713    ProcessRecord mProfileProc = null;
714    String mProfileFile;
715    ParcelFileDescriptor mProfileFd;
716    int mProfileType = 0;
717    boolean mAutoStopProfiler = false;
718    String mOpenGlTraceApp = null;
719
720    static class ProcessChangeItem {
721        static final int CHANGE_ACTIVITIES = 1<<0;
722        static final int CHANGE_IMPORTANCE= 1<<1;
723        int changes;
724        int uid;
725        int pid;
726        int importance;
727        boolean foregroundActivities;
728    }
729
730    final RemoteCallbackList<IProcessObserver> mProcessObservers
731            = new RemoteCallbackList<IProcessObserver>();
732    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
733
734    final ArrayList<ProcessChangeItem> mPendingProcessChanges
735            = new ArrayList<ProcessChangeItem>();
736    final ArrayList<ProcessChangeItem> mAvailProcessChanges
737            = new ArrayList<ProcessChangeItem>();
738
739    /**
740     * Callback of last caller to {@link #requestPss}.
741     */
742    Runnable mRequestPssCallback;
743
744    /**
745     * Remaining processes for which we are waiting results from the last
746     * call to {@link #requestPss}.
747     */
748    final ArrayList<ProcessRecord> mRequestPssList
749            = new ArrayList<ProcessRecord>();
750
751    /**
752     * Runtime statistics collection thread.  This object's lock is used to
753     * protect all related state.
754     */
755    final Thread mProcessStatsThread;
756
757    /**
758     * Used to collect process stats when showing not responding dialog.
759     * Protected by mProcessStatsThread.
760     */
761    final ProcessStats mProcessStats = new ProcessStats(
762            MONITOR_THREAD_CPU_USAGE);
763    final AtomicLong mLastCpuTime = new AtomicLong(0);
764    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
765
766    long mLastWriteTime = 0;
767
768    /**
769     * Set to true after the system has finished booting.
770     */
771    boolean mBooted = false;
772
773    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
774    int mProcessLimitOverride = -1;
775
776    WindowManagerService mWindowManager;
777
778    static ActivityManagerService mSelf;
779    static ActivityThread mSystemThread;
780
781    private final class AppDeathRecipient implements IBinder.DeathRecipient {
782        final ProcessRecord mApp;
783        final int mPid;
784        final IApplicationThread mAppThread;
785
786        AppDeathRecipient(ProcessRecord app, int pid,
787                IApplicationThread thread) {
788            if (localLOGV) Slog.v(
789                TAG, "New death recipient " + this
790                + " for thread " + thread.asBinder());
791            mApp = app;
792            mPid = pid;
793            mAppThread = thread;
794        }
795
796        public void binderDied() {
797            if (localLOGV) Slog.v(
798                TAG, "Death received in " + this
799                + " for thread " + mAppThread.asBinder());
800            synchronized(ActivityManagerService.this) {
801                appDiedLocked(mApp, mPid, mAppThread);
802            }
803        }
804    }
805
806    static final int SHOW_ERROR_MSG = 1;
807    static final int SHOW_NOT_RESPONDING_MSG = 2;
808    static final int SHOW_FACTORY_ERROR_MSG = 3;
809    static final int UPDATE_CONFIGURATION_MSG = 4;
810    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
811    static final int WAIT_FOR_DEBUGGER_MSG = 6;
812    static final int SERVICE_TIMEOUT_MSG = 12;
813    static final int UPDATE_TIME_ZONE = 13;
814    static final int SHOW_UID_ERROR_MSG = 14;
815    static final int IM_FEELING_LUCKY_MSG = 15;
816    static final int PROC_START_TIMEOUT_MSG = 20;
817    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
818    static final int KILL_APPLICATION_MSG = 22;
819    static final int FINALIZE_PENDING_INTENT_MSG = 23;
820    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
821    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
822    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
823    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
824    static final int CLEAR_DNS_CACHE = 28;
825    static final int UPDATE_HTTP_PROXY = 29;
826    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
827    static final int DISPATCH_PROCESSES_CHANGED = 31;
828    static final int DISPATCH_PROCESS_DIED = 32;
829    static final int REPORT_MEM_USAGE = 33;
830
831    static final int FIRST_ACTIVITY_STACK_MSG = 100;
832    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
833    static final int FIRST_COMPAT_MODE_MSG = 300;
834
835    AlertDialog mUidAlert;
836    CompatModeDialog mCompatModeDialog;
837    long mLastMemUsageReportTime = 0;
838
839    final Handler mHandler = new Handler() {
840        //public Handler() {
841        //    if (localLOGV) Slog.v(TAG, "Handler started!");
842        //}
843
844        public void handleMessage(Message msg) {
845            switch (msg.what) {
846            case SHOW_ERROR_MSG: {
847                HashMap data = (HashMap) msg.obj;
848                synchronized (ActivityManagerService.this) {
849                    ProcessRecord proc = (ProcessRecord)data.get("app");
850                    if (proc != null && proc.crashDialog != null) {
851                        Slog.e(TAG, "App already has crash dialog: " + proc);
852                        return;
853                    }
854                    AppErrorResult res = (AppErrorResult) data.get("result");
855                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
856                        Dialog d = new AppErrorDialog(mContext, res, proc);
857                        d.show();
858                        proc.crashDialog = d;
859                    } else {
860                        // The device is asleep, so just pretend that the user
861                        // saw a crash dialog and hit "force quit".
862                        res.set(0);
863                    }
864                }
865
866                ensureBootCompleted();
867            } break;
868            case SHOW_NOT_RESPONDING_MSG: {
869                synchronized (ActivityManagerService.this) {
870                    HashMap data = (HashMap) msg.obj;
871                    ProcessRecord proc = (ProcessRecord)data.get("app");
872                    if (proc != null && proc.anrDialog != null) {
873                        Slog.e(TAG, "App already has anr dialog: " + proc);
874                        return;
875                    }
876
877                    Intent intent = new Intent("android.intent.action.ANR");
878                    if (!mProcessesReady) {
879                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
880                                | Intent.FLAG_RECEIVER_FOREGROUND);
881                    }
882                    broadcastIntentLocked(null, null, intent,
883                            null, null, 0, null, null, null,
884                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
885
886                    if (mShowDialogs) {
887                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
888                                mContext, proc, (ActivityRecord)data.get("activity"));
889                        d.show();
890                        proc.anrDialog = d;
891                    } else {
892                        // Just kill the app if there is no dialog to be shown.
893                        killAppAtUsersRequest(proc, null);
894                    }
895                }
896
897                ensureBootCompleted();
898            } break;
899            case SHOW_STRICT_MODE_VIOLATION_MSG: {
900                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
901                synchronized (ActivityManagerService.this) {
902                    ProcessRecord proc = (ProcessRecord) data.get("app");
903                    if (proc == null) {
904                        Slog.e(TAG, "App not found when showing strict mode dialog.");
905                        break;
906                    }
907                    if (proc.crashDialog != null) {
908                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
909                        return;
910                    }
911                    AppErrorResult res = (AppErrorResult) data.get("result");
912                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
913                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
914                        d.show();
915                        proc.crashDialog = d;
916                    } else {
917                        // The device is asleep, so just pretend that the user
918                        // saw a crash dialog and hit "force quit".
919                        res.set(0);
920                    }
921                }
922                ensureBootCompleted();
923            } break;
924            case SHOW_FACTORY_ERROR_MSG: {
925                Dialog d = new FactoryErrorDialog(
926                    mContext, msg.getData().getCharSequence("msg"));
927                d.show();
928                ensureBootCompleted();
929            } break;
930            case UPDATE_CONFIGURATION_MSG: {
931                final ContentResolver resolver = mContext.getContentResolver();
932                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
933            } break;
934            case GC_BACKGROUND_PROCESSES_MSG: {
935                synchronized (ActivityManagerService.this) {
936                    performAppGcsIfAppropriateLocked();
937                }
938            } break;
939            case WAIT_FOR_DEBUGGER_MSG: {
940                synchronized (ActivityManagerService.this) {
941                    ProcessRecord app = (ProcessRecord)msg.obj;
942                    if (msg.arg1 != 0) {
943                        if (!app.waitedForDebugger) {
944                            Dialog d = new AppWaitingForDebuggerDialog(
945                                    ActivityManagerService.this,
946                                    mContext, app);
947                            app.waitDialog = d;
948                            app.waitedForDebugger = true;
949                            d.show();
950                        }
951                    } else {
952                        if (app.waitDialog != null) {
953                            app.waitDialog.dismiss();
954                            app.waitDialog = null;
955                        }
956                    }
957                }
958            } break;
959            case SERVICE_TIMEOUT_MSG: {
960                if (mDidDexOpt) {
961                    mDidDexOpt = false;
962                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
963                    nmsg.obj = msg.obj;
964                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
965                    return;
966                }
967                mServices.serviceTimeout((ProcessRecord)msg.obj);
968            } break;
969            case UPDATE_TIME_ZONE: {
970                synchronized (ActivityManagerService.this) {
971                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
972                        ProcessRecord r = mLruProcesses.get(i);
973                        if (r.thread != null) {
974                            try {
975                                r.thread.updateTimeZone();
976                            } catch (RemoteException ex) {
977                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
978                            }
979                        }
980                    }
981                }
982            } break;
983            case CLEAR_DNS_CACHE: {
984                synchronized (ActivityManagerService.this) {
985                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
986                        ProcessRecord r = mLruProcesses.get(i);
987                        if (r.thread != null) {
988                            try {
989                                r.thread.clearDnsCache();
990                            } catch (RemoteException ex) {
991                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
992                            }
993                        }
994                    }
995                }
996            } break;
997            case UPDATE_HTTP_PROXY: {
998                ProxyProperties proxy = (ProxyProperties)msg.obj;
999                String host = "";
1000                String port = "";
1001                String exclList = "";
1002                if (proxy != null) {
1003                    host = proxy.getHost();
1004                    port = Integer.toString(proxy.getPort());
1005                    exclList = proxy.getExclusionList();
1006                }
1007                synchronized (ActivityManagerService.this) {
1008                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1009                        ProcessRecord r = mLruProcesses.get(i);
1010                        if (r.thread != null) {
1011                            try {
1012                                r.thread.setHttpProxy(host, port, exclList);
1013                            } catch (RemoteException ex) {
1014                                Slog.w(TAG, "Failed to update http proxy for: " +
1015                                        r.info.processName);
1016                            }
1017                        }
1018                    }
1019                }
1020            } break;
1021            case SHOW_UID_ERROR_MSG: {
1022                String title = "System UIDs Inconsistent";
1023                String text = "UIDs on the system are inconsistent, you need to wipe your"
1024                        + " data partition or your device will be unstable.";
1025                Log.e(TAG, title + ": " + text);
1026                if (mShowDialogs) {
1027                    // XXX This is a temporary dialog, no need to localize.
1028                    AlertDialog d = new BaseErrorDialog(mContext);
1029                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1030                    d.setCancelable(false);
1031                    d.setTitle(title);
1032                    d.setMessage(text);
1033                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1034                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1035                    mUidAlert = d;
1036                    d.show();
1037                }
1038            } break;
1039            case IM_FEELING_LUCKY_MSG: {
1040                if (mUidAlert != null) {
1041                    mUidAlert.dismiss();
1042                    mUidAlert = null;
1043                }
1044            } break;
1045            case PROC_START_TIMEOUT_MSG: {
1046                if (mDidDexOpt) {
1047                    mDidDexOpt = false;
1048                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1049                    nmsg.obj = msg.obj;
1050                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1051                    return;
1052                }
1053                ProcessRecord app = (ProcessRecord)msg.obj;
1054                synchronized (ActivityManagerService.this) {
1055                    processStartTimedOutLocked(app);
1056                }
1057            } break;
1058            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1059                synchronized (ActivityManagerService.this) {
1060                    doPendingActivityLaunchesLocked(true);
1061                }
1062            } break;
1063            case KILL_APPLICATION_MSG: {
1064                synchronized (ActivityManagerService.this) {
1065                    int uid = msg.arg1;
1066                    boolean restart = (msg.arg2 == 1);
1067                    String pkg = (String) msg.obj;
1068                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1069                            UserId.getUserId(uid));
1070                }
1071            } break;
1072            case FINALIZE_PENDING_INTENT_MSG: {
1073                ((PendingIntentRecord)msg.obj).completeFinalize();
1074            } break;
1075            case POST_HEAVY_NOTIFICATION_MSG: {
1076                INotificationManager inm = NotificationManager.getService();
1077                if (inm == null) {
1078                    return;
1079                }
1080
1081                ActivityRecord root = (ActivityRecord)msg.obj;
1082                ProcessRecord process = root.app;
1083                if (process == null) {
1084                    return;
1085                }
1086
1087                try {
1088                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1089                    String text = mContext.getString(R.string.heavy_weight_notification,
1090                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1091                    Notification notification = new Notification();
1092                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1093                    notification.when = 0;
1094                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1095                    notification.tickerText = text;
1096                    notification.defaults = 0; // please be quiet
1097                    notification.sound = null;
1098                    notification.vibrate = null;
1099                    notification.setLatestEventInfo(context, text,
1100                            mContext.getText(R.string.heavy_weight_notification_detail),
1101                            PendingIntent.getActivity(mContext, 0, root.intent,
1102                                    PendingIntent.FLAG_CANCEL_CURRENT));
1103
1104                    try {
1105                        int[] outId = new int[1];
1106                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1107                                notification, outId);
1108                    } catch (RuntimeException e) {
1109                        Slog.w(ActivityManagerService.TAG,
1110                                "Error showing notification for heavy-weight app", e);
1111                    } catch (RemoteException e) {
1112                    }
1113                } catch (NameNotFoundException e) {
1114                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1115                }
1116            } break;
1117            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1118                INotificationManager inm = NotificationManager.getService();
1119                if (inm == null) {
1120                    return;
1121                }
1122                try {
1123                    inm.cancelNotification("android",
1124                            R.string.heavy_weight_notification);
1125                } catch (RuntimeException e) {
1126                    Slog.w(ActivityManagerService.TAG,
1127                            "Error canceling notification for service", e);
1128                } catch (RemoteException e) {
1129                }
1130            } break;
1131            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1132                synchronized (ActivityManagerService.this) {
1133                    checkExcessivePowerUsageLocked(true);
1134                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1135                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1136                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1137                }
1138            } break;
1139            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1140                synchronized (ActivityManagerService.this) {
1141                    ActivityRecord ar = (ActivityRecord)msg.obj;
1142                    if (mCompatModeDialog != null) {
1143                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1144                                ar.info.applicationInfo.packageName)) {
1145                            return;
1146                        }
1147                        mCompatModeDialog.dismiss();
1148                        mCompatModeDialog = null;
1149                    }
1150                    if (ar != null && false) {
1151                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1152                                ar.packageName)) {
1153                            int mode = mCompatModePackages.computeCompatModeLocked(
1154                                    ar.info.applicationInfo);
1155                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1156                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1157                                mCompatModeDialog = new CompatModeDialog(
1158                                        ActivityManagerService.this, mContext,
1159                                        ar.info.applicationInfo);
1160                                mCompatModeDialog.show();
1161                            }
1162                        }
1163                    }
1164                }
1165                break;
1166            }
1167            case DISPATCH_PROCESSES_CHANGED: {
1168                dispatchProcessesChanged();
1169                break;
1170            }
1171            case DISPATCH_PROCESS_DIED: {
1172                final int pid = msg.arg1;
1173                final int uid = msg.arg2;
1174                dispatchProcessDied(pid, uid);
1175                break;
1176            }
1177            case REPORT_MEM_USAGE: {
1178                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1179                if (!isDebuggable) {
1180                    return;
1181                }
1182                synchronized (ActivityManagerService.this) {
1183                    long now = SystemClock.uptimeMillis();
1184                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1185                        // Don't report more than every 5 minutes to somewhat
1186                        // avoid spamming.
1187                        return;
1188                    }
1189                    mLastMemUsageReportTime = now;
1190                }
1191                Thread thread = new Thread() {
1192                    @Override public void run() {
1193                        StringBuilder dropBuilder = new StringBuilder(1024);
1194                        StringBuilder logBuilder = new StringBuilder(1024);
1195                        StringWriter oomSw = new StringWriter();
1196                        PrintWriter oomPw = new PrintWriter(oomSw);
1197                        StringWriter catSw = new StringWriter();
1198                        PrintWriter catPw = new PrintWriter(catSw);
1199                        String[] emptyArgs = new String[] { };
1200                        StringBuilder tag = new StringBuilder(128);
1201                        StringBuilder stack = new StringBuilder(128);
1202                        tag.append("Low on memory -- ");
1203                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1204                                tag, stack);
1205                        dropBuilder.append(stack);
1206                        dropBuilder.append('\n');
1207                        dropBuilder.append('\n');
1208                        String oomString = oomSw.toString();
1209                        dropBuilder.append(oomString);
1210                        dropBuilder.append('\n');
1211                        logBuilder.append(oomString);
1212                        try {
1213                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1214                                    "procrank", });
1215                            final InputStreamReader converter = new InputStreamReader(
1216                                    proc.getInputStream());
1217                            BufferedReader in = new BufferedReader(converter);
1218                            String line;
1219                            while (true) {
1220                                line = in.readLine();
1221                                if (line == null) {
1222                                    break;
1223                                }
1224                                if (line.length() > 0) {
1225                                    logBuilder.append(line);
1226                                    logBuilder.append('\n');
1227                                }
1228                                dropBuilder.append(line);
1229                                dropBuilder.append('\n');
1230                            }
1231                            converter.close();
1232                        } catch (IOException e) {
1233                        }
1234                        synchronized (ActivityManagerService.this) {
1235                            catPw.println();
1236                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1237                            catPw.println();
1238                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1239                                    false, false, null);
1240                            catPw.println();
1241                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1242                        }
1243                        dropBuilder.append(catSw.toString());
1244                        addErrorToDropBox("lowmem", null, "system_server", null,
1245                                null, tag.toString(), dropBuilder.toString(), null, null);
1246                        Slog.i(TAG, logBuilder.toString());
1247                        synchronized (ActivityManagerService.this) {
1248                            long now = SystemClock.uptimeMillis();
1249                            if (mLastMemUsageReportTime < now) {
1250                                mLastMemUsageReportTime = now;
1251                            }
1252                        }
1253                    }
1254                };
1255                thread.start();
1256                break;
1257            }
1258            }
1259        }
1260    };
1261
1262    public static void setSystemProcess() {
1263        try {
1264            ActivityManagerService m = mSelf;
1265
1266            ServiceManager.addService("activity", m, true);
1267            ServiceManager.addService("meminfo", new MemBinder(m));
1268            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1269            ServiceManager.addService("dbinfo", new DbBinder(m));
1270            if (MONITOR_CPU_USAGE) {
1271                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1272            }
1273            ServiceManager.addService("permission", new PermissionController(m));
1274
1275            ApplicationInfo info =
1276                mSelf.mContext.getPackageManager().getApplicationInfo(
1277                            "android", STOCK_PM_FLAGS);
1278            mSystemThread.installSystemApplicationInfo(info);
1279
1280            synchronized (mSelf) {
1281                ProcessRecord app = mSelf.newProcessRecordLocked(
1282                        mSystemThread.getApplicationThread(), info,
1283                        info.processName, false);
1284                app.persistent = true;
1285                app.pid = MY_PID;
1286                app.maxAdj = ProcessList.SYSTEM_ADJ;
1287                mSelf.mProcessNames.put(app.processName, app.uid, app);
1288                synchronized (mSelf.mPidsSelfLocked) {
1289                    mSelf.mPidsSelfLocked.put(app.pid, app);
1290                }
1291                mSelf.updateLruProcessLocked(app, true, true);
1292            }
1293        } catch (PackageManager.NameNotFoundException e) {
1294            throw new RuntimeException(
1295                    "Unable to find android system package", e);
1296        }
1297    }
1298
1299    public void setWindowManager(WindowManagerService wm) {
1300        mWindowManager = wm;
1301    }
1302
1303    public static final Context main(int factoryTest) {
1304        AThread thr = new AThread();
1305        thr.start();
1306
1307        synchronized (thr) {
1308            while (thr.mService == null) {
1309                try {
1310                    thr.wait();
1311                } catch (InterruptedException e) {
1312                }
1313            }
1314        }
1315
1316        ActivityManagerService m = thr.mService;
1317        mSelf = m;
1318        ActivityThread at = ActivityThread.systemMain();
1319        mSystemThread = at;
1320        Context context = at.getSystemContext();
1321        context.setTheme(android.R.style.Theme_Holo);
1322        m.mContext = context;
1323        m.mFactoryTest = factoryTest;
1324        m.mMainStack = new ActivityStack(m, context, true);
1325
1326        m.mBatteryStatsService.publish(context);
1327        m.mUsageStatsService.publish(context);
1328
1329        synchronized (thr) {
1330            thr.mReady = true;
1331            thr.notifyAll();
1332        }
1333
1334        m.startRunning(null, null, null, null);
1335
1336        return context;
1337    }
1338
1339    public static ActivityManagerService self() {
1340        return mSelf;
1341    }
1342
1343    static class AThread extends Thread {
1344        ActivityManagerService mService;
1345        boolean mReady = false;
1346
1347        public AThread() {
1348            super("ActivityManager");
1349        }
1350
1351        public void run() {
1352            Looper.prepare();
1353
1354            android.os.Process.setThreadPriority(
1355                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1356            android.os.Process.setCanSelfBackground(false);
1357
1358            ActivityManagerService m = new ActivityManagerService();
1359
1360            synchronized (this) {
1361                mService = m;
1362                notifyAll();
1363            }
1364
1365            synchronized (this) {
1366                while (!mReady) {
1367                    try {
1368                        wait();
1369                    } catch (InterruptedException e) {
1370                    }
1371                }
1372            }
1373
1374            // For debug builds, log event loop stalls to dropbox for analysis.
1375            if (StrictMode.conditionallyEnableDebugLogging()) {
1376                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1377            }
1378
1379            Looper.loop();
1380        }
1381    }
1382
1383    static class MemBinder extends Binder {
1384        ActivityManagerService mActivityManagerService;
1385        MemBinder(ActivityManagerService activityManagerService) {
1386            mActivityManagerService = activityManagerService;
1387        }
1388
1389        @Override
1390        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1391            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1392                    != PackageManager.PERMISSION_GRANTED) {
1393                pw.println("Permission Denial: can't dump meminfo from from pid="
1394                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1395                        + " without permission " + android.Manifest.permission.DUMP);
1396                return;
1397            }
1398
1399            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1400                    false, null, null, null);
1401        }
1402    }
1403
1404    static class GraphicsBinder extends Binder {
1405        ActivityManagerService mActivityManagerService;
1406        GraphicsBinder(ActivityManagerService activityManagerService) {
1407            mActivityManagerService = activityManagerService;
1408        }
1409
1410        @Override
1411        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1412            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1413                    != PackageManager.PERMISSION_GRANTED) {
1414                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1415                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1416                        + " without permission " + android.Manifest.permission.DUMP);
1417                return;
1418            }
1419
1420            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1421        }
1422    }
1423
1424    static class DbBinder extends Binder {
1425        ActivityManagerService mActivityManagerService;
1426        DbBinder(ActivityManagerService activityManagerService) {
1427            mActivityManagerService = activityManagerService;
1428        }
1429
1430        @Override
1431        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1432            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1433                    != PackageManager.PERMISSION_GRANTED) {
1434                pw.println("Permission Denial: can't dump dbinfo from from pid="
1435                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1436                        + " without permission " + android.Manifest.permission.DUMP);
1437                return;
1438            }
1439
1440            mActivityManagerService.dumpDbInfo(fd, pw, args);
1441        }
1442    }
1443
1444    static class CpuBinder extends Binder {
1445        ActivityManagerService mActivityManagerService;
1446        CpuBinder(ActivityManagerService activityManagerService) {
1447            mActivityManagerService = activityManagerService;
1448        }
1449
1450        @Override
1451        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1452            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1453                    != PackageManager.PERMISSION_GRANTED) {
1454                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1455                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1456                        + " without permission " + android.Manifest.permission.DUMP);
1457                return;
1458            }
1459
1460            synchronized (mActivityManagerService.mProcessStatsThread) {
1461                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1462                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1463                        SystemClock.uptimeMillis()));
1464            }
1465        }
1466    }
1467
1468    private ActivityManagerService() {
1469        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1470
1471        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1472        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1473        mBroadcastQueues[0] = mFgBroadcastQueue;
1474        mBroadcastQueues[1] = mBgBroadcastQueue;
1475
1476        mServices = new ActiveServices(this);
1477
1478        File dataDir = Environment.getDataDirectory();
1479        File systemDir = new File(dataDir, "system");
1480        systemDir.mkdirs();
1481        mBatteryStatsService = new BatteryStatsService(new File(
1482                systemDir, "batterystats.bin").toString());
1483        mBatteryStatsService.getActiveStatistics().readLocked();
1484        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1485        mOnBattery = DEBUG_POWER ? true
1486                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1487        mBatteryStatsService.getActiveStatistics().setCallback(this);
1488
1489        mUsageStatsService = new UsageStatsService(new File(
1490                systemDir, "usagestats").toString());
1491        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1492
1493        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1494            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1495
1496        mConfiguration.setToDefaults();
1497        mConfiguration.locale = Locale.getDefault();
1498        mConfigurationSeq = mConfiguration.seq = 1;
1499        mProcessStats.init();
1500
1501        mCompatModePackages = new CompatModePackages(this, systemDir);
1502
1503        // Add ourself to the Watchdog monitors.
1504        Watchdog.getInstance().addMonitor(this);
1505
1506        mProcessStatsThread = new Thread("ProcessStats") {
1507            public void run() {
1508                while (true) {
1509                    try {
1510                        try {
1511                            synchronized(this) {
1512                                final long now = SystemClock.uptimeMillis();
1513                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1514                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1515                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1516                                //        + ", write delay=" + nextWriteDelay);
1517                                if (nextWriteDelay < nextCpuDelay) {
1518                                    nextCpuDelay = nextWriteDelay;
1519                                }
1520                                if (nextCpuDelay > 0) {
1521                                    mProcessStatsMutexFree.set(true);
1522                                    this.wait(nextCpuDelay);
1523                                }
1524                            }
1525                        } catch (InterruptedException e) {
1526                        }
1527                        updateCpuStatsNow();
1528                    } catch (Exception e) {
1529                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1530                    }
1531                }
1532            }
1533        };
1534        mProcessStatsThread.start();
1535    }
1536
1537    @Override
1538    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1539            throws RemoteException {
1540        if (code == SYSPROPS_TRANSACTION) {
1541            // We need to tell all apps about the system property change.
1542            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1543            synchronized(this) {
1544                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1545                    final int NA = apps.size();
1546                    for (int ia=0; ia<NA; ia++) {
1547                        ProcessRecord app = apps.valueAt(ia);
1548                        if (app.thread != null) {
1549                            procs.add(app.thread.asBinder());
1550                        }
1551                    }
1552                }
1553            }
1554
1555            int N = procs.size();
1556            for (int i=0; i<N; i++) {
1557                Parcel data2 = Parcel.obtain();
1558                try {
1559                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1560                } catch (RemoteException e) {
1561                }
1562                data2.recycle();
1563            }
1564        }
1565        try {
1566            return super.onTransact(code, data, reply, flags);
1567        } catch (RuntimeException e) {
1568            // The activity manager only throws security exceptions, so let's
1569            // log all others.
1570            if (!(e instanceof SecurityException)) {
1571                Slog.e(TAG, "Activity Manager Crash", e);
1572            }
1573            throw e;
1574        }
1575    }
1576
1577    void updateCpuStats() {
1578        final long now = SystemClock.uptimeMillis();
1579        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1580            return;
1581        }
1582        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1583            synchronized (mProcessStatsThread) {
1584                mProcessStatsThread.notify();
1585            }
1586        }
1587    }
1588
1589    void updateCpuStatsNow() {
1590        synchronized (mProcessStatsThread) {
1591            mProcessStatsMutexFree.set(false);
1592            final long now = SystemClock.uptimeMillis();
1593            boolean haveNewCpuStats = false;
1594
1595            if (MONITOR_CPU_USAGE &&
1596                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1597                mLastCpuTime.set(now);
1598                haveNewCpuStats = true;
1599                mProcessStats.update();
1600                //Slog.i(TAG, mProcessStats.printCurrentState());
1601                //Slog.i(TAG, "Total CPU usage: "
1602                //        + mProcessStats.getTotalCpuPercent() + "%");
1603
1604                // Slog the cpu usage if the property is set.
1605                if ("true".equals(SystemProperties.get("events.cpu"))) {
1606                    int user = mProcessStats.getLastUserTime();
1607                    int system = mProcessStats.getLastSystemTime();
1608                    int iowait = mProcessStats.getLastIoWaitTime();
1609                    int irq = mProcessStats.getLastIrqTime();
1610                    int softIrq = mProcessStats.getLastSoftIrqTime();
1611                    int idle = mProcessStats.getLastIdleTime();
1612
1613                    int total = user + system + iowait + irq + softIrq + idle;
1614                    if (total == 0) total = 1;
1615
1616                    EventLog.writeEvent(EventLogTags.CPU,
1617                            ((user+system+iowait+irq+softIrq) * 100) / total,
1618                            (user * 100) / total,
1619                            (system * 100) / total,
1620                            (iowait * 100) / total,
1621                            (irq * 100) / total,
1622                            (softIrq * 100) / total);
1623                }
1624            }
1625
1626            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1627            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1628            synchronized(bstats) {
1629                synchronized(mPidsSelfLocked) {
1630                    if (haveNewCpuStats) {
1631                        if (mOnBattery) {
1632                            int perc = bstats.startAddingCpuLocked();
1633                            int totalUTime = 0;
1634                            int totalSTime = 0;
1635                            final int N = mProcessStats.countStats();
1636                            for (int i=0; i<N; i++) {
1637                                ProcessStats.Stats st = mProcessStats.getStats(i);
1638                                if (!st.working) {
1639                                    continue;
1640                                }
1641                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1642                                int otherUTime = (st.rel_utime*perc)/100;
1643                                int otherSTime = (st.rel_stime*perc)/100;
1644                                totalUTime += otherUTime;
1645                                totalSTime += otherSTime;
1646                                if (pr != null) {
1647                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1648                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1649                                            st.rel_stime-otherSTime);
1650                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1651                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1652                                } else {
1653                                    BatteryStatsImpl.Uid.Proc ps =
1654                                            bstats.getProcessStatsLocked(st.name, st.pid);
1655                                    if (ps != null) {
1656                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1657                                                st.rel_stime-otherSTime);
1658                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1659                                    }
1660                                }
1661                            }
1662                            bstats.finishAddingCpuLocked(perc, totalUTime,
1663                                    totalSTime, cpuSpeedTimes);
1664                        }
1665                    }
1666                }
1667
1668                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1669                    mLastWriteTime = now;
1670                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1671                }
1672            }
1673        }
1674    }
1675
1676    @Override
1677    public void batteryNeedsCpuUpdate() {
1678        updateCpuStatsNow();
1679    }
1680
1681    @Override
1682    public void batteryPowerChanged(boolean onBattery) {
1683        // When plugging in, update the CPU stats first before changing
1684        // the plug state.
1685        updateCpuStatsNow();
1686        synchronized (this) {
1687            synchronized(mPidsSelfLocked) {
1688                mOnBattery = DEBUG_POWER ? true : onBattery;
1689            }
1690        }
1691    }
1692
1693    /**
1694     * Initialize the application bind args. These are passed to each
1695     * process when the bindApplication() IPC is sent to the process. They're
1696     * lazily setup to make sure the services are running when they're asked for.
1697     */
1698    private HashMap<String, IBinder> getCommonServicesLocked() {
1699        if (mAppBindArgs == null) {
1700            mAppBindArgs = new HashMap<String, IBinder>();
1701
1702            // Setup the application init args
1703            mAppBindArgs.put("package", ServiceManager.getService("package"));
1704            mAppBindArgs.put("window", ServiceManager.getService("window"));
1705            mAppBindArgs.put(Context.ALARM_SERVICE,
1706                    ServiceManager.getService(Context.ALARM_SERVICE));
1707        }
1708        return mAppBindArgs;
1709    }
1710
1711    final void setFocusedActivityLocked(ActivityRecord r) {
1712        if (mFocusedActivity != r) {
1713            mFocusedActivity = r;
1714            if (r != null) {
1715                mWindowManager.setFocusedApp(r.appToken, true);
1716            }
1717        }
1718    }
1719
1720    private final void updateLruProcessInternalLocked(ProcessRecord app,
1721            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1722        // put it on the LRU to keep track of when it should be exited.
1723        int lrui = mLruProcesses.indexOf(app);
1724        if (lrui >= 0) mLruProcesses.remove(lrui);
1725
1726        int i = mLruProcesses.size()-1;
1727        int skipTop = 0;
1728
1729        app.lruSeq = mLruSeq;
1730
1731        // compute the new weight for this process.
1732        if (updateActivityTime) {
1733            app.lastActivityTime = SystemClock.uptimeMillis();
1734        }
1735        if (app.activities.size() > 0) {
1736            // If this process has activities, we more strongly want to keep
1737            // it around.
1738            app.lruWeight = app.lastActivityTime;
1739        } else if (app.pubProviders.size() > 0) {
1740            // If this process contains content providers, we want to keep
1741            // it a little more strongly.
1742            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1743            // Also don't let it kick out the first few "real" hidden processes.
1744            skipTop = ProcessList.MIN_HIDDEN_APPS;
1745        } else {
1746            // If this process doesn't have activities, we less strongly
1747            // want to keep it around, and generally want to avoid getting
1748            // in front of any very recently used activities.
1749            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1750            // Also don't let it kick out the first few "real" hidden processes.
1751            skipTop = ProcessList.MIN_HIDDEN_APPS;
1752        }
1753
1754        while (i >= 0) {
1755            ProcessRecord p = mLruProcesses.get(i);
1756            // If this app shouldn't be in front of the first N background
1757            // apps, then skip over that many that are currently hidden.
1758            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1759                skipTop--;
1760            }
1761            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1762                mLruProcesses.add(i+1, app);
1763                break;
1764            }
1765            i--;
1766        }
1767        if (i < 0) {
1768            mLruProcesses.add(0, app);
1769        }
1770
1771        // If the app is currently using a content provider or service,
1772        // bump those processes as well.
1773        if (app.connections.size() > 0) {
1774            for (ConnectionRecord cr : app.connections) {
1775                if (cr.binding != null && cr.binding.service != null
1776                        && cr.binding.service.app != null
1777                        && cr.binding.service.app.lruSeq != mLruSeq) {
1778                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1779                            updateActivityTime, i+1);
1780                }
1781            }
1782        }
1783        for (int j=app.conProviders.size()-1; j>=0; j--) {
1784            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1785            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1786                updateLruProcessInternalLocked(cpr.proc, false,
1787                        updateActivityTime, i+1);
1788            }
1789        }
1790
1791        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1792        if (oomAdj) {
1793            updateOomAdjLocked();
1794        }
1795    }
1796
1797    final void updateLruProcessLocked(ProcessRecord app,
1798            boolean oomAdj, boolean updateActivityTime) {
1799        mLruSeq++;
1800        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1801    }
1802
1803    final ProcessRecord getProcessRecordLocked(
1804            String processName, int uid) {
1805        if (uid == Process.SYSTEM_UID) {
1806            // The system gets to run in any process.  If there are multiple
1807            // processes with the same uid, just pick the first (this
1808            // should never happen).
1809            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1810                    processName);
1811            if (procs == null) return null;
1812            final int N = procs.size();
1813            for (int i = 0; i < N; i++) {
1814                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1815            }
1816        }
1817        ProcessRecord proc = mProcessNames.get(processName, uid);
1818        return proc;
1819    }
1820
1821    void ensurePackageDexOpt(String packageName) {
1822        IPackageManager pm = AppGlobals.getPackageManager();
1823        try {
1824            if (pm.performDexOpt(packageName)) {
1825                mDidDexOpt = true;
1826            }
1827        } catch (RemoteException e) {
1828        }
1829    }
1830
1831    boolean isNextTransitionForward() {
1832        int transit = mWindowManager.getPendingAppTransition();
1833        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1834                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1835                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1836    }
1837
1838    final ProcessRecord startProcessLocked(String processName,
1839            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1840            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1841            boolean isolated) {
1842        ProcessRecord app;
1843        if (!isolated) {
1844            app = getProcessRecordLocked(processName, info.uid);
1845        } else {
1846            // If this is an isolated process, it can't re-use an existing process.
1847            app = null;
1848        }
1849        // We don't have to do anything more if:
1850        // (1) There is an existing application record; and
1851        // (2) The caller doesn't think it is dead, OR there is no thread
1852        //     object attached to it so we know it couldn't have crashed; and
1853        // (3) There is a pid assigned to it, so it is either starting or
1854        //     already running.
1855        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1856                + " app=" + app + " knownToBeDead=" + knownToBeDead
1857                + " thread=" + (app != null ? app.thread : null)
1858                + " pid=" + (app != null ? app.pid : -1));
1859        if (app != null && app.pid > 0) {
1860            if (!knownToBeDead || app.thread == null) {
1861                // We already have the app running, or are waiting for it to
1862                // come up (we have a pid but not yet its thread), so keep it.
1863                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1864                // If this is a new package in the process, add the package to the list
1865                app.addPackage(info.packageName);
1866                return app;
1867            } else {
1868                // An application record is attached to a previous process,
1869                // clean it up now.
1870                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1871                handleAppDiedLocked(app, true, true);
1872            }
1873        }
1874
1875        String hostingNameStr = hostingName != null
1876                ? hostingName.flattenToShortString() : null;
1877
1878        if (!isolated) {
1879            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1880                // If we are in the background, then check to see if this process
1881                // is bad.  If so, we will just silently fail.
1882                if (mBadProcesses.get(info.processName, info.uid) != null) {
1883                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1884                            + "/" + info.processName);
1885                    return null;
1886                }
1887            } else {
1888                // When the user is explicitly starting a process, then clear its
1889                // crash count so that we won't make it bad until they see at
1890                // least one crash dialog again, and make the process good again
1891                // if it had been bad.
1892                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1893                        + "/" + info.processName);
1894                mProcessCrashTimes.remove(info.processName, info.uid);
1895                if (mBadProcesses.get(info.processName, info.uid) != null) {
1896                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1897                            info.processName);
1898                    mBadProcesses.remove(info.processName, info.uid);
1899                    if (app != null) {
1900                        app.bad = false;
1901                    }
1902                }
1903            }
1904        }
1905
1906        if (app == null) {
1907            app = newProcessRecordLocked(null, info, processName, isolated);
1908            if (app == null) {
1909                Slog.w(TAG, "Failed making new process record for "
1910                        + processName + "/" + info.uid + " isolated=" + isolated);
1911                return null;
1912            }
1913            mProcessNames.put(processName, app.uid, app);
1914            if (isolated) {
1915                mIsolatedProcesses.put(app.uid, app);
1916            }
1917        } else {
1918            // If this is a new package in the process, add the package to the list
1919            app.addPackage(info.packageName);
1920        }
1921
1922        // If the system is not ready yet, then hold off on starting this
1923        // process until it is.
1924        if (!mProcessesReady
1925                && !isAllowedWhileBooting(info)
1926                && !allowWhileBooting) {
1927            if (!mProcessesOnHold.contains(app)) {
1928                mProcessesOnHold.add(app);
1929            }
1930            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1931            return app;
1932        }
1933
1934        startProcessLocked(app, hostingType, hostingNameStr);
1935        return (app.pid != 0) ? app : null;
1936    }
1937
1938    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1939        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1940    }
1941
1942    private final void startProcessLocked(ProcessRecord app,
1943            String hostingType, String hostingNameStr) {
1944        if (app.pid > 0 && app.pid != MY_PID) {
1945            synchronized (mPidsSelfLocked) {
1946                mPidsSelfLocked.remove(app.pid);
1947                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1948            }
1949            app.pid = 0;
1950        }
1951
1952        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1953                "startProcessLocked removing on hold: " + app);
1954        mProcessesOnHold.remove(app);
1955
1956        updateCpuStats();
1957
1958        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1959        mProcDeaths[0] = 0;
1960
1961        try {
1962            int uid = app.uid;
1963
1964            int[] gids = null;
1965            if (!app.isolated) {
1966                try {
1967                    gids = mContext.getPackageManager().getPackageGids(
1968                            app.info.packageName);
1969                } catch (PackageManager.NameNotFoundException e) {
1970                    Slog.w(TAG, "Unable to retrieve gids", e);
1971                }
1972            }
1973            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1974                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1975                        && mTopComponent != null
1976                        && app.processName.equals(mTopComponent.getPackageName())) {
1977                    uid = 0;
1978                }
1979                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1980                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1981                    uid = 0;
1982                }
1983            }
1984            int debugFlags = 0;
1985            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1986                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1987                // Also turn on CheckJNI for debuggable apps. It's quite
1988                // awkward to turn on otherwise.
1989                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1990            }
1991            // Run the app in safe mode if its manifest requests so or the
1992            // system is booted in safe mode.
1993            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1994                Zygote.systemInSafeMode == true) {
1995                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1996            }
1997            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1998                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1999            }
2000            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2001                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2002            }
2003            if ("1".equals(SystemProperties.get("debug.assert"))) {
2004                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2005            }
2006
2007            // Start the process.  It will either succeed and return a result containing
2008            // the PID of the new process, or else throw a RuntimeException.
2009            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2010                    app.processName, uid, uid, gids, debugFlags,
2011                    app.info.targetSdkVersion, null, null);
2012
2013            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2014            synchronized (bs) {
2015                if (bs.isOnBattery()) {
2016                    app.batteryStats.incStartsLocked();
2017                }
2018            }
2019
2020            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2021                    app.processName, hostingType,
2022                    hostingNameStr != null ? hostingNameStr : "");
2023
2024            if (app.persistent) {
2025                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2026            }
2027
2028            StringBuilder buf = mStringBuilder;
2029            buf.setLength(0);
2030            buf.append("Start proc ");
2031            buf.append(app.processName);
2032            buf.append(" for ");
2033            buf.append(hostingType);
2034            if (hostingNameStr != null) {
2035                buf.append(" ");
2036                buf.append(hostingNameStr);
2037            }
2038            buf.append(": pid=");
2039            buf.append(startResult.pid);
2040            buf.append(" uid=");
2041            buf.append(uid);
2042            buf.append(" gids={");
2043            if (gids != null) {
2044                for (int gi=0; gi<gids.length; gi++) {
2045                    if (gi != 0) buf.append(", ");
2046                    buf.append(gids[gi]);
2047
2048                }
2049            }
2050            buf.append("}");
2051            Slog.i(TAG, buf.toString());
2052            app.pid = startResult.pid;
2053            app.usingWrapper = startResult.usingWrapper;
2054            app.removed = false;
2055            synchronized (mPidsSelfLocked) {
2056                this.mPidsSelfLocked.put(startResult.pid, app);
2057                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2058                msg.obj = app;
2059                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2060                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2061            }
2062        } catch (RuntimeException e) {
2063            // XXX do better error recovery.
2064            app.pid = 0;
2065            Slog.e(TAG, "Failure starting process " + app.processName, e);
2066        }
2067    }
2068
2069    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2070        if (resumed) {
2071            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2072        } else {
2073            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2074        }
2075    }
2076
2077    boolean startHomeActivityLocked(int userId) {
2078        if (mHeadless) {
2079            // Added because none of the other calls to ensureBootCompleted seem to fire
2080            // when running headless.
2081            ensureBootCompleted();
2082            return false;
2083        }
2084
2085        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2086                && mTopAction == null) {
2087            // We are running in factory test mode, but unable to find
2088            // the factory test app, so just sit around displaying the
2089            // error message and don't try to start anything.
2090            return false;
2091        }
2092        Intent intent = new Intent(
2093            mTopAction,
2094            mTopData != null ? Uri.parse(mTopData) : null);
2095        intent.setComponent(mTopComponent);
2096        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2097            intent.addCategory(Intent.CATEGORY_HOME);
2098        }
2099        ActivityInfo aInfo =
2100            intent.resolveActivityInfo(mContext.getPackageManager(),
2101                    STOCK_PM_FLAGS);
2102        if (aInfo != null) {
2103            intent.setComponent(new ComponentName(
2104                    aInfo.applicationInfo.packageName, aInfo.name));
2105            // Don't do this if the home app is currently being
2106            // instrumented.
2107            aInfo = new ActivityInfo(aInfo);
2108            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2109            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2110                    aInfo.applicationInfo.uid);
2111            if (app == null || app.instrumentationClass == null) {
2112                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2113                mMainStack.startActivityLocked(null, intent, null, aInfo,
2114                        null, null, 0, 0, 0, 0, null, false, null);
2115            }
2116        }
2117
2118        return true;
2119    }
2120
2121    /**
2122     * Starts the "new version setup screen" if appropriate.
2123     */
2124    void startSetupActivityLocked() {
2125        // Only do this once per boot.
2126        if (mCheckedForSetup) {
2127            return;
2128        }
2129
2130        // We will show this screen if the current one is a different
2131        // version than the last one shown, and we are not running in
2132        // low-level factory test mode.
2133        final ContentResolver resolver = mContext.getContentResolver();
2134        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2135                Settings.Secure.getInt(resolver,
2136                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2137            mCheckedForSetup = true;
2138
2139            // See if we should be showing the platform update setup UI.
2140            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2141            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2142                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2143
2144            // We don't allow third party apps to replace this.
2145            ResolveInfo ri = null;
2146            for (int i=0; ris != null && i<ris.size(); i++) {
2147                if ((ris.get(i).activityInfo.applicationInfo.flags
2148                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2149                    ri = ris.get(i);
2150                    break;
2151                }
2152            }
2153
2154            if (ri != null) {
2155                String vers = ri.activityInfo.metaData != null
2156                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2157                        : null;
2158                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2159                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2160                            Intent.METADATA_SETUP_VERSION);
2161                }
2162                String lastVers = Settings.Secure.getString(
2163                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2164                if (vers != null && !vers.equals(lastVers)) {
2165                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2166                    intent.setComponent(new ComponentName(
2167                            ri.activityInfo.packageName, ri.activityInfo.name));
2168                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2169                            null, null, 0, 0, 0, 0, null, false, null);
2170                }
2171            }
2172        }
2173    }
2174
2175    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2176        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2177    }
2178
2179    void enforceNotIsolatedCaller(String caller) {
2180        if (UserId.isIsolated(Binder.getCallingUid())) {
2181            throw new SecurityException("Isolated process not allowed to call " + caller);
2182        }
2183    }
2184
2185    public int getFrontActivityScreenCompatMode() {
2186        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2187        synchronized (this) {
2188            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2189        }
2190    }
2191
2192    public void setFrontActivityScreenCompatMode(int mode) {
2193        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2194                "setFrontActivityScreenCompatMode");
2195        synchronized (this) {
2196            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2197        }
2198    }
2199
2200    public int getPackageScreenCompatMode(String packageName) {
2201        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2202        synchronized (this) {
2203            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2204        }
2205    }
2206
2207    public void setPackageScreenCompatMode(String packageName, int mode) {
2208        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2209                "setPackageScreenCompatMode");
2210        synchronized (this) {
2211            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2212        }
2213    }
2214
2215    public boolean getPackageAskScreenCompat(String packageName) {
2216        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2217        synchronized (this) {
2218            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2219        }
2220    }
2221
2222    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2223        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2224                "setPackageAskScreenCompat");
2225        synchronized (this) {
2226            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2227        }
2228    }
2229
2230    void reportResumedActivityLocked(ActivityRecord r) {
2231        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2232        updateUsageStats(r, true);
2233    }
2234
2235    private void dispatchProcessesChanged() {
2236        int N;
2237        synchronized (this) {
2238            N = mPendingProcessChanges.size();
2239            if (mActiveProcessChanges.length < N) {
2240                mActiveProcessChanges = new ProcessChangeItem[N];
2241            }
2242            mPendingProcessChanges.toArray(mActiveProcessChanges);
2243            mAvailProcessChanges.addAll(mPendingProcessChanges);
2244            mPendingProcessChanges.clear();
2245            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2246        }
2247        int i = mProcessObservers.beginBroadcast();
2248        while (i > 0) {
2249            i--;
2250            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2251            if (observer != null) {
2252                try {
2253                    for (int j=0; j<N; j++) {
2254                        ProcessChangeItem item = mActiveProcessChanges[j];
2255                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2256                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2257                                    + item.pid + " uid=" + item.uid + ": "
2258                                    + item.foregroundActivities);
2259                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2260                                    item.foregroundActivities);
2261                        }
2262                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2263                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2264                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2265                            observer.onImportanceChanged(item.pid, item.uid,
2266                                    item.importance);
2267                        }
2268                    }
2269                } catch (RemoteException e) {
2270                }
2271            }
2272        }
2273        mProcessObservers.finishBroadcast();
2274    }
2275
2276    private void dispatchProcessDied(int pid, int uid) {
2277        int i = mProcessObservers.beginBroadcast();
2278        while (i > 0) {
2279            i--;
2280            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2281            if (observer != null) {
2282                try {
2283                    observer.onProcessDied(pid, uid);
2284                } catch (RemoteException e) {
2285                }
2286            }
2287        }
2288        mProcessObservers.finishBroadcast();
2289    }
2290
2291    final void doPendingActivityLaunchesLocked(boolean doResume) {
2292        final int N = mPendingActivityLaunches.size();
2293        if (N <= 0) {
2294            return;
2295        }
2296        for (int i=0; i<N; i++) {
2297            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2298            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2299                    pal.startFlags, doResume && i == (N-1), null);
2300        }
2301        mPendingActivityLaunches.clear();
2302    }
2303
2304    public final int startActivity(IApplicationThread caller,
2305            Intent intent, String resolvedType, IBinder resultTo,
2306            String resultWho, int requestCode, int startFlags,
2307            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2308        enforceNotIsolatedCaller("startActivity");
2309        int userId = 0;
2310        if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2311            // Requesting home, set the identity to the current user
2312            // HACK!
2313            userId = mCurrentUserId;
2314        } else {
2315            // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2316            // the current user's userId
2317            if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2318                userId = 0;
2319            } else {
2320                userId = Binder.getOrigCallingUser();
2321            }
2322        }
2323        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2324                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2325                null, null, options, userId);
2326    }
2327
2328    public final WaitResult startActivityAndWait(IApplicationThread caller,
2329            Intent intent, String resolvedType, IBinder resultTo,
2330            String resultWho, int requestCode, int startFlags, String profileFile,
2331            ParcelFileDescriptor profileFd, Bundle options) {
2332        enforceNotIsolatedCaller("startActivityAndWait");
2333        WaitResult res = new WaitResult();
2334        int userId = Binder.getOrigCallingUser();
2335        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2336                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2337                res, null, options, userId);
2338        return res;
2339    }
2340
2341    public final int startActivityWithConfig(IApplicationThread caller,
2342            Intent intent, String resolvedType, IBinder resultTo,
2343            String resultWho, int requestCode, int startFlags, Configuration config,
2344            Bundle options) {
2345        enforceNotIsolatedCaller("startActivityWithConfig");
2346        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2347                resultTo, resultWho, requestCode, startFlags,
2348                null, null, null, config, options, Binder.getOrigCallingUser());
2349        return ret;
2350    }
2351
2352    public int startActivityIntentSender(IApplicationThread caller,
2353            IntentSender intent, Intent fillInIntent, String resolvedType,
2354            IBinder resultTo, String resultWho, int requestCode,
2355            int flagsMask, int flagsValues, Bundle options) {
2356        enforceNotIsolatedCaller("startActivityIntentSender");
2357        // Refuse possible leaked file descriptors
2358        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2359            throw new IllegalArgumentException("File descriptors passed in Intent");
2360        }
2361
2362        IIntentSender sender = intent.getTarget();
2363        if (!(sender instanceof PendingIntentRecord)) {
2364            throw new IllegalArgumentException("Bad PendingIntent object");
2365        }
2366
2367        PendingIntentRecord pir = (PendingIntentRecord)sender;
2368
2369        synchronized (this) {
2370            // If this is coming from the currently resumed activity, it is
2371            // effectively saying that app switches are allowed at this point.
2372            if (mMainStack.mResumedActivity != null
2373                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2374                            Binder.getCallingUid()) {
2375                mAppSwitchesAllowedTime = 0;
2376            }
2377        }
2378        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2379                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2380        return ret;
2381    }
2382
2383    public boolean startNextMatchingActivity(IBinder callingActivity,
2384            Intent intent, Bundle options) {
2385        // Refuse possible leaked file descriptors
2386        if (intent != null && intent.hasFileDescriptors() == true) {
2387            throw new IllegalArgumentException("File descriptors passed in Intent");
2388        }
2389
2390        synchronized (this) {
2391            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2392            if (r == null) {
2393                ActivityOptions.abort(options);
2394                return false;
2395            }
2396            if (r.app == null || r.app.thread == null) {
2397                // The caller is not running...  d'oh!
2398                ActivityOptions.abort(options);
2399                return false;
2400            }
2401            intent = new Intent(intent);
2402            // The caller is not allowed to change the data.
2403            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2404            // And we are resetting to find the next component...
2405            intent.setComponent(null);
2406
2407            ActivityInfo aInfo = null;
2408            try {
2409                List<ResolveInfo> resolves =
2410                    AppGlobals.getPackageManager().queryIntentActivities(
2411                            intent, r.resolvedType,
2412                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2413                            UserId.getCallingUserId());
2414
2415                // Look for the original activity in the list...
2416                final int N = resolves != null ? resolves.size() : 0;
2417                for (int i=0; i<N; i++) {
2418                    ResolveInfo rInfo = resolves.get(i);
2419                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2420                            && rInfo.activityInfo.name.equals(r.info.name)) {
2421                        // We found the current one...  the next matching is
2422                        // after it.
2423                        i++;
2424                        if (i<N) {
2425                            aInfo = resolves.get(i).activityInfo;
2426                        }
2427                        break;
2428                    }
2429                }
2430            } catch (RemoteException e) {
2431            }
2432
2433            if (aInfo == null) {
2434                // Nobody who is next!
2435                ActivityOptions.abort(options);
2436                return false;
2437            }
2438
2439            intent.setComponent(new ComponentName(
2440                    aInfo.applicationInfo.packageName, aInfo.name));
2441            intent.setFlags(intent.getFlags()&~(
2442                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2443                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2444                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2445                    Intent.FLAG_ACTIVITY_NEW_TASK));
2446
2447            // Okay now we need to start the new activity, replacing the
2448            // currently running activity.  This is a little tricky because
2449            // we want to start the new one as if the current one is finished,
2450            // but not finish the current one first so that there is no flicker.
2451            // And thus...
2452            final boolean wasFinishing = r.finishing;
2453            r.finishing = true;
2454
2455            // Propagate reply information over to the new activity.
2456            final ActivityRecord resultTo = r.resultTo;
2457            final String resultWho = r.resultWho;
2458            final int requestCode = r.requestCode;
2459            r.resultTo = null;
2460            if (resultTo != null) {
2461                resultTo.removeResultsLocked(r, resultWho, requestCode);
2462            }
2463
2464            final long origId = Binder.clearCallingIdentity();
2465            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2466                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2467                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2468                    options, false, null);
2469            Binder.restoreCallingIdentity(origId);
2470
2471            r.finishing = wasFinishing;
2472            if (res != ActivityManager.START_SUCCESS) {
2473                return false;
2474            }
2475            return true;
2476        }
2477    }
2478
2479    public final int startActivityInPackage(int uid,
2480            Intent intent, String resolvedType, IBinder resultTo,
2481            String resultWho, int requestCode, int startFlags, Bundle options) {
2482
2483        // This is so super not safe, that only the system (or okay root)
2484        // can do it.
2485        int userId = Binder.getOrigCallingUser();
2486        final int callingUid = Binder.getCallingUid();
2487        if (callingUid != 0 && callingUid != Process.myUid()) {
2488            throw new SecurityException(
2489                    "startActivityInPackage only available to the system");
2490        }
2491
2492        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2493                resultTo, resultWho, requestCode, startFlags,
2494                null, null, null, null, options, userId);
2495        return ret;
2496    }
2497
2498    public final int startActivities(IApplicationThread caller,
2499            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2500        enforceNotIsolatedCaller("startActivities");
2501        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2502                options, Binder.getOrigCallingUser());
2503        return ret;
2504    }
2505
2506    public final int startActivitiesInPackage(int uid,
2507            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2508            Bundle options) {
2509
2510        // This is so super not safe, that only the system (or okay root)
2511        // can do it.
2512        final int callingUid = Binder.getCallingUid();
2513        if (callingUid != 0 && callingUid != Process.myUid()) {
2514            throw new SecurityException(
2515                    "startActivityInPackage only available to the system");
2516        }
2517        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2518                options, UserId.getUserId(uid));
2519        return ret;
2520    }
2521
2522    final void addRecentTaskLocked(TaskRecord task) {
2523        int N = mRecentTasks.size();
2524        // Quick case: check if the top-most recent task is the same.
2525        if (N > 0 && mRecentTasks.get(0) == task) {
2526            return;
2527        }
2528        // Remove any existing entries that are the same kind of task.
2529        for (int i=0; i<N; i++) {
2530            TaskRecord tr = mRecentTasks.get(i);
2531            if (task.userId == tr.userId
2532                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2533                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2534                mRecentTasks.remove(i);
2535                i--;
2536                N--;
2537                if (task.intent == null) {
2538                    // If the new recent task we are adding is not fully
2539                    // specified, then replace it with the existing recent task.
2540                    task = tr;
2541                }
2542            }
2543        }
2544        if (N >= MAX_RECENT_TASKS) {
2545            mRecentTasks.remove(N-1);
2546        }
2547        mRecentTasks.add(0, task);
2548    }
2549
2550    public void setRequestedOrientation(IBinder token,
2551            int requestedOrientation) {
2552        synchronized (this) {
2553            ActivityRecord r = mMainStack.isInStackLocked(token);
2554            if (r == null) {
2555                return;
2556            }
2557            final long origId = Binder.clearCallingIdentity();
2558            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2559            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2560                    mConfiguration,
2561                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2562            if (config != null) {
2563                r.frozenBeforeDestroy = true;
2564                if (!updateConfigurationLocked(config, r, false, false)) {
2565                    mMainStack.resumeTopActivityLocked(null);
2566                }
2567            }
2568            Binder.restoreCallingIdentity(origId);
2569        }
2570    }
2571
2572    public int getRequestedOrientation(IBinder token) {
2573        synchronized (this) {
2574            ActivityRecord r = mMainStack.isInStackLocked(token);
2575            if (r == null) {
2576                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2577            }
2578            return mWindowManager.getAppOrientation(r.appToken);
2579        }
2580    }
2581
2582    /**
2583     * This is the internal entry point for handling Activity.finish().
2584     *
2585     * @param token The Binder token referencing the Activity we want to finish.
2586     * @param resultCode Result code, if any, from this Activity.
2587     * @param resultData Result data (Intent), if any, from this Activity.
2588     *
2589     * @return Returns true if the activity successfully finished, or false if it is still running.
2590     */
2591    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2592        // Refuse possible leaked file descriptors
2593        if (resultData != null && resultData.hasFileDescriptors() == true) {
2594            throw new IllegalArgumentException("File descriptors passed in Intent");
2595        }
2596
2597        synchronized(this) {
2598            if (mController != null) {
2599                // Find the first activity that is not finishing.
2600                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2601                if (next != null) {
2602                    // ask watcher if this is allowed
2603                    boolean resumeOK = true;
2604                    try {
2605                        resumeOK = mController.activityResuming(next.packageName);
2606                    } catch (RemoteException e) {
2607                        mController = null;
2608                    }
2609
2610                    if (!resumeOK) {
2611                        return false;
2612                    }
2613                }
2614            }
2615            final long origId = Binder.clearCallingIdentity();
2616            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2617                    resultData, "app-request");
2618            Binder.restoreCallingIdentity(origId);
2619            return res;
2620        }
2621    }
2622
2623    public final void finishHeavyWeightApp() {
2624        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2625                != PackageManager.PERMISSION_GRANTED) {
2626            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2627                    + Binder.getCallingPid()
2628                    + ", uid=" + Binder.getCallingUid()
2629                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2630            Slog.w(TAG, msg);
2631            throw new SecurityException(msg);
2632        }
2633
2634        synchronized(this) {
2635            if (mHeavyWeightProcess == null) {
2636                return;
2637            }
2638
2639            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2640                    mHeavyWeightProcess.activities);
2641            for (int i=0; i<activities.size(); i++) {
2642                ActivityRecord r = activities.get(i);
2643                if (!r.finishing) {
2644                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2645                    if (index >= 0) {
2646                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2647                                null, "finish-heavy");
2648                    }
2649                }
2650            }
2651
2652            mHeavyWeightProcess = null;
2653            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2654        }
2655    }
2656
2657    public void crashApplication(int uid, int initialPid, String packageName,
2658            String message) {
2659        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2660                != PackageManager.PERMISSION_GRANTED) {
2661            String msg = "Permission Denial: crashApplication() from pid="
2662                    + Binder.getCallingPid()
2663                    + ", uid=" + Binder.getCallingUid()
2664                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2665            Slog.w(TAG, msg);
2666            throw new SecurityException(msg);
2667        }
2668
2669        synchronized(this) {
2670            ProcessRecord proc = null;
2671
2672            // Figure out which process to kill.  We don't trust that initialPid
2673            // still has any relation to current pids, so must scan through the
2674            // list.
2675            synchronized (mPidsSelfLocked) {
2676                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2677                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2678                    if (p.uid != uid) {
2679                        continue;
2680                    }
2681                    if (p.pid == initialPid) {
2682                        proc = p;
2683                        break;
2684                    }
2685                    for (String str : p.pkgList) {
2686                        if (str.equals(packageName)) {
2687                            proc = p;
2688                        }
2689                    }
2690                }
2691            }
2692
2693            if (proc == null) {
2694                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2695                        + " initialPid=" + initialPid
2696                        + " packageName=" + packageName);
2697                return;
2698            }
2699
2700            if (proc.thread != null) {
2701                if (proc.pid == Process.myPid()) {
2702                    Log.w(TAG, "crashApplication: trying to crash self!");
2703                    return;
2704                }
2705                long ident = Binder.clearCallingIdentity();
2706                try {
2707                    proc.thread.scheduleCrash(message);
2708                } catch (RemoteException e) {
2709                }
2710                Binder.restoreCallingIdentity(ident);
2711            }
2712        }
2713    }
2714
2715    public final void finishSubActivity(IBinder token, String resultWho,
2716            int requestCode) {
2717        synchronized(this) {
2718            final long origId = Binder.clearCallingIdentity();
2719            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2720            Binder.restoreCallingIdentity(origId);
2721        }
2722    }
2723
2724    public boolean finishActivityAffinity(IBinder token) {
2725        synchronized(this) {
2726            final long origId = Binder.clearCallingIdentity();
2727            boolean res = mMainStack.finishActivityAffinityLocked(token);
2728            Binder.restoreCallingIdentity(origId);
2729            return res;
2730        }
2731    }
2732
2733    public boolean willActivityBeVisible(IBinder token) {
2734        synchronized(this) {
2735            int i;
2736            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2737                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2738                if (r.appToken == token) {
2739                    return true;
2740                }
2741                if (r.fullscreen && !r.finishing) {
2742                    return false;
2743                }
2744            }
2745            return true;
2746        }
2747    }
2748
2749    public void overridePendingTransition(IBinder token, String packageName,
2750            int enterAnim, int exitAnim) {
2751        synchronized(this) {
2752            ActivityRecord self = mMainStack.isInStackLocked(token);
2753            if (self == null) {
2754                return;
2755            }
2756
2757            final long origId = Binder.clearCallingIdentity();
2758
2759            if (self.state == ActivityState.RESUMED
2760                    || self.state == ActivityState.PAUSING) {
2761                mWindowManager.overridePendingAppTransition(packageName,
2762                        enterAnim, exitAnim, null);
2763            }
2764
2765            Binder.restoreCallingIdentity(origId);
2766        }
2767    }
2768
2769    /**
2770     * Main function for removing an existing process from the activity manager
2771     * as a result of that process going away.  Clears out all connections
2772     * to the process.
2773     */
2774    private final void handleAppDiedLocked(ProcessRecord app,
2775            boolean restarting, boolean allowRestart) {
2776        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2777        if (!restarting) {
2778            mLruProcesses.remove(app);
2779        }
2780
2781        if (mProfileProc == app) {
2782            clearProfilerLocked();
2783        }
2784
2785        // Just in case...
2786        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2787            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2788            mMainStack.mPausingActivity = null;
2789        }
2790        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2791            mMainStack.mLastPausedActivity = null;
2792        }
2793
2794        // Remove this application's activities from active lists.
2795        mMainStack.removeHistoryRecordsForAppLocked(app);
2796
2797        boolean atTop = true;
2798        boolean hasVisibleActivities = false;
2799
2800        // Clean out the history list.
2801        int i = mMainStack.mHistory.size();
2802        if (localLOGV) Slog.v(
2803            TAG, "Removing app " + app + " from history with " + i + " entries");
2804        while (i > 0) {
2805            i--;
2806            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2807            if (localLOGV) Slog.v(
2808                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2809            if (r.app == app) {
2810                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2811                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2812                        RuntimeException here = new RuntimeException("here");
2813                        here.fillInStackTrace();
2814                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2815                                + ": haveState=" + r.haveState
2816                                + " stateNotNeeded=" + r.stateNotNeeded
2817                                + " finishing=" + r.finishing
2818                                + " state=" + r.state, here);
2819                    }
2820                    if (!r.finishing) {
2821                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2822                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2823                                System.identityHashCode(r),
2824                                r.task.taskId, r.shortComponentName,
2825                                "proc died without state saved");
2826                    }
2827                    mMainStack.removeActivityFromHistoryLocked(r);
2828
2829                } else {
2830                    // We have the current state for this activity, so
2831                    // it can be restarted later when needed.
2832                    if (localLOGV) Slog.v(
2833                        TAG, "Keeping entry, setting app to null");
2834                    if (r.visible) {
2835                        hasVisibleActivities = true;
2836                    }
2837                    r.app = null;
2838                    r.nowVisible = false;
2839                    if (!r.haveState) {
2840                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2841                                "App died, clearing saved state of " + r);
2842                        r.icicle = null;
2843                    }
2844                }
2845
2846                r.stack.cleanUpActivityLocked(r, true, true);
2847            }
2848            atTop = false;
2849        }
2850
2851        app.activities.clear();
2852
2853        if (app.instrumentationClass != null) {
2854            Slog.w(TAG, "Crash of app " + app.processName
2855                  + " running instrumentation " + app.instrumentationClass);
2856            Bundle info = new Bundle();
2857            info.putString("shortMsg", "Process crashed.");
2858            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2859        }
2860
2861        if (!restarting) {
2862            if (!mMainStack.resumeTopActivityLocked(null)) {
2863                // If there was nothing to resume, and we are not already
2864                // restarting this process, but there is a visible activity that
2865                // is hosted by the process...  then make sure all visible
2866                // activities are running, taking care of restarting this
2867                // process.
2868                if (hasVisibleActivities) {
2869                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2870                }
2871            }
2872        }
2873    }
2874
2875    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2876        IBinder threadBinder = thread.asBinder();
2877        // Find the application record.
2878        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2879            ProcessRecord rec = mLruProcesses.get(i);
2880            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2881                return i;
2882            }
2883        }
2884        return -1;
2885    }
2886
2887    final ProcessRecord getRecordForAppLocked(
2888            IApplicationThread thread) {
2889        if (thread == null) {
2890            return null;
2891        }
2892
2893        int appIndex = getLRURecordIndexForAppLocked(thread);
2894        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2895    }
2896
2897    final void appDiedLocked(ProcessRecord app, int pid,
2898            IApplicationThread thread) {
2899
2900        mProcDeaths[0]++;
2901
2902        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2903        synchronized (stats) {
2904            stats.noteProcessDiedLocked(app.info.uid, pid);
2905        }
2906
2907        // Clean up already done if the process has been re-started.
2908        if (app.pid == pid && app.thread != null &&
2909                app.thread.asBinder() == thread.asBinder()) {
2910            if (!app.killedBackground) {
2911                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2912                        + ") has died.");
2913            }
2914            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2915            if (localLOGV) Slog.v(
2916                TAG, "Dying app: " + app + ", pid: " + pid
2917                + ", thread: " + thread.asBinder());
2918            boolean doLowMem = app.instrumentationClass == null;
2919            handleAppDiedLocked(app, false, true);
2920
2921            if (doLowMem) {
2922                // If there are no longer any background processes running,
2923                // and the app that died was not running instrumentation,
2924                // then tell everyone we are now low on memory.
2925                boolean haveBg = false;
2926                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2927                    ProcessRecord rec = mLruProcesses.get(i);
2928                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2929                        haveBg = true;
2930                        break;
2931                    }
2932                }
2933
2934                if (!haveBg) {
2935                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2936                    long now = SystemClock.uptimeMillis();
2937                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2938                        ProcessRecord rec = mLruProcesses.get(i);
2939                        if (rec != app && rec.thread != null &&
2940                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2941                            // The low memory report is overriding any current
2942                            // state for a GC request.  Make sure to do
2943                            // heavy/important/visible/foreground processes first.
2944                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2945                                rec.lastRequestedGc = 0;
2946                            } else {
2947                                rec.lastRequestedGc = rec.lastLowMemory;
2948                            }
2949                            rec.reportLowMemory = true;
2950                            rec.lastLowMemory = now;
2951                            mProcessesToGc.remove(rec);
2952                            addProcessToGcListLocked(rec);
2953                        }
2954                    }
2955                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
2956                    scheduleAppGcsLocked();
2957                }
2958            }
2959        } else if (app.pid != pid) {
2960            // A new process has already been started.
2961            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2962                    + ") has died and restarted (pid " + app.pid + ").");
2963            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2964        } else if (DEBUG_PROCESSES) {
2965            Slog.d(TAG, "Received spurious death notification for thread "
2966                    + thread.asBinder());
2967        }
2968    }
2969
2970    /**
2971     * If a stack trace dump file is configured, dump process stack traces.
2972     * @param clearTraces causes the dump file to be erased prior to the new
2973     *    traces being written, if true; when false, the new traces will be
2974     *    appended to any existing file content.
2975     * @param firstPids of dalvik VM processes to dump stack traces for first
2976     * @param lastPids of dalvik VM processes to dump stack traces for last
2977     * @param nativeProcs optional list of native process names to dump stack crawls
2978     * @return file containing stack traces, or null if no dump file is configured
2979     */
2980    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2981            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
2982        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2983        if (tracesPath == null || tracesPath.length() == 0) {
2984            return null;
2985        }
2986
2987        File tracesFile = new File(tracesPath);
2988        try {
2989            File tracesDir = tracesFile.getParentFile();
2990            if (!tracesDir.exists()) tracesFile.mkdirs();
2991            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
2992
2993            if (clearTraces && tracesFile.exists()) tracesFile.delete();
2994            tracesFile.createNewFile();
2995            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2996        } catch (IOException e) {
2997            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
2998            return null;
2999        }
3000
3001        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3002        return tracesFile;
3003    }
3004
3005    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3006            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3007        // Use a FileObserver to detect when traces finish writing.
3008        // The order of traces is considered important to maintain for legibility.
3009        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3010            public synchronized void onEvent(int event, String path) { notify(); }
3011        };
3012
3013        try {
3014            observer.startWatching();
3015
3016            // First collect all of the stacks of the most important pids.
3017            if (firstPids != null) {
3018                try {
3019                    int num = firstPids.size();
3020                    for (int i = 0; i < num; i++) {
3021                        synchronized (observer) {
3022                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3023                            observer.wait(200);  // Wait for write-close, give up after 200msec
3024                        }
3025                    }
3026                } catch (InterruptedException e) {
3027                    Log.wtf(TAG, e);
3028                }
3029            }
3030
3031            // Next measure CPU usage.
3032            if (processStats != null) {
3033                processStats.init();
3034                System.gc();
3035                processStats.update();
3036                try {
3037                    synchronized (processStats) {
3038                        processStats.wait(500); // measure over 1/2 second.
3039                    }
3040                } catch (InterruptedException e) {
3041                }
3042                processStats.update();
3043
3044                // We'll take the stack crawls of just the top apps using CPU.
3045                final int N = processStats.countWorkingStats();
3046                int numProcs = 0;
3047                for (int i=0; i<N && numProcs<5; i++) {
3048                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3049                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3050                        numProcs++;
3051                        try {
3052                            synchronized (observer) {
3053                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3054                                observer.wait(200);  // Wait for write-close, give up after 200msec
3055                            }
3056                        } catch (InterruptedException e) {
3057                            Log.wtf(TAG, e);
3058                        }
3059
3060                    }
3061                }
3062            }
3063
3064        } finally {
3065            observer.stopWatching();
3066        }
3067
3068        if (nativeProcs != null) {
3069            int[] pids = Process.getPidsForCommands(nativeProcs);
3070            if (pids != null) {
3071                for (int pid : pids) {
3072                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3073                }
3074            }
3075        }
3076    }
3077
3078    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3079        if (true || IS_USER_BUILD) {
3080            return;
3081        }
3082        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3083        if (tracesPath == null || tracesPath.length() == 0) {
3084            return;
3085        }
3086
3087        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3088        StrictMode.allowThreadDiskWrites();
3089        try {
3090            final File tracesFile = new File(tracesPath);
3091            final File tracesDir = tracesFile.getParentFile();
3092            final File tracesTmp = new File(tracesDir, "__tmp__");
3093            try {
3094                if (!tracesDir.exists()) tracesFile.mkdirs();
3095                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3096
3097                if (tracesFile.exists()) {
3098                    tracesTmp.delete();
3099                    tracesFile.renameTo(tracesTmp);
3100                }
3101                StringBuilder sb = new StringBuilder();
3102                Time tobj = new Time();
3103                tobj.set(System.currentTimeMillis());
3104                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3105                sb.append(": ");
3106                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3107                sb.append(" since ");
3108                sb.append(msg);
3109                FileOutputStream fos = new FileOutputStream(tracesFile);
3110                fos.write(sb.toString().getBytes());
3111                if (app == null) {
3112                    fos.write("\n*** No application process!".getBytes());
3113                }
3114                fos.close();
3115                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3116            } catch (IOException e) {
3117                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3118                return;
3119            }
3120
3121            if (app != null) {
3122                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3123                firstPids.add(app.pid);
3124                dumpStackTraces(tracesPath, firstPids, null, null, null);
3125            }
3126
3127            File lastTracesFile = null;
3128            File curTracesFile = null;
3129            for (int i=9; i>=0; i--) {
3130                String name = String.format("slow%02d.txt", i);
3131                curTracesFile = new File(tracesDir, name);
3132                if (curTracesFile.exists()) {
3133                    if (lastTracesFile != null) {
3134                        curTracesFile.renameTo(lastTracesFile);
3135                    } else {
3136                        curTracesFile.delete();
3137                    }
3138                }
3139                lastTracesFile = curTracesFile;
3140            }
3141            tracesFile.renameTo(curTracesFile);
3142            if (tracesTmp.exists()) {
3143                tracesTmp.renameTo(tracesFile);
3144            }
3145        } finally {
3146            StrictMode.setThreadPolicy(oldPolicy);
3147        }
3148    }
3149
3150    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3151            ActivityRecord parent, final String annotation) {
3152        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3153        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3154
3155        if (mController != null) {
3156            try {
3157                // 0 == continue, -1 = kill process immediately
3158                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3159                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3160            } catch (RemoteException e) {
3161                mController = null;
3162            }
3163        }
3164
3165        long anrTime = SystemClock.uptimeMillis();
3166        if (MONITOR_CPU_USAGE) {
3167            updateCpuStatsNow();
3168        }
3169
3170        synchronized (this) {
3171            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3172            if (mShuttingDown) {
3173                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3174                return;
3175            } else if (app.notResponding) {
3176                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3177                return;
3178            } else if (app.crashing) {
3179                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3180                return;
3181            }
3182
3183            // In case we come through here for the same app before completing
3184            // this one, mark as anring now so we will bail out.
3185            app.notResponding = true;
3186
3187            // Log the ANR to the event log.
3188            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3189                    annotation);
3190
3191            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3192            firstPids.add(app.pid);
3193
3194            int parentPid = app.pid;
3195            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3196            if (parentPid != app.pid) firstPids.add(parentPid);
3197
3198            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3199
3200            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3201                ProcessRecord r = mLruProcesses.get(i);
3202                if (r != null && r.thread != null) {
3203                    int pid = r.pid;
3204                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3205                        if (r.persistent) {
3206                            firstPids.add(pid);
3207                        } else {
3208                            lastPids.put(pid, Boolean.TRUE);
3209                        }
3210                    }
3211                }
3212            }
3213        }
3214
3215        // Log the ANR to the main log.
3216        StringBuilder info = new StringBuilder();
3217        info.setLength(0);
3218        info.append("ANR in ").append(app.processName);
3219        if (activity != null && activity.shortComponentName != null) {
3220            info.append(" (").append(activity.shortComponentName).append(")");
3221        }
3222        info.append("\n");
3223        if (annotation != null) {
3224            info.append("Reason: ").append(annotation).append("\n");
3225        }
3226        if (parent != null && parent != activity) {
3227            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3228        }
3229
3230        final ProcessStats processStats = new ProcessStats(true);
3231
3232        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3233
3234        String cpuInfo = null;
3235        if (MONITOR_CPU_USAGE) {
3236            updateCpuStatsNow();
3237            synchronized (mProcessStatsThread) {
3238                cpuInfo = mProcessStats.printCurrentState(anrTime);
3239            }
3240            info.append(processStats.printCurrentLoad());
3241            info.append(cpuInfo);
3242        }
3243
3244        info.append(processStats.printCurrentState(anrTime));
3245
3246        Slog.e(TAG, info.toString());
3247        if (tracesFile == null) {
3248            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3249            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3250        }
3251
3252        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3253                cpuInfo, tracesFile, null);
3254
3255        if (mController != null) {
3256            try {
3257                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3258                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3259                if (res != 0) {
3260                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3261                    return;
3262                }
3263            } catch (RemoteException e) {
3264                mController = null;
3265            }
3266        }
3267
3268        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3269        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3270                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3271
3272        synchronized (this) {
3273            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3274                Slog.w(TAG, "Killing " + app + ": background ANR");
3275                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3276                        app.processName, app.setAdj, "background ANR");
3277                Process.killProcessQuiet(app.pid);
3278                return;
3279            }
3280
3281            // Set the app's notResponding state, and look up the errorReportReceiver
3282            makeAppNotRespondingLocked(app,
3283                    activity != null ? activity.shortComponentName : null,
3284                    annotation != null ? "ANR " + annotation : "ANR",
3285                    info.toString());
3286
3287            // Bring up the infamous App Not Responding dialog
3288            Message msg = Message.obtain();
3289            HashMap map = new HashMap();
3290            msg.what = SHOW_NOT_RESPONDING_MSG;
3291            msg.obj = map;
3292            map.put("app", app);
3293            if (activity != null) {
3294                map.put("activity", activity);
3295            }
3296
3297            mHandler.sendMessage(msg);
3298        }
3299    }
3300
3301    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3302        if (!mLaunchWarningShown) {
3303            mLaunchWarningShown = true;
3304            mHandler.post(new Runnable() {
3305                @Override
3306                public void run() {
3307                    synchronized (ActivityManagerService.this) {
3308                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3309                        d.show();
3310                        mHandler.postDelayed(new Runnable() {
3311                            @Override
3312                            public void run() {
3313                                synchronized (ActivityManagerService.this) {
3314                                    d.dismiss();
3315                                    mLaunchWarningShown = false;
3316                                }
3317                            }
3318                        }, 4000);
3319                    }
3320                }
3321            });
3322        }
3323    }
3324
3325    public boolean clearApplicationUserData(final String packageName,
3326            final IPackageDataObserver observer, final int userId) {
3327        enforceNotIsolatedCaller("clearApplicationUserData");
3328        int uid = Binder.getCallingUid();
3329        int pid = Binder.getCallingPid();
3330        long callingId = Binder.clearCallingIdentity();
3331        try {
3332            IPackageManager pm = AppGlobals.getPackageManager();
3333            int pkgUid = -1;
3334            synchronized(this) {
3335                try {
3336                    pkgUid = pm.getPackageUid(packageName, userId);
3337                } catch (RemoteException e) {
3338                }
3339                if (pkgUid == -1) {
3340                    Slog.w(TAG, "Invalid packageName:" + packageName);
3341                    return false;
3342                }
3343                if (uid == pkgUid || checkComponentPermission(
3344                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3345                        pid, uid, -1, true)
3346                        == PackageManager.PERMISSION_GRANTED) {
3347                    forceStopPackageLocked(packageName, pkgUid);
3348                } else {
3349                    throw new SecurityException(pid+" does not have permission:"+
3350                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3351                                    "for process:"+packageName);
3352                }
3353            }
3354
3355            try {
3356                //clear application user data
3357                pm.clearApplicationUserData(packageName, observer, userId);
3358                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3359                        Uri.fromParts("package", packageName, null));
3360                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3361                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3362                        null, null, 0, null, null, null, false, false, userId);
3363            } catch (RemoteException e) {
3364            }
3365        } finally {
3366            Binder.restoreCallingIdentity(callingId);
3367        }
3368        return true;
3369    }
3370
3371    public void killBackgroundProcesses(final String packageName) {
3372        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3373                != PackageManager.PERMISSION_GRANTED &&
3374                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3375                        != PackageManager.PERMISSION_GRANTED) {
3376            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3377                    + Binder.getCallingPid()
3378                    + ", uid=" + Binder.getCallingUid()
3379                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3380            Slog.w(TAG, msg);
3381            throw new SecurityException(msg);
3382        }
3383
3384        int userId = UserId.getCallingUserId();
3385        long callingId = Binder.clearCallingIdentity();
3386        try {
3387            IPackageManager pm = AppGlobals.getPackageManager();
3388            int pkgUid = -1;
3389            synchronized(this) {
3390                try {
3391                    pkgUid = pm.getPackageUid(packageName, userId);
3392                } catch (RemoteException e) {
3393                }
3394                if (pkgUid == -1) {
3395                    Slog.w(TAG, "Invalid packageName: " + packageName);
3396                    return;
3397                }
3398                killPackageProcessesLocked(packageName, pkgUid,
3399                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3400            }
3401        } finally {
3402            Binder.restoreCallingIdentity(callingId);
3403        }
3404    }
3405
3406    public void killAllBackgroundProcesses() {
3407        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3408                != PackageManager.PERMISSION_GRANTED) {
3409            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3410                    + Binder.getCallingPid()
3411                    + ", uid=" + Binder.getCallingUid()
3412                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3413            Slog.w(TAG, msg);
3414            throw new SecurityException(msg);
3415        }
3416
3417        long callingId = Binder.clearCallingIdentity();
3418        try {
3419            synchronized(this) {
3420                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3421                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3422                    final int NA = apps.size();
3423                    for (int ia=0; ia<NA; ia++) {
3424                        ProcessRecord app = apps.valueAt(ia);
3425                        if (app.persistent) {
3426                            // we don't kill persistent processes
3427                            continue;
3428                        }
3429                        if (app.removed) {
3430                            procs.add(app);
3431                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3432                            app.removed = true;
3433                            procs.add(app);
3434                        }
3435                    }
3436                }
3437
3438                int N = procs.size();
3439                for (int i=0; i<N; i++) {
3440                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3441                }
3442            }
3443        } finally {
3444            Binder.restoreCallingIdentity(callingId);
3445        }
3446    }
3447
3448    public void forceStopPackage(final String packageName) {
3449        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3450                != PackageManager.PERMISSION_GRANTED) {
3451            String msg = "Permission Denial: forceStopPackage() from pid="
3452                    + Binder.getCallingPid()
3453                    + ", uid=" + Binder.getCallingUid()
3454                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3455            Slog.w(TAG, msg);
3456            throw new SecurityException(msg);
3457        }
3458        final int userId = UserId.getCallingUserId();
3459        long callingId = Binder.clearCallingIdentity();
3460        try {
3461            IPackageManager pm = AppGlobals.getPackageManager();
3462            int pkgUid = -1;
3463            synchronized(this) {
3464                try {
3465                    pkgUid = pm.getPackageUid(packageName, userId);
3466                } catch (RemoteException e) {
3467                }
3468                if (pkgUid == -1) {
3469                    Slog.w(TAG, "Invalid packageName: " + packageName);
3470                    return;
3471                }
3472                forceStopPackageLocked(packageName, pkgUid);
3473                try {
3474                    pm.setPackageStoppedState(packageName, true, userId);
3475                } catch (RemoteException e) {
3476                } catch (IllegalArgumentException e) {
3477                    Slog.w(TAG, "Failed trying to unstop package "
3478                            + packageName + ": " + e);
3479                }
3480            }
3481        } finally {
3482            Binder.restoreCallingIdentity(callingId);
3483        }
3484    }
3485
3486    /*
3487     * The pkg name and uid have to be specified.
3488     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3489     */
3490    public void killApplicationWithUid(String pkg, int uid) {
3491        if (pkg == null) {
3492            return;
3493        }
3494        // Make sure the uid is valid.
3495        if (uid < 0) {
3496            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3497            return;
3498        }
3499        int callerUid = Binder.getCallingUid();
3500        // Only the system server can kill an application
3501        if (callerUid == Process.SYSTEM_UID) {
3502            // Post an aysnc message to kill the application
3503            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3504            msg.arg1 = uid;
3505            msg.arg2 = 0;
3506            msg.obj = pkg;
3507            mHandler.sendMessage(msg);
3508        } else {
3509            throw new SecurityException(callerUid + " cannot kill pkg: " +
3510                    pkg);
3511        }
3512    }
3513
3514    public void closeSystemDialogs(String reason) {
3515        enforceNotIsolatedCaller("closeSystemDialogs");
3516
3517        final int uid = Binder.getCallingUid();
3518        final long origId = Binder.clearCallingIdentity();
3519        synchronized (this) {
3520            closeSystemDialogsLocked(uid, reason);
3521        }
3522        Binder.restoreCallingIdentity(origId);
3523    }
3524
3525    void closeSystemDialogsLocked(int callingUid, String reason) {
3526        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3527        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3528        if (reason != null) {
3529            intent.putExtra("reason", reason);
3530        }
3531        mWindowManager.closeSystemDialogs(reason);
3532
3533        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3534            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3535            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3536                r.stack.finishActivityLocked(r, i,
3537                        Activity.RESULT_CANCELED, null, "close-sys");
3538            }
3539        }
3540
3541        broadcastIntentLocked(null, null, intent, null,
3542                null, 0, null, null, null, false, false, -1,
3543                callingUid, 0 /* TODO: Verify */);
3544    }
3545
3546    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3547            throws RemoteException {
3548        enforceNotIsolatedCaller("getProcessMemoryInfo");
3549        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3550        for (int i=pids.length-1; i>=0; i--) {
3551            infos[i] = new Debug.MemoryInfo();
3552            Debug.getMemoryInfo(pids[i], infos[i]);
3553        }
3554        return infos;
3555    }
3556
3557    public long[] getProcessPss(int[] pids) throws RemoteException {
3558        enforceNotIsolatedCaller("getProcessPss");
3559        long[] pss = new long[pids.length];
3560        for (int i=pids.length-1; i>=0; i--) {
3561            pss[i] = Debug.getPss(pids[i]);
3562        }
3563        return pss;
3564    }
3565
3566    public void killApplicationProcess(String processName, int uid) {
3567        if (processName == null) {
3568            return;
3569        }
3570
3571        int callerUid = Binder.getCallingUid();
3572        // Only the system server can kill an application
3573        if (callerUid == Process.SYSTEM_UID) {
3574            synchronized (this) {
3575                ProcessRecord app = getProcessRecordLocked(processName, uid);
3576                if (app != null && app.thread != null) {
3577                    try {
3578                        app.thread.scheduleSuicide();
3579                    } catch (RemoteException e) {
3580                        // If the other end already died, then our work here is done.
3581                    }
3582                } else {
3583                    Slog.w(TAG, "Process/uid not found attempting kill of "
3584                            + processName + " / " + uid);
3585                }
3586            }
3587        } else {
3588            throw new SecurityException(callerUid + " cannot kill app process: " +
3589                    processName);
3590        }
3591    }
3592
3593    private void forceStopPackageLocked(final String packageName, int uid) {
3594        forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
3595        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3596                Uri.fromParts("package", packageName, null));
3597        if (!mProcessesReady) {
3598            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3599        }
3600        intent.putExtra(Intent.EXTRA_UID, uid);
3601        broadcastIntentLocked(null, null, intent,
3602                null, null, 0, null, null, null,
3603                false, false,
3604                MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
3605    }
3606
3607    private final boolean killPackageProcessesLocked(String packageName, int uid,
3608            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3609            boolean evenPersistent, String reason) {
3610        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3611
3612        // Remove all processes this package may have touched: all with the
3613        // same UID (except for the system or root user), and all whose name
3614        // matches the package name.
3615        final String procNamePrefix = packageName + ":";
3616        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3617            final int NA = apps.size();
3618            for (int ia=0; ia<NA; ia++) {
3619                ProcessRecord app = apps.valueAt(ia);
3620                if (app.persistent && !evenPersistent) {
3621                    // we don't kill persistent processes
3622                    continue;
3623                }
3624                if (app.removed) {
3625                    if (doit) {
3626                        procs.add(app);
3627                    }
3628                // If uid is specified and the uid and process name match
3629                // Or, the uid is not specified and the process name matches
3630                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3631                            || ((app.processName.equals(packageName)
3632                                 || app.processName.startsWith(procNamePrefix))
3633                                && uid < 0))) {
3634                    if (app.setAdj >= minOomAdj) {
3635                        if (!doit) {
3636                            return true;
3637                        }
3638                        app.removed = true;
3639                        procs.add(app);
3640                    }
3641                }
3642            }
3643        }
3644
3645        int N = procs.size();
3646        for (int i=0; i<N; i++) {
3647            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3648        }
3649        return N > 0;
3650    }
3651
3652    private final boolean forceStopPackageLocked(String name, int uid,
3653            boolean callerWillRestart, boolean purgeCache, boolean doit,
3654            boolean evenPersistent, int userId) {
3655        int i;
3656        int N;
3657
3658        if (uid < 0) {
3659            try {
3660                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3661            } catch (RemoteException e) {
3662            }
3663        }
3664
3665        if (doit) {
3666            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3667
3668            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3669            while (badApps.hasNext()) {
3670                SparseArray<Long> ba = badApps.next();
3671                if (ba.get(uid) != null) {
3672                    badApps.remove();
3673                }
3674            }
3675        }
3676
3677        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3678                callerWillRestart, false, doit, evenPersistent, "force stop");
3679
3680        TaskRecord lastTask = null;
3681        for (i=0; i<mMainStack.mHistory.size(); i++) {
3682            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3683            final boolean samePackage = r.packageName.equals(name);
3684            if (r.userId == userId
3685                    && (samePackage || r.task == lastTask)
3686                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3687                if (!doit) {
3688                    if (r.finishing) {
3689                        // If this activity is just finishing, then it is not
3690                        // interesting as far as something to stop.
3691                        continue;
3692                    }
3693                    return true;
3694                }
3695                didSomething = true;
3696                Slog.i(TAG, "  Force finishing activity " + r);
3697                if (samePackage) {
3698                    if (r.app != null) {
3699                        r.app.removed = true;
3700                    }
3701                    r.app = null;
3702                }
3703                lastTask = r.task;
3704                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3705                        null, "force-stop", true)) {
3706                    i--;
3707                }
3708            }
3709        }
3710
3711        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3712            if (!doit) {
3713                return true;
3714            }
3715            didSomething = true;
3716        }
3717
3718        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3719        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3720            if (provider.info.packageName.equals(name)
3721                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3722                if (!doit) {
3723                    return true;
3724                }
3725                didSomething = true;
3726                providers.add(provider);
3727            }
3728        }
3729
3730        N = providers.size();
3731        for (i=0; i<N; i++) {
3732            removeDyingProviderLocked(null, providers.get(i), true);
3733        }
3734
3735        if (doit) {
3736            if (purgeCache) {
3737                AttributeCache ac = AttributeCache.instance();
3738                if (ac != null) {
3739                    ac.removePackage(name);
3740                }
3741            }
3742            if (mBooted) {
3743                mMainStack.resumeTopActivityLocked(null);
3744                mMainStack.scheduleIdleLocked();
3745            }
3746        }
3747
3748        return didSomething;
3749    }
3750
3751    private final boolean removeProcessLocked(ProcessRecord app,
3752            boolean callerWillRestart, boolean allowRestart, String reason) {
3753        final String name = app.processName;
3754        final int uid = app.uid;
3755        if (DEBUG_PROCESSES) Slog.d(
3756            TAG, "Force removing proc " + app.toShortString() + " (" + name
3757            + "/" + uid + ")");
3758
3759        mProcessNames.remove(name, uid);
3760        mIsolatedProcesses.remove(app.uid);
3761        if (mHeavyWeightProcess == app) {
3762            mHeavyWeightProcess = null;
3763            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3764        }
3765        boolean needRestart = false;
3766        if (app.pid > 0 && app.pid != MY_PID) {
3767            int pid = app.pid;
3768            synchronized (mPidsSelfLocked) {
3769                mPidsSelfLocked.remove(pid);
3770                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3771            }
3772            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3773            handleAppDiedLocked(app, true, allowRestart);
3774            mLruProcesses.remove(app);
3775            Process.killProcessQuiet(pid);
3776
3777            if (app.persistent && !app.isolated) {
3778                if (!callerWillRestart) {
3779                    addAppLocked(app.info, false);
3780                } else {
3781                    needRestart = true;
3782                }
3783            }
3784        } else {
3785            mRemovedProcesses.add(app);
3786        }
3787
3788        return needRestart;
3789    }
3790
3791    private final void processStartTimedOutLocked(ProcessRecord app) {
3792        final int pid = app.pid;
3793        boolean gone = false;
3794        synchronized (mPidsSelfLocked) {
3795            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3796            if (knownApp != null && knownApp.thread == null) {
3797                mPidsSelfLocked.remove(pid);
3798                gone = true;
3799            }
3800        }
3801
3802        if (gone) {
3803            Slog.w(TAG, "Process " + app + " failed to attach");
3804            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3805                    app.processName);
3806            mProcessNames.remove(app.processName, app.uid);
3807            mIsolatedProcesses.remove(app.uid);
3808            if (mHeavyWeightProcess == app) {
3809                mHeavyWeightProcess = null;
3810                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3811            }
3812            // Take care of any launching providers waiting for this process.
3813            checkAppInLaunchingProvidersLocked(app, true);
3814            // Take care of any services that are waiting for the process.
3815            mServices.processStartTimedOutLocked(app);
3816            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3817                    app.processName, app.setAdj, "start timeout");
3818            Process.killProcessQuiet(pid);
3819            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3820                Slog.w(TAG, "Unattached app died before backup, skipping");
3821                try {
3822                    IBackupManager bm = IBackupManager.Stub.asInterface(
3823                            ServiceManager.getService(Context.BACKUP_SERVICE));
3824                    bm.agentDisconnected(app.info.packageName);
3825                } catch (RemoteException e) {
3826                    // Can't happen; the backup manager is local
3827                }
3828            }
3829            if (isPendingBroadcastProcessLocked(pid)) {
3830                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3831                skipPendingBroadcastLocked(pid);
3832            }
3833        } else {
3834            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3835        }
3836    }
3837
3838    private final boolean attachApplicationLocked(IApplicationThread thread,
3839            int pid) {
3840
3841        // Find the application record that is being attached...  either via
3842        // the pid if we are running in multiple processes, or just pull the
3843        // next app record if we are emulating process with anonymous threads.
3844        ProcessRecord app;
3845        if (pid != MY_PID && pid >= 0) {
3846            synchronized (mPidsSelfLocked) {
3847                app = mPidsSelfLocked.get(pid);
3848            }
3849        } else {
3850            app = null;
3851        }
3852
3853        if (app == null) {
3854            Slog.w(TAG, "No pending application record for pid " + pid
3855                    + " (IApplicationThread " + thread + "); dropping process");
3856            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3857            if (pid > 0 && pid != MY_PID) {
3858                Process.killProcessQuiet(pid);
3859            } else {
3860                try {
3861                    thread.scheduleExit();
3862                } catch (Exception e) {
3863                    // Ignore exceptions.
3864                }
3865            }
3866            return false;
3867        }
3868
3869        // If this application record is still attached to a previous
3870        // process, clean it up now.
3871        if (app.thread != null) {
3872            handleAppDiedLocked(app, true, true);
3873        }
3874
3875        // Tell the process all about itself.
3876
3877        if (localLOGV) Slog.v(
3878                TAG, "Binding process pid " + pid + " to record " + app);
3879
3880        String processName = app.processName;
3881        try {
3882            AppDeathRecipient adr = new AppDeathRecipient(
3883                    app, pid, thread);
3884            thread.asBinder().linkToDeath(adr, 0);
3885            app.deathRecipient = adr;
3886        } catch (RemoteException e) {
3887            app.resetPackageList();
3888            startProcessLocked(app, "link fail", processName);
3889            return false;
3890        }
3891
3892        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3893
3894        app.thread = thread;
3895        app.curAdj = app.setAdj = -100;
3896        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3897        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3898        app.forcingToForeground = null;
3899        app.foregroundServices = false;
3900        app.hasShownUi = false;
3901        app.debugging = false;
3902
3903        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3904
3905        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3906        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3907
3908        if (!normalMode) {
3909            Slog.i(TAG, "Launching preboot mode app: " + app);
3910        }
3911
3912        if (localLOGV) Slog.v(
3913            TAG, "New app record " + app
3914            + " thread=" + thread.asBinder() + " pid=" + pid);
3915        try {
3916            int testMode = IApplicationThread.DEBUG_OFF;
3917            if (mDebugApp != null && mDebugApp.equals(processName)) {
3918                testMode = mWaitForDebugger
3919                    ? IApplicationThread.DEBUG_WAIT
3920                    : IApplicationThread.DEBUG_ON;
3921                app.debugging = true;
3922                if (mDebugTransient) {
3923                    mDebugApp = mOrigDebugApp;
3924                    mWaitForDebugger = mOrigWaitForDebugger;
3925                }
3926            }
3927            String profileFile = app.instrumentationProfileFile;
3928            ParcelFileDescriptor profileFd = null;
3929            boolean profileAutoStop = false;
3930            if (mProfileApp != null && mProfileApp.equals(processName)) {
3931                mProfileProc = app;
3932                profileFile = mProfileFile;
3933                profileFd = mProfileFd;
3934                profileAutoStop = mAutoStopProfiler;
3935            }
3936            boolean enableOpenGlTrace = false;
3937            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3938                enableOpenGlTrace = true;
3939                mOpenGlTraceApp = null;
3940            }
3941
3942            // If the app is being launched for restore or full backup, set it up specially
3943            boolean isRestrictedBackupMode = false;
3944            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3945                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3946                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3947                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3948            }
3949
3950            ensurePackageDexOpt(app.instrumentationInfo != null
3951                    ? app.instrumentationInfo.packageName
3952                    : app.info.packageName);
3953            if (app.instrumentationClass != null) {
3954                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3955            }
3956            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3957                    + processName + " with config " + mConfiguration);
3958            ApplicationInfo appInfo = app.instrumentationInfo != null
3959                    ? app.instrumentationInfo : app.info;
3960            app.compat = compatibilityInfoForPackageLocked(appInfo);
3961            if (profileFd != null) {
3962                profileFd = profileFd.dup();
3963            }
3964            thread.bindApplication(processName, appInfo, providers,
3965                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
3966                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3967                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
3968                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
3969                    mCoreSettingsObserver.getCoreSettingsLocked());
3970            updateLruProcessLocked(app, false, true);
3971            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
3972        } catch (Exception e) {
3973            // todo: Yikes!  What should we do?  For now we will try to
3974            // start another process, but that could easily get us in
3975            // an infinite loop of restarting processes...
3976            Slog.w(TAG, "Exception thrown during bind!", e);
3977
3978            app.resetPackageList();
3979            app.unlinkDeathRecipient();
3980            startProcessLocked(app, "bind fail", processName);
3981            return false;
3982        }
3983
3984        // Remove this record from the list of starting applications.
3985        mPersistentStartingProcesses.remove(app);
3986        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3987                "Attach application locked removing on hold: " + app);
3988        mProcessesOnHold.remove(app);
3989
3990        boolean badApp = false;
3991        boolean didSomething = false;
3992
3993        // See if the top visible activity is waiting to run in this process...
3994        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
3995        if (hr != null && normalMode) {
3996            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
3997                    && processName.equals(hr.processName)) {
3998                try {
3999                    if (mHeadless) {
4000                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4001                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4002                        didSomething = true;
4003                    }
4004                } catch (Exception e) {
4005                    Slog.w(TAG, "Exception in new application when starting activity "
4006                          + hr.intent.getComponent().flattenToShortString(), e);
4007                    badApp = true;
4008                }
4009            } else {
4010                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4011            }
4012        }
4013
4014        // Find any services that should be running in this process...
4015        if (!badApp) {
4016            try {
4017                didSomething |= mServices.attachApplicationLocked(app, processName);
4018            } catch (Exception e) {
4019                badApp = true;
4020            }
4021        }
4022
4023        // Check if a next-broadcast receiver is in this process...
4024        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4025            try {
4026                didSomething = sendPendingBroadcastsLocked(app);
4027            } catch (Exception e) {
4028                // If the app died trying to launch the receiver we declare it 'bad'
4029                badApp = true;
4030            }
4031        }
4032
4033        // Check whether the next backup agent is in this process...
4034        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4035            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4036            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4037            try {
4038                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4039                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4040                        mBackupTarget.backupMode);
4041            } catch (Exception e) {
4042                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4043                e.printStackTrace();
4044            }
4045        }
4046
4047        if (badApp) {
4048            // todo: Also need to kill application to deal with all
4049            // kinds of exceptions.
4050            handleAppDiedLocked(app, false, true);
4051            return false;
4052        }
4053
4054        if (!didSomething) {
4055            updateOomAdjLocked();
4056        }
4057
4058        return true;
4059    }
4060
4061    public final void attachApplication(IApplicationThread thread) {
4062        synchronized (this) {
4063            int callingPid = Binder.getCallingPid();
4064            final long origId = Binder.clearCallingIdentity();
4065            attachApplicationLocked(thread, callingPid);
4066            Binder.restoreCallingIdentity(origId);
4067        }
4068    }
4069
4070    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4071        final long origId = Binder.clearCallingIdentity();
4072        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4073        if (stopProfiling) {
4074            synchronized (this) {
4075                if (mProfileProc == r.app) {
4076                    if (mProfileFd != null) {
4077                        try {
4078                            mProfileFd.close();
4079                        } catch (IOException e) {
4080                        }
4081                        clearProfilerLocked();
4082                    }
4083                }
4084            }
4085        }
4086        Binder.restoreCallingIdentity(origId);
4087    }
4088
4089    void enableScreenAfterBoot() {
4090        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4091                SystemClock.uptimeMillis());
4092        mWindowManager.enableScreenAfterBoot();
4093
4094        synchronized (this) {
4095            updateEventDispatchingLocked();
4096        }
4097    }
4098
4099    public void showBootMessage(final CharSequence msg, final boolean always) {
4100        enforceNotIsolatedCaller("showBootMessage");
4101        mWindowManager.showBootMessage(msg, always);
4102    }
4103
4104    public void dismissKeyguardOnNextActivity() {
4105        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4106        final long token = Binder.clearCallingIdentity();
4107        try {
4108            synchronized (this) {
4109                if (mLockScreenShown) {
4110                    mLockScreenShown = false;
4111                    comeOutOfSleepIfNeededLocked();
4112                }
4113                mMainStack.dismissKeyguardOnNextActivityLocked();
4114            }
4115        } finally {
4116            Binder.restoreCallingIdentity(token);
4117        }
4118    }
4119
4120    final void finishBooting() {
4121        IntentFilter pkgFilter = new IntentFilter();
4122        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4123        pkgFilter.addDataScheme("package");
4124        mContext.registerReceiver(new BroadcastReceiver() {
4125            @Override
4126            public void onReceive(Context context, Intent intent) {
4127                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4128                if (pkgs != null) {
4129                    for (String pkg : pkgs) {
4130                        synchronized (ActivityManagerService.this) {
4131                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4132                                setResultCode(Activity.RESULT_OK);
4133                                return;
4134                            }
4135                        }
4136                    }
4137                }
4138            }
4139        }, pkgFilter);
4140
4141        IntentFilter userFilter = new IntentFilter();
4142        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4143        mContext.registerReceiver(new BroadcastReceiver() {
4144            @Override
4145            public void onReceive(Context context, Intent intent) {
4146                onUserRemoved(intent);
4147            }
4148        }, userFilter);
4149
4150        synchronized (this) {
4151            // Ensure that any processes we had put on hold are now started
4152            // up.
4153            final int NP = mProcessesOnHold.size();
4154            if (NP > 0) {
4155                ArrayList<ProcessRecord> procs =
4156                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4157                for (int ip=0; ip<NP; ip++) {
4158                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4159                            + procs.get(ip));
4160                    startProcessLocked(procs.get(ip), "on-hold", null);
4161                }
4162            }
4163
4164            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4165                // Start looking for apps that are abusing wake locks.
4166                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4167                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4168                // Tell anyone interested that we are done booting!
4169                SystemProperties.set("sys.boot_completed", "1");
4170                SystemProperties.set("dev.bootcomplete", "1");
4171                /* TODO: Send this to all users that are to be logged in on startup */
4172                broadcastIntentLocked(null, null,
4173                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4174                        null, null, 0, null, null,
4175                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4176                        false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
4177            }
4178        }
4179    }
4180
4181    final void ensureBootCompleted() {
4182        boolean booting;
4183        boolean enableScreen;
4184        synchronized (this) {
4185            booting = mBooting;
4186            mBooting = false;
4187            enableScreen = !mBooted;
4188            mBooted = true;
4189        }
4190
4191        if (booting) {
4192            finishBooting();
4193        }
4194
4195        if (enableScreen) {
4196            enableScreenAfterBoot();
4197        }
4198    }
4199
4200    public final void activityPaused(IBinder token) {
4201        final long origId = Binder.clearCallingIdentity();
4202        mMainStack.activityPaused(token, false);
4203        Binder.restoreCallingIdentity(origId);
4204    }
4205
4206    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4207            CharSequence description) {
4208        if (localLOGV) Slog.v(
4209            TAG, "Activity stopped: token=" + token);
4210
4211        // Refuse possible leaked file descriptors
4212        if (icicle != null && icicle.hasFileDescriptors()) {
4213            throw new IllegalArgumentException("File descriptors passed in Bundle");
4214        }
4215
4216        ActivityRecord r = null;
4217
4218        final long origId = Binder.clearCallingIdentity();
4219
4220        synchronized (this) {
4221            r = mMainStack.isInStackLocked(token);
4222            if (r != null) {
4223                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4224            }
4225        }
4226
4227        if (r != null) {
4228            sendPendingThumbnail(r, null, null, null, false);
4229        }
4230
4231        trimApplications();
4232
4233        Binder.restoreCallingIdentity(origId);
4234    }
4235
4236    public final void activityDestroyed(IBinder token) {
4237        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4238        mMainStack.activityDestroyed(token);
4239    }
4240
4241    public String getCallingPackage(IBinder token) {
4242        synchronized (this) {
4243            ActivityRecord r = getCallingRecordLocked(token);
4244            return r != null && r.app != null ? r.info.packageName : null;
4245        }
4246    }
4247
4248    public ComponentName getCallingActivity(IBinder token) {
4249        synchronized (this) {
4250            ActivityRecord r = getCallingRecordLocked(token);
4251            return r != null ? r.intent.getComponent() : null;
4252        }
4253    }
4254
4255    private ActivityRecord getCallingRecordLocked(IBinder token) {
4256        ActivityRecord r = mMainStack.isInStackLocked(token);
4257        if (r == null) {
4258            return null;
4259        }
4260        return r.resultTo;
4261    }
4262
4263    public ComponentName getActivityClassForToken(IBinder token) {
4264        synchronized(this) {
4265            ActivityRecord r = mMainStack.isInStackLocked(token);
4266            if (r == null) {
4267                return null;
4268            }
4269            return r.intent.getComponent();
4270        }
4271    }
4272
4273    public String getPackageForToken(IBinder token) {
4274        synchronized(this) {
4275            ActivityRecord r = mMainStack.isInStackLocked(token);
4276            if (r == null) {
4277                return null;
4278            }
4279            return r.packageName;
4280        }
4281    }
4282
4283    public IIntentSender getIntentSender(int type,
4284            String packageName, IBinder token, String resultWho,
4285            int requestCode, Intent[] intents, String[] resolvedTypes,
4286            int flags, Bundle options) {
4287        enforceNotIsolatedCaller("getIntentSender");
4288        // Refuse possible leaked file descriptors
4289        if (intents != null) {
4290            if (intents.length < 1) {
4291                throw new IllegalArgumentException("Intents array length must be >= 1");
4292            }
4293            for (int i=0; i<intents.length; i++) {
4294                Intent intent = intents[i];
4295                if (intent != null) {
4296                    if (intent.hasFileDescriptors()) {
4297                        throw new IllegalArgumentException("File descriptors passed in Intent");
4298                    }
4299                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4300                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4301                        throw new IllegalArgumentException(
4302                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4303                    }
4304                    intents[i] = new Intent(intent);
4305                }
4306            }
4307            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4308                throw new IllegalArgumentException(
4309                        "Intent array length does not match resolvedTypes length");
4310            }
4311        }
4312        if (options != null) {
4313            if (options.hasFileDescriptors()) {
4314                throw new IllegalArgumentException("File descriptors passed in options");
4315            }
4316        }
4317
4318        synchronized(this) {
4319            int callingUid = Binder.getCallingUid();
4320            try {
4321                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4322                    int uid = AppGlobals.getPackageManager()
4323                            .getPackageUid(packageName, UserId.getUserId(callingUid));
4324                    if (!UserId.isSameApp(callingUid, uid)) {
4325                        String msg = "Permission Denial: getIntentSender() from pid="
4326                            + Binder.getCallingPid()
4327                            + ", uid=" + Binder.getCallingUid()
4328                            + ", (need uid=" + uid + ")"
4329                            + " is not allowed to send as package " + packageName;
4330                        Slog.w(TAG, msg);
4331                        throw new SecurityException(msg);
4332                    }
4333                }
4334
4335                if (DEBUG_MU)
4336                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4337                            + Binder.getOrigCallingUid());
4338                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4339                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4340
4341            } catch (RemoteException e) {
4342                throw new SecurityException(e);
4343            }
4344        }
4345    }
4346
4347    IIntentSender getIntentSenderLocked(int type,
4348            String packageName, int callingUid, IBinder token, String resultWho,
4349            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4350            Bundle options) {
4351        if (DEBUG_MU)
4352            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4353        ActivityRecord activity = null;
4354        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4355            activity = mMainStack.isInStackLocked(token);
4356            if (activity == null) {
4357                return null;
4358            }
4359            if (activity.finishing) {
4360                return null;
4361            }
4362        }
4363
4364        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4365        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4366        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4367        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4368                |PendingIntent.FLAG_UPDATE_CURRENT);
4369
4370        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4371                type, packageName, activity, resultWho,
4372                requestCode, intents, resolvedTypes, flags, options);
4373        WeakReference<PendingIntentRecord> ref;
4374        ref = mIntentSenderRecords.get(key);
4375        PendingIntentRecord rec = ref != null ? ref.get() : null;
4376        if (rec != null) {
4377            if (!cancelCurrent) {
4378                if (updateCurrent) {
4379                    if (rec.key.requestIntent != null) {
4380                        rec.key.requestIntent.replaceExtras(intents != null ?
4381                                intents[intents.length - 1] : null);
4382                    }
4383                    if (intents != null) {
4384                        intents[intents.length-1] = rec.key.requestIntent;
4385                        rec.key.allIntents = intents;
4386                        rec.key.allResolvedTypes = resolvedTypes;
4387                    } else {
4388                        rec.key.allIntents = null;
4389                        rec.key.allResolvedTypes = null;
4390                    }
4391                }
4392                return rec;
4393            }
4394            rec.canceled = true;
4395            mIntentSenderRecords.remove(key);
4396        }
4397        if (noCreate) {
4398            return rec;
4399        }
4400        rec = new PendingIntentRecord(this, key, callingUid);
4401        mIntentSenderRecords.put(key, rec.ref);
4402        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4403            if (activity.pendingResults == null) {
4404                activity.pendingResults
4405                        = new HashSet<WeakReference<PendingIntentRecord>>();
4406            }
4407            activity.pendingResults.add(rec.ref);
4408        }
4409        return rec;
4410    }
4411
4412    public void cancelIntentSender(IIntentSender sender) {
4413        if (!(sender instanceof PendingIntentRecord)) {
4414            return;
4415        }
4416        synchronized(this) {
4417            PendingIntentRecord rec = (PendingIntentRecord)sender;
4418            try {
4419                int uid = AppGlobals.getPackageManager()
4420                        .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
4421                if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
4422                    String msg = "Permission Denial: cancelIntentSender() from pid="
4423                        + Binder.getCallingPid()
4424                        + ", uid=" + Binder.getCallingUid()
4425                        + " is not allowed to cancel packges "
4426                        + rec.key.packageName;
4427                    Slog.w(TAG, msg);
4428                    throw new SecurityException(msg);
4429                }
4430            } catch (RemoteException e) {
4431                throw new SecurityException(e);
4432            }
4433            cancelIntentSenderLocked(rec, true);
4434        }
4435    }
4436
4437    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4438        rec.canceled = true;
4439        mIntentSenderRecords.remove(rec.key);
4440        if (cleanActivity && rec.key.activity != null) {
4441            rec.key.activity.pendingResults.remove(rec.ref);
4442        }
4443    }
4444
4445    public String getPackageForIntentSender(IIntentSender pendingResult) {
4446        if (!(pendingResult instanceof PendingIntentRecord)) {
4447            return null;
4448        }
4449        try {
4450            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4451            return res.key.packageName;
4452        } catch (ClassCastException e) {
4453        }
4454        return null;
4455    }
4456
4457    public int getUidForIntentSender(IIntentSender sender) {
4458        if (sender instanceof PendingIntentRecord) {
4459            try {
4460                PendingIntentRecord res = (PendingIntentRecord)sender;
4461                return res.uid;
4462            } catch (ClassCastException e) {
4463            }
4464        }
4465        return -1;
4466    }
4467
4468    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4469        if (!(pendingResult instanceof PendingIntentRecord)) {
4470            return false;
4471        }
4472        try {
4473            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4474            if (res.key.allIntents == null) {
4475                return false;
4476            }
4477            for (int i=0; i<res.key.allIntents.length; i++) {
4478                Intent intent = res.key.allIntents[i];
4479                if (intent.getPackage() != null && intent.getComponent() != null) {
4480                    return false;
4481                }
4482            }
4483            return true;
4484        } catch (ClassCastException e) {
4485        }
4486        return false;
4487    }
4488
4489    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4490        if (!(pendingResult instanceof PendingIntentRecord)) {
4491            return false;
4492        }
4493        try {
4494            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4495            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4496                return true;
4497            }
4498            return false;
4499        } catch (ClassCastException e) {
4500        }
4501        return false;
4502    }
4503
4504    public void setProcessLimit(int max) {
4505        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4506                "setProcessLimit()");
4507        synchronized (this) {
4508            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4509            mProcessLimitOverride = max;
4510        }
4511        trimApplications();
4512    }
4513
4514    public int getProcessLimit() {
4515        synchronized (this) {
4516            return mProcessLimitOverride;
4517        }
4518    }
4519
4520    void foregroundTokenDied(ForegroundToken token) {
4521        synchronized (ActivityManagerService.this) {
4522            synchronized (mPidsSelfLocked) {
4523                ForegroundToken cur
4524                    = mForegroundProcesses.get(token.pid);
4525                if (cur != token) {
4526                    return;
4527                }
4528                mForegroundProcesses.remove(token.pid);
4529                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4530                if (pr == null) {
4531                    return;
4532                }
4533                pr.forcingToForeground = null;
4534                pr.foregroundServices = false;
4535            }
4536            updateOomAdjLocked();
4537        }
4538    }
4539
4540    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4541        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4542                "setProcessForeground()");
4543        synchronized(this) {
4544            boolean changed = false;
4545
4546            synchronized (mPidsSelfLocked) {
4547                ProcessRecord pr = mPidsSelfLocked.get(pid);
4548                if (pr == null && isForeground) {
4549                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4550                    return;
4551                }
4552                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4553                if (oldToken != null) {
4554                    oldToken.token.unlinkToDeath(oldToken, 0);
4555                    mForegroundProcesses.remove(pid);
4556                    if (pr != null) {
4557                        pr.forcingToForeground = null;
4558                    }
4559                    changed = true;
4560                }
4561                if (isForeground && token != null) {
4562                    ForegroundToken newToken = new ForegroundToken() {
4563                        public void binderDied() {
4564                            foregroundTokenDied(this);
4565                        }
4566                    };
4567                    newToken.pid = pid;
4568                    newToken.token = token;
4569                    try {
4570                        token.linkToDeath(newToken, 0);
4571                        mForegroundProcesses.put(pid, newToken);
4572                        pr.forcingToForeground = token;
4573                        changed = true;
4574                    } catch (RemoteException e) {
4575                        // If the process died while doing this, we will later
4576                        // do the cleanup with the process death link.
4577                    }
4578                }
4579            }
4580
4581            if (changed) {
4582                updateOomAdjLocked();
4583            }
4584        }
4585    }
4586
4587    // =========================================================
4588    // PERMISSIONS
4589    // =========================================================
4590
4591    static class PermissionController extends IPermissionController.Stub {
4592        ActivityManagerService mActivityManagerService;
4593        PermissionController(ActivityManagerService activityManagerService) {
4594            mActivityManagerService = activityManagerService;
4595        }
4596
4597        public boolean checkPermission(String permission, int pid, int uid) {
4598            return mActivityManagerService.checkPermission(permission, pid,
4599                    uid) == PackageManager.PERMISSION_GRANTED;
4600        }
4601    }
4602
4603    /**
4604     * This can be called with or without the global lock held.
4605     */
4606    int checkComponentPermission(String permission, int pid, int uid,
4607            int owningUid, boolean exported) {
4608        // We might be performing an operation on behalf of an indirect binder
4609        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4610        // client identity accordingly before proceeding.
4611        Identity tlsIdentity = sCallerIdentity.get();
4612        if (tlsIdentity != null) {
4613            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4614                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4615            uid = tlsIdentity.uid;
4616            pid = tlsIdentity.pid;
4617        }
4618
4619        if (pid == MY_PID) {
4620            return PackageManager.PERMISSION_GRANTED;
4621        }
4622
4623        return ActivityManager.checkComponentPermission(permission, uid,
4624                owningUid, exported);
4625    }
4626
4627    /**
4628     * As the only public entry point for permissions checking, this method
4629     * can enforce the semantic that requesting a check on a null global
4630     * permission is automatically denied.  (Internally a null permission
4631     * string is used when calling {@link #checkComponentPermission} in cases
4632     * when only uid-based security is needed.)
4633     *
4634     * This can be called with or without the global lock held.
4635     */
4636    public int checkPermission(String permission, int pid, int uid) {
4637        if (permission == null) {
4638            return PackageManager.PERMISSION_DENIED;
4639        }
4640        return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
4641    }
4642
4643    /**
4644     * Binder IPC calls go through the public entry point.
4645     * This can be called with or without the global lock held.
4646     */
4647    int checkCallingPermission(String permission) {
4648        return checkPermission(permission,
4649                Binder.getCallingPid(),
4650                UserId.getAppId(Binder.getCallingUid()));
4651    }
4652
4653    /**
4654     * This can be called with or without the global lock held.
4655     */
4656    void enforceCallingPermission(String permission, String func) {
4657        if (checkCallingPermission(permission)
4658                == PackageManager.PERMISSION_GRANTED) {
4659            return;
4660        }
4661
4662        String msg = "Permission Denial: " + func + " from pid="
4663                + Binder.getCallingPid()
4664                + ", uid=" + Binder.getCallingUid()
4665                + " requires " + permission;
4666        Slog.w(TAG, msg);
4667        throw new SecurityException(msg);
4668    }
4669
4670    /**
4671     * Determine if UID is holding permissions required to access {@link Uri} in
4672     * the given {@link ProviderInfo}. Final permission checking is always done
4673     * in {@link ContentProvider}.
4674     */
4675    private final boolean checkHoldingPermissionsLocked(
4676            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4677        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4678                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4679
4680        if (pi.applicationInfo.uid == uid) {
4681            return true;
4682        } else if (!pi.exported) {
4683            return false;
4684        }
4685
4686        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4687        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4688        try {
4689            // check if target holds top-level <provider> permissions
4690            if (!readMet && pi.readPermission != null
4691                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4692                readMet = true;
4693            }
4694            if (!writeMet && pi.writePermission != null
4695                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4696                writeMet = true;
4697            }
4698
4699            // track if unprotected read/write is allowed; any denied
4700            // <path-permission> below removes this ability
4701            boolean allowDefaultRead = pi.readPermission == null;
4702            boolean allowDefaultWrite = pi.writePermission == null;
4703
4704            // check if target holds any <path-permission> that match uri
4705            final PathPermission[] pps = pi.pathPermissions;
4706            if (pps != null) {
4707                final String path = uri.getPath();
4708                int i = pps.length;
4709                while (i > 0 && (!readMet || !writeMet)) {
4710                    i--;
4711                    PathPermission pp = pps[i];
4712                    if (pp.match(path)) {
4713                        if (!readMet) {
4714                            final String pprperm = pp.getReadPermission();
4715                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4716                                    + pprperm + " for " + pp.getPath()
4717                                    + ": match=" + pp.match(path)
4718                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4719                            if (pprperm != null) {
4720                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4721                                    readMet = true;
4722                                } else {
4723                                    allowDefaultRead = false;
4724                                }
4725                            }
4726                        }
4727                        if (!writeMet) {
4728                            final String ppwperm = pp.getWritePermission();
4729                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4730                                    + ppwperm + " for " + pp.getPath()
4731                                    + ": match=" + pp.match(path)
4732                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4733                            if (ppwperm != null) {
4734                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4735                                    writeMet = true;
4736                                } else {
4737                                    allowDefaultWrite = false;
4738                                }
4739                            }
4740                        }
4741                    }
4742                }
4743            }
4744
4745            // grant unprotected <provider> read/write, if not blocked by
4746            // <path-permission> above
4747            if (allowDefaultRead) readMet = true;
4748            if (allowDefaultWrite) writeMet = true;
4749
4750        } catch (RemoteException e) {
4751            return false;
4752        }
4753
4754        return readMet && writeMet;
4755    }
4756
4757    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4758            int modeFlags) {
4759        // Root gets to do everything.
4760        if (uid == 0) {
4761            return true;
4762        }
4763        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4764        if (perms == null) return false;
4765        UriPermission perm = perms.get(uri);
4766        if (perm == null) return false;
4767        return (modeFlags&perm.modeFlags) == modeFlags;
4768    }
4769
4770    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4771        enforceNotIsolatedCaller("checkUriPermission");
4772
4773        // Another redirected-binder-call permissions check as in
4774        // {@link checkComponentPermission}.
4775        Identity tlsIdentity = sCallerIdentity.get();
4776        if (tlsIdentity != null) {
4777            uid = tlsIdentity.uid;
4778            pid = tlsIdentity.pid;
4779        }
4780
4781        uid = UserId.getAppId(uid);
4782        // Our own process gets to do everything.
4783        if (pid == MY_PID) {
4784            return PackageManager.PERMISSION_GRANTED;
4785        }
4786        synchronized(this) {
4787            return checkUriPermissionLocked(uri, uid, modeFlags)
4788                    ? PackageManager.PERMISSION_GRANTED
4789                    : PackageManager.PERMISSION_DENIED;
4790        }
4791    }
4792
4793    /**
4794     * Check if the targetPkg can be granted permission to access uri by
4795     * the callingUid using the given modeFlags.  Throws a security exception
4796     * if callingUid is not allowed to do this.  Returns the uid of the target
4797     * if the URI permission grant should be performed; returns -1 if it is not
4798     * needed (for example targetPkg already has permission to access the URI).
4799     * If you already know the uid of the target, you can supply it in
4800     * lastTargetUid else set that to -1.
4801     */
4802    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4803            Uri uri, int modeFlags, int lastTargetUid) {
4804        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4805                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4806        if (modeFlags == 0) {
4807            return -1;
4808        }
4809
4810        if (targetPkg != null) {
4811            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4812                    "Checking grant " + targetPkg + " permission to " + uri);
4813        }
4814
4815        final IPackageManager pm = AppGlobals.getPackageManager();
4816
4817        // If this is not a content: uri, we can't do anything with it.
4818        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4819            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4820                    "Can't grant URI permission for non-content URI: " + uri);
4821            return -1;
4822        }
4823
4824        String name = uri.getAuthority();
4825        ProviderInfo pi = null;
4826        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4827                UserId.getUserId(callingUid));
4828        if (cpr != null) {
4829            pi = cpr.info;
4830        } else {
4831            try {
4832                pi = pm.resolveContentProvider(name,
4833                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
4834            } catch (RemoteException ex) {
4835            }
4836        }
4837        if (pi == null) {
4838            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4839            return -1;
4840        }
4841
4842        int targetUid = lastTargetUid;
4843        if (targetUid < 0 && targetPkg != null) {
4844            try {
4845                targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
4846                if (targetUid < 0) {
4847                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4848                            "Can't grant URI permission no uid for: " + targetPkg);
4849                    return -1;
4850                }
4851            } catch (RemoteException ex) {
4852                return -1;
4853            }
4854        }
4855
4856        if (targetUid >= 0) {
4857            // First...  does the target actually need this permission?
4858            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4859                // No need to grant the target this permission.
4860                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4861                        "Target " + targetPkg + " already has full permission to " + uri);
4862                return -1;
4863            }
4864        } else {
4865            // First...  there is no target package, so can anyone access it?
4866            boolean allowed = pi.exported;
4867            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4868                if (pi.readPermission != null) {
4869                    allowed = false;
4870                }
4871            }
4872            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4873                if (pi.writePermission != null) {
4874                    allowed = false;
4875                }
4876            }
4877            if (allowed) {
4878                return -1;
4879            }
4880        }
4881
4882        // Second...  is the provider allowing granting of URI permissions?
4883        if (!pi.grantUriPermissions) {
4884            throw new SecurityException("Provider " + pi.packageName
4885                    + "/" + pi.name
4886                    + " does not allow granting of Uri permissions (uri "
4887                    + uri + ")");
4888        }
4889        if (pi.uriPermissionPatterns != null) {
4890            final int N = pi.uriPermissionPatterns.length;
4891            boolean allowed = false;
4892            for (int i=0; i<N; i++) {
4893                if (pi.uriPermissionPatterns[i] != null
4894                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4895                    allowed = true;
4896                    break;
4897                }
4898            }
4899            if (!allowed) {
4900                throw new SecurityException("Provider " + pi.packageName
4901                        + "/" + pi.name
4902                        + " does not allow granting of permission to path of Uri "
4903                        + uri);
4904            }
4905        }
4906
4907        // Third...  does the caller itself have permission to access
4908        // this uri?
4909        if (callingUid != Process.myUid()) {
4910            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4911                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4912                    throw new SecurityException("Uid " + callingUid
4913                            + " does not have permission to uri " + uri);
4914                }
4915            }
4916        }
4917
4918        return targetUid;
4919    }
4920
4921    public int checkGrantUriPermission(int callingUid, String targetPkg,
4922            Uri uri, int modeFlags) {
4923        enforceNotIsolatedCaller("checkGrantUriPermission");
4924        synchronized(this) {
4925            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4926        }
4927    }
4928
4929    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4930            Uri uri, int modeFlags, UriPermissionOwner owner) {
4931        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4932                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4933        if (modeFlags == 0) {
4934            return;
4935        }
4936
4937        // So here we are: the caller has the assumed permission
4938        // to the uri, and the target doesn't.  Let's now give this to
4939        // the target.
4940
4941        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4942                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4943
4944        HashMap<Uri, UriPermission> targetUris
4945                = mGrantedUriPermissions.get(targetUid);
4946        if (targetUris == null) {
4947            targetUris = new HashMap<Uri, UriPermission>();
4948            mGrantedUriPermissions.put(targetUid, targetUris);
4949        }
4950
4951        UriPermission perm = targetUris.get(uri);
4952        if (perm == null) {
4953            perm = new UriPermission(targetUid, uri);
4954            targetUris.put(uri, perm);
4955        }
4956
4957        perm.modeFlags |= modeFlags;
4958        if (owner == null) {
4959            perm.globalModeFlags |= modeFlags;
4960        } else {
4961            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4962                 perm.readOwners.add(owner);
4963                 owner.addReadPermission(perm);
4964            }
4965            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4966                 perm.writeOwners.add(owner);
4967                 owner.addWritePermission(perm);
4968            }
4969        }
4970    }
4971
4972    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
4973            int modeFlags, UriPermissionOwner owner) {
4974        if (targetPkg == null) {
4975            throw new NullPointerException("targetPkg");
4976        }
4977
4978        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4979        if (targetUid < 0) {
4980            return;
4981        }
4982
4983        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4984    }
4985
4986    static class NeededUriGrants extends ArrayList<Uri> {
4987        final String targetPkg;
4988        final int targetUid;
4989        final int flags;
4990
4991        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
4992            targetPkg = _targetPkg;
4993            targetUid = _targetUid;
4994            flags = _flags;
4995        }
4996    }
4997
4998    /**
4999     * Like checkGrantUriPermissionLocked, but takes an Intent.
5000     */
5001    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5002            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5003        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5004                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5005                + " clip=" + (intent != null ? intent.getClipData() : null)
5006                + " from " + intent + "; flags=0x"
5007                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5008
5009        if (targetPkg == null) {
5010            throw new NullPointerException("targetPkg");
5011        }
5012
5013        if (intent == null) {
5014            return null;
5015        }
5016        Uri data = intent.getData();
5017        ClipData clip = intent.getClipData();
5018        if (data == null && clip == null) {
5019            return null;
5020        }
5021        if (data != null) {
5022            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5023                mode, needed != null ? needed.targetUid : -1);
5024            if (target > 0) {
5025                if (needed == null) {
5026                    needed = new NeededUriGrants(targetPkg, target, mode);
5027                }
5028                needed.add(data);
5029            }
5030        }
5031        if (clip != null) {
5032            for (int i=0; i<clip.getItemCount(); i++) {
5033                Uri uri = clip.getItemAt(i).getUri();
5034                if (uri != null) {
5035                    int target = -1;
5036                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5037                            mode, needed != null ? needed.targetUid : -1);
5038                    if (target > 0) {
5039                        if (needed == null) {
5040                            needed = new NeededUriGrants(targetPkg, target, mode);
5041                        }
5042                        needed.add(uri);
5043                    }
5044                } else {
5045                    Intent clipIntent = clip.getItemAt(i).getIntent();
5046                    if (clipIntent != null) {
5047                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5048                                callingUid, targetPkg, clipIntent, mode, needed);
5049                        if (newNeeded != null) {
5050                            needed = newNeeded;
5051                        }
5052                    }
5053                }
5054            }
5055        }
5056
5057        return needed;
5058    }
5059
5060    /**
5061     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5062     */
5063    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5064            UriPermissionOwner owner) {
5065        if (needed != null) {
5066            for (int i=0; i<needed.size(); i++) {
5067                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5068                        needed.get(i), needed.flags, owner);
5069            }
5070        }
5071    }
5072
5073    void grantUriPermissionFromIntentLocked(int callingUid,
5074            String targetPkg, Intent intent, UriPermissionOwner owner) {
5075        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5076                intent, intent != null ? intent.getFlags() : 0, null);
5077        if (needed == null) {
5078            return;
5079        }
5080
5081        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5082    }
5083
5084    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5085            Uri uri, int modeFlags) {
5086        enforceNotIsolatedCaller("grantUriPermission");
5087        synchronized(this) {
5088            final ProcessRecord r = getRecordForAppLocked(caller);
5089            if (r == null) {
5090                throw new SecurityException("Unable to find app for caller "
5091                        + caller
5092                        + " when granting permission to uri " + uri);
5093            }
5094            if (targetPkg == null) {
5095                throw new IllegalArgumentException("null target");
5096            }
5097            if (uri == null) {
5098                throw new IllegalArgumentException("null uri");
5099            }
5100
5101            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5102                    null);
5103        }
5104    }
5105
5106    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5107        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5108                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5109            HashMap<Uri, UriPermission> perms
5110                    = mGrantedUriPermissions.get(perm.uid);
5111            if (perms != null) {
5112                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5113                        "Removing " + perm.uid + " permission to " + perm.uri);
5114                perms.remove(perm.uri);
5115                if (perms.size() == 0) {
5116                    mGrantedUriPermissions.remove(perm.uid);
5117                }
5118            }
5119        }
5120    }
5121
5122    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5123            int modeFlags) {
5124        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5125                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5126        if (modeFlags == 0) {
5127            return;
5128        }
5129
5130        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5131                "Revoking all granted permissions to " + uri);
5132
5133        final IPackageManager pm = AppGlobals.getPackageManager();
5134
5135        final String authority = uri.getAuthority();
5136        ProviderInfo pi = null;
5137        int userId = UserId.getUserId(callingUid);
5138        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5139        if (cpr != null) {
5140            pi = cpr.info;
5141        } else {
5142            try {
5143                pi = pm.resolveContentProvider(authority,
5144                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5145            } catch (RemoteException ex) {
5146            }
5147        }
5148        if (pi == null) {
5149            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5150            return;
5151        }
5152
5153        // Does the caller have this permission on the URI?
5154        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5155            // Right now, if you are not the original owner of the permission,
5156            // you are not allowed to revoke it.
5157            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5158                throw new SecurityException("Uid " + callingUid
5159                        + " does not have permission to uri " + uri);
5160            //}
5161        }
5162
5163        // Go through all of the permissions and remove any that match.
5164        final List<String> SEGMENTS = uri.getPathSegments();
5165        if (SEGMENTS != null) {
5166            final int NS = SEGMENTS.size();
5167            int N = mGrantedUriPermissions.size();
5168            for (int i=0; i<N; i++) {
5169                HashMap<Uri, UriPermission> perms
5170                        = mGrantedUriPermissions.valueAt(i);
5171                Iterator<UriPermission> it = perms.values().iterator();
5172            toploop:
5173                while (it.hasNext()) {
5174                    UriPermission perm = it.next();
5175                    Uri targetUri = perm.uri;
5176                    if (!authority.equals(targetUri.getAuthority())) {
5177                        continue;
5178                    }
5179                    List<String> targetSegments = targetUri.getPathSegments();
5180                    if (targetSegments == null) {
5181                        continue;
5182                    }
5183                    if (targetSegments.size() < NS) {
5184                        continue;
5185                    }
5186                    for (int j=0; j<NS; j++) {
5187                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5188                            continue toploop;
5189                        }
5190                    }
5191                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5192                            "Revoking " + perm.uid + " permission to " + perm.uri);
5193                    perm.clearModes(modeFlags);
5194                    if (perm.modeFlags == 0) {
5195                        it.remove();
5196                    }
5197                }
5198                if (perms.size() == 0) {
5199                    mGrantedUriPermissions.remove(
5200                            mGrantedUriPermissions.keyAt(i));
5201                    N--;
5202                    i--;
5203                }
5204            }
5205        }
5206    }
5207
5208    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5209            int modeFlags) {
5210        enforceNotIsolatedCaller("revokeUriPermission");
5211        synchronized(this) {
5212            final ProcessRecord r = getRecordForAppLocked(caller);
5213            if (r == null) {
5214                throw new SecurityException("Unable to find app for caller "
5215                        + caller
5216                        + " when revoking permission to uri " + uri);
5217            }
5218            if (uri == null) {
5219                Slog.w(TAG, "revokeUriPermission: null uri");
5220                return;
5221            }
5222
5223            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5224                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5225            if (modeFlags == 0) {
5226                return;
5227            }
5228
5229            final IPackageManager pm = AppGlobals.getPackageManager();
5230
5231            final String authority = uri.getAuthority();
5232            ProviderInfo pi = null;
5233            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5234            if (cpr != null) {
5235                pi = cpr.info;
5236            } else {
5237                try {
5238                    pi = pm.resolveContentProvider(authority,
5239                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5240                } catch (RemoteException ex) {
5241                }
5242            }
5243            if (pi == null) {
5244                Slog.w(TAG, "No content provider found for permission revoke: "
5245                        + uri.toSafeString());
5246                return;
5247            }
5248
5249            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5250        }
5251    }
5252
5253    @Override
5254    public IBinder newUriPermissionOwner(String name) {
5255        enforceNotIsolatedCaller("newUriPermissionOwner");
5256        synchronized(this) {
5257            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5258            return owner.getExternalTokenLocked();
5259        }
5260    }
5261
5262    @Override
5263    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5264            Uri uri, int modeFlags) {
5265        synchronized(this) {
5266            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5267            if (owner == null) {
5268                throw new IllegalArgumentException("Unknown owner: " + token);
5269            }
5270            if (fromUid != Binder.getCallingUid()) {
5271                if (Binder.getCallingUid() != Process.myUid()) {
5272                    // Only system code can grant URI permissions on behalf
5273                    // of other users.
5274                    throw new SecurityException("nice try");
5275                }
5276            }
5277            if (targetPkg == null) {
5278                throw new IllegalArgumentException("null target");
5279            }
5280            if (uri == null) {
5281                throw new IllegalArgumentException("null uri");
5282            }
5283
5284            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5285        }
5286    }
5287
5288    @Override
5289    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5290        synchronized(this) {
5291            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5292            if (owner == null) {
5293                throw new IllegalArgumentException("Unknown owner: " + token);
5294            }
5295
5296            if (uri == null) {
5297                owner.removeUriPermissionsLocked(mode);
5298            } else {
5299                owner.removeUriPermissionLocked(uri, mode);
5300            }
5301        }
5302    }
5303
5304    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5305        synchronized (this) {
5306            ProcessRecord app =
5307                who != null ? getRecordForAppLocked(who) : null;
5308            if (app == null) return;
5309
5310            Message msg = Message.obtain();
5311            msg.what = WAIT_FOR_DEBUGGER_MSG;
5312            msg.obj = app;
5313            msg.arg1 = waiting ? 1 : 0;
5314            mHandler.sendMessage(msg);
5315        }
5316    }
5317
5318    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5319        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5320        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5321        outInfo.availMem = Process.getFreeMemory();
5322        outInfo.totalMem = Process.getTotalMemory();
5323        outInfo.threshold = homeAppMem;
5324        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5325        outInfo.hiddenAppThreshold = hiddenAppMem;
5326        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5327                ProcessList.SERVICE_ADJ);
5328        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5329                ProcessList.VISIBLE_APP_ADJ);
5330        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5331                ProcessList.FOREGROUND_APP_ADJ);
5332    }
5333
5334    // =========================================================
5335    // TASK MANAGEMENT
5336    // =========================================================
5337
5338    public List getTasks(int maxNum, int flags,
5339                         IThumbnailReceiver receiver) {
5340        ArrayList list = new ArrayList();
5341
5342        PendingThumbnailsRecord pending = null;
5343        IApplicationThread topThumbnail = null;
5344        ActivityRecord topRecord = null;
5345
5346        synchronized(this) {
5347            if (localLOGV) Slog.v(
5348                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5349                + ", receiver=" + receiver);
5350
5351            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5352                    != PackageManager.PERMISSION_GRANTED) {
5353                if (receiver != null) {
5354                    // If the caller wants to wait for pending thumbnails,
5355                    // it ain't gonna get them.
5356                    try {
5357                        receiver.finished();
5358                    } catch (RemoteException ex) {
5359                    }
5360                }
5361                String msg = "Permission Denial: getTasks() from pid="
5362                        + Binder.getCallingPid()
5363                        + ", uid=" + Binder.getCallingUid()
5364                        + " requires " + android.Manifest.permission.GET_TASKS;
5365                Slog.w(TAG, msg);
5366                throw new SecurityException(msg);
5367            }
5368
5369            int pos = mMainStack.mHistory.size()-1;
5370            ActivityRecord next =
5371                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5372            ActivityRecord top = null;
5373            TaskRecord curTask = null;
5374            int numActivities = 0;
5375            int numRunning = 0;
5376            while (pos >= 0 && maxNum > 0) {
5377                final ActivityRecord r = next;
5378                pos--;
5379                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5380
5381                // Initialize state for next task if needed.
5382                if (top == null ||
5383                        (top.state == ActivityState.INITIALIZING
5384                            && top.task == r.task)) {
5385                    top = r;
5386                    curTask = r.task;
5387                    numActivities = numRunning = 0;
5388                }
5389
5390                // Add 'r' into the current task.
5391                numActivities++;
5392                if (r.app != null && r.app.thread != null) {
5393                    numRunning++;
5394                }
5395
5396                if (localLOGV) Slog.v(
5397                    TAG, r.intent.getComponent().flattenToShortString()
5398                    + ": task=" + r.task);
5399
5400                // If the next one is a different task, generate a new
5401                // TaskInfo entry for what we have.
5402                if (next == null || next.task != curTask) {
5403                    ActivityManager.RunningTaskInfo ci
5404                            = new ActivityManager.RunningTaskInfo();
5405                    ci.id = curTask.taskId;
5406                    ci.baseActivity = r.intent.getComponent();
5407                    ci.topActivity = top.intent.getComponent();
5408                    if (top.thumbHolder != null) {
5409                        ci.description = top.thumbHolder.lastDescription;
5410                    }
5411                    ci.numActivities = numActivities;
5412                    ci.numRunning = numRunning;
5413                    //System.out.println(
5414                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5415                    if (ci.thumbnail == null && receiver != null) {
5416                        if (localLOGV) Slog.v(
5417                            TAG, "State=" + top.state + "Idle=" + top.idle
5418                            + " app=" + top.app
5419                            + " thr=" + (top.app != null ? top.app.thread : null));
5420                        if (top.state == ActivityState.RESUMED
5421                                || top.state == ActivityState.PAUSING) {
5422                            if (top.idle && top.app != null
5423                                && top.app.thread != null) {
5424                                topRecord = top;
5425                                topThumbnail = top.app.thread;
5426                            } else {
5427                                top.thumbnailNeeded = true;
5428                            }
5429                        }
5430                        if (pending == null) {
5431                            pending = new PendingThumbnailsRecord(receiver);
5432                        }
5433                        pending.pendingRecords.add(top);
5434                    }
5435                    list.add(ci);
5436                    maxNum--;
5437                    top = null;
5438                }
5439            }
5440
5441            if (pending != null) {
5442                mPendingThumbnails.add(pending);
5443            }
5444        }
5445
5446        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5447
5448        if (topThumbnail != null) {
5449            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5450            try {
5451                topThumbnail.requestThumbnail(topRecord.appToken);
5452            } catch (Exception e) {
5453                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5454                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5455            }
5456        }
5457
5458        if (pending == null && receiver != null) {
5459            // In this case all thumbnails were available and the client
5460            // is being asked to be told when the remaining ones come in...
5461            // which is unusually, since the top-most currently running
5462            // activity should never have a canned thumbnail!  Oh well.
5463            try {
5464                receiver.finished();
5465            } catch (RemoteException ex) {
5466            }
5467        }
5468
5469        return list;
5470    }
5471
5472    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5473            int flags) {
5474        final int callingUid = Binder.getCallingUid();
5475        // If it's the system uid asking, then use the current user id.
5476        // TODO: Make sure that there aren't any other legitimate calls from the system uid that
5477        // require the entire list.
5478        final int callingUserId = callingUid == Process.SYSTEM_UID
5479                ? mCurrentUserId : UserId.getUserId(callingUid);
5480        synchronized (this) {
5481            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5482                    "getRecentTasks()");
5483            final boolean detailed = checkCallingPermission(
5484                    android.Manifest.permission.GET_DETAILED_TASKS)
5485                    == PackageManager.PERMISSION_GRANTED;
5486
5487            IPackageManager pm = AppGlobals.getPackageManager();
5488
5489            final int N = mRecentTasks.size();
5490            ArrayList<ActivityManager.RecentTaskInfo> res
5491                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5492                            maxNum < N ? maxNum : N);
5493            for (int i=0; i<N && maxNum > 0; i++) {
5494                TaskRecord tr = mRecentTasks.get(i);
5495                // Only add calling user's recent tasks
5496                if (tr.userId != callingUserId) continue;
5497                // Return the entry if desired by the caller.  We always return
5498                // the first entry, because callers always expect this to be the
5499                // foreground app.  We may filter others if the caller has
5500                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5501                // we should exclude the entry.
5502
5503                if (i == 0
5504                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5505                        || (tr.intent == null)
5506                        || ((tr.intent.getFlags()
5507                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5508                    ActivityManager.RecentTaskInfo rti
5509                            = new ActivityManager.RecentTaskInfo();
5510                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5511                    rti.persistentId = tr.taskId;
5512                    rti.baseIntent = new Intent(
5513                            tr.intent != null ? tr.intent : tr.affinityIntent);
5514                    if (!detailed) {
5515                        rti.baseIntent.replaceExtras((Bundle)null);
5516                    }
5517                    rti.origActivity = tr.origActivity;
5518                    rti.description = tr.lastDescription;
5519
5520                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5521                        // Check whether this activity is currently available.
5522                        try {
5523                            if (rti.origActivity != null) {
5524                                if (pm.getActivityInfo(rti.origActivity, 0, callingUserId)
5525                                        == null) {
5526                                    continue;
5527                                }
5528                            } else if (rti.baseIntent != null) {
5529                                if (pm.queryIntentActivities(rti.baseIntent,
5530                                        null, 0, callingUserId) == null) {
5531                                    continue;
5532                                }
5533                            }
5534                        } catch (RemoteException e) {
5535                            // Will never happen.
5536                        }
5537                    }
5538
5539                    res.add(rti);
5540                    maxNum--;
5541                }
5542            }
5543            return res;
5544        }
5545    }
5546
5547    private TaskRecord taskForIdLocked(int id) {
5548        final int N = mRecentTasks.size();
5549        for (int i=0; i<N; i++) {
5550            TaskRecord tr = mRecentTasks.get(i);
5551            if (tr.taskId == id) {
5552                return tr;
5553            }
5554        }
5555        return null;
5556    }
5557
5558    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5559        synchronized (this) {
5560            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5561                    "getTaskThumbnails()");
5562            TaskRecord tr = taskForIdLocked(id);
5563            if (tr != null) {
5564                return mMainStack.getTaskThumbnailsLocked(tr);
5565            }
5566        }
5567        return null;
5568    }
5569
5570    public boolean removeSubTask(int taskId, int subTaskIndex) {
5571        synchronized (this) {
5572            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5573                    "removeSubTask()");
5574            long ident = Binder.clearCallingIdentity();
5575            try {
5576                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5577                        true) != null;
5578            } finally {
5579                Binder.restoreCallingIdentity(ident);
5580            }
5581        }
5582    }
5583
5584    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5585        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5586        Intent baseIntent = new Intent(
5587                tr.intent != null ? tr.intent : tr.affinityIntent);
5588        ComponentName component = baseIntent.getComponent();
5589        if (component == null) {
5590            Slog.w(TAG, "Now component for base intent of task: " + tr);
5591            return;
5592        }
5593
5594        // Find any running services associated with this app.
5595        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5596
5597        if (killProcesses) {
5598            // Find any running processes associated with this app.
5599            final String pkg = component.getPackageName();
5600            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5601            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5602            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5603                for (int i=0; i<uids.size(); i++) {
5604                    ProcessRecord proc = uids.valueAt(i);
5605                    if (proc.userId != tr.userId) {
5606                        continue;
5607                    }
5608                    if (!proc.pkgList.contains(pkg)) {
5609                        continue;
5610                    }
5611                    procs.add(proc);
5612                }
5613            }
5614
5615            // Kill the running processes.
5616            for (int i=0; i<procs.size(); i++) {
5617                ProcessRecord pr = procs.get(i);
5618                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5619                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5620                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5621                            pr.processName, pr.setAdj, "remove task");
5622                    pr.killedBackground = true;
5623                    Process.killProcessQuiet(pr.pid);
5624                } else {
5625                    pr.waitingToKill = "remove task";
5626                }
5627            }
5628        }
5629    }
5630
5631    public boolean removeTask(int taskId, int flags) {
5632        synchronized (this) {
5633            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5634                    "removeTask()");
5635            long ident = Binder.clearCallingIdentity();
5636            try {
5637                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5638                        false);
5639                if (r != null) {
5640                    mRecentTasks.remove(r.task);
5641                    cleanUpRemovedTaskLocked(r.task, flags);
5642                    return true;
5643                } else {
5644                    TaskRecord tr = null;
5645                    int i=0;
5646                    while (i < mRecentTasks.size()) {
5647                        TaskRecord t = mRecentTasks.get(i);
5648                        if (t.taskId == taskId) {
5649                            tr = t;
5650                            break;
5651                        }
5652                        i++;
5653                    }
5654                    if (tr != null) {
5655                        if (tr.numActivities <= 0) {
5656                            // Caller is just removing a recent task that is
5657                            // not actively running.  That is easy!
5658                            mRecentTasks.remove(i);
5659                            cleanUpRemovedTaskLocked(tr, flags);
5660                            return true;
5661                        } else {
5662                            Slog.w(TAG, "removeTask: task " + taskId
5663                                    + " does not have activities to remove, "
5664                                    + " but numActivities=" + tr.numActivities
5665                                    + ": " + tr);
5666                        }
5667                    }
5668                }
5669            } finally {
5670                Binder.restoreCallingIdentity(ident);
5671            }
5672        }
5673        return false;
5674    }
5675
5676    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5677        int j;
5678        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5679        TaskRecord jt = startTask;
5680
5681        // First look backwards
5682        for (j=startIndex-1; j>=0; j--) {
5683            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5684            if (r.task != jt) {
5685                jt = r.task;
5686                if (affinity.equals(jt.affinity)) {
5687                    return j;
5688                }
5689            }
5690        }
5691
5692        // Now look forwards
5693        final int N = mMainStack.mHistory.size();
5694        jt = startTask;
5695        for (j=startIndex+1; j<N; j++) {
5696            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5697            if (r.task != jt) {
5698                if (affinity.equals(jt.affinity)) {
5699                    return j;
5700                }
5701                jt = r.task;
5702            }
5703        }
5704
5705        // Might it be at the top?
5706        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5707            return N-1;
5708        }
5709
5710        return -1;
5711    }
5712
5713    /**
5714     * TODO: Add mController hook
5715     */
5716    public void moveTaskToFront(int task, int flags, Bundle options) {
5717        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5718                "moveTaskToFront()");
5719
5720        synchronized(this) {
5721            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5722                    Binder.getCallingUid(), "Task to front")) {
5723                ActivityOptions.abort(options);
5724                return;
5725            }
5726            final long origId = Binder.clearCallingIdentity();
5727            try {
5728                TaskRecord tr = taskForIdLocked(task);
5729                if (tr != null) {
5730                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5731                        mMainStack.mUserLeaving = true;
5732                    }
5733                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5734                        // Caller wants the home activity moved with it.  To accomplish this,
5735                        // we'll just move the home task to the top first.
5736                        mMainStack.moveHomeToFrontLocked();
5737                    }
5738                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5739                    return;
5740                }
5741                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5742                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5743                    if (hr.task.taskId == task) {
5744                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5745                            mMainStack.mUserLeaving = true;
5746                        }
5747                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5748                            // Caller wants the home activity moved with it.  To accomplish this,
5749                            // we'll just move the home task to the top first.
5750                            mMainStack.moveHomeToFrontLocked();
5751                        }
5752                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5753                        return;
5754                    }
5755                }
5756            } finally {
5757                Binder.restoreCallingIdentity(origId);
5758            }
5759            ActivityOptions.abort(options);
5760        }
5761    }
5762
5763    public void moveTaskToBack(int task) {
5764        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5765                "moveTaskToBack()");
5766
5767        synchronized(this) {
5768            if (mMainStack.mResumedActivity != null
5769                    && mMainStack.mResumedActivity.task.taskId == task) {
5770                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5771                        Binder.getCallingUid(), "Task to back")) {
5772                    return;
5773                }
5774            }
5775            final long origId = Binder.clearCallingIdentity();
5776            mMainStack.moveTaskToBackLocked(task, null);
5777            Binder.restoreCallingIdentity(origId);
5778        }
5779    }
5780
5781    /**
5782     * Moves an activity, and all of the other activities within the same task, to the bottom
5783     * of the history stack.  The activity's order within the task is unchanged.
5784     *
5785     * @param token A reference to the activity we wish to move
5786     * @param nonRoot If false then this only works if the activity is the root
5787     *                of a task; if true it will work for any activity in a task.
5788     * @return Returns true if the move completed, false if not.
5789     */
5790    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5791        enforceNotIsolatedCaller("moveActivityTaskToBack");
5792        synchronized(this) {
5793            final long origId = Binder.clearCallingIdentity();
5794            int taskId = getTaskForActivityLocked(token, !nonRoot);
5795            if (taskId >= 0) {
5796                return mMainStack.moveTaskToBackLocked(taskId, null);
5797            }
5798            Binder.restoreCallingIdentity(origId);
5799        }
5800        return false;
5801    }
5802
5803    public void moveTaskBackwards(int task) {
5804        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5805                "moveTaskBackwards()");
5806
5807        synchronized(this) {
5808            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5809                    Binder.getCallingUid(), "Task backwards")) {
5810                return;
5811            }
5812            final long origId = Binder.clearCallingIdentity();
5813            moveTaskBackwardsLocked(task);
5814            Binder.restoreCallingIdentity(origId);
5815        }
5816    }
5817
5818    private final void moveTaskBackwardsLocked(int task) {
5819        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5820    }
5821
5822    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5823        synchronized(this) {
5824            return getTaskForActivityLocked(token, onlyRoot);
5825        }
5826    }
5827
5828    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5829        final int N = mMainStack.mHistory.size();
5830        TaskRecord lastTask = null;
5831        for (int i=0; i<N; i++) {
5832            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5833            if (r.appToken == token) {
5834                if (!onlyRoot || lastTask != r.task) {
5835                    return r.task.taskId;
5836                }
5837                return -1;
5838            }
5839            lastTask = r.task;
5840        }
5841
5842        return -1;
5843    }
5844
5845    // =========================================================
5846    // THUMBNAILS
5847    // =========================================================
5848
5849    public void reportThumbnail(IBinder token,
5850            Bitmap thumbnail, CharSequence description) {
5851        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5852        final long origId = Binder.clearCallingIdentity();
5853        sendPendingThumbnail(null, token, thumbnail, description, true);
5854        Binder.restoreCallingIdentity(origId);
5855    }
5856
5857    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5858            Bitmap thumbnail, CharSequence description, boolean always) {
5859        TaskRecord task = null;
5860        ArrayList receivers = null;
5861
5862        //System.out.println("Send pending thumbnail: " + r);
5863
5864        synchronized(this) {
5865            if (r == null) {
5866                r = mMainStack.isInStackLocked(token);
5867                if (r == null) {
5868                    return;
5869                }
5870            }
5871            if (thumbnail == null && r.thumbHolder != null) {
5872                thumbnail = r.thumbHolder.lastThumbnail;
5873                description = r.thumbHolder.lastDescription;
5874            }
5875            if (thumbnail == null && !always) {
5876                // If there is no thumbnail, and this entry is not actually
5877                // going away, then abort for now and pick up the next
5878                // thumbnail we get.
5879                return;
5880            }
5881            task = r.task;
5882
5883            int N = mPendingThumbnails.size();
5884            int i=0;
5885            while (i<N) {
5886                PendingThumbnailsRecord pr =
5887                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5888                //System.out.println("Looking in " + pr.pendingRecords);
5889                if (pr.pendingRecords.remove(r)) {
5890                    if (receivers == null) {
5891                        receivers = new ArrayList();
5892                    }
5893                    receivers.add(pr);
5894                    if (pr.pendingRecords.size() == 0) {
5895                        pr.finished = true;
5896                        mPendingThumbnails.remove(i);
5897                        N--;
5898                        continue;
5899                    }
5900                }
5901                i++;
5902            }
5903        }
5904
5905        if (receivers != null) {
5906            final int N = receivers.size();
5907            for (int i=0; i<N; i++) {
5908                try {
5909                    PendingThumbnailsRecord pr =
5910                        (PendingThumbnailsRecord)receivers.get(i);
5911                    pr.receiver.newThumbnail(
5912                        task != null ? task.taskId : -1, thumbnail, description);
5913                    if (pr.finished) {
5914                        pr.receiver.finished();
5915                    }
5916                } catch (Exception e) {
5917                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5918                }
5919            }
5920        }
5921    }
5922
5923    // =========================================================
5924    // CONTENT PROVIDERS
5925    // =========================================================
5926
5927    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5928        List<ProviderInfo> providers = null;
5929        try {
5930            providers = AppGlobals.getPackageManager().
5931                queryContentProviders(app.processName, app.uid,
5932                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5933        } catch (RemoteException ex) {
5934        }
5935        if (DEBUG_MU)
5936            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
5937        int userId = app.userId;
5938        if (providers != null) {
5939            int N = providers.size();
5940            for (int i=0; i<N; i++) {
5941                ProviderInfo cpi =
5942                    (ProviderInfo)providers.get(i);
5943                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
5944                        cpi.name, cpi.flags);
5945                if (singleton && UserId.getUserId(app.uid) != 0) {
5946                    // This is a singleton provider, but a user besides the
5947                    // default user is asking to initialize a process it runs
5948                    // in...  well, no, it doesn't actually run in this process,
5949                    // it runs in the process of the default user.  Get rid of it.
5950                    providers.remove(i);
5951                    N--;
5952                    continue;
5953                }
5954
5955                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5956                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
5957                if (cpr == null) {
5958                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
5959                    mProviderMap.putProviderByClass(comp, cpr);
5960                }
5961                if (DEBUG_MU)
5962                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
5963                app.pubProviders.put(cpi.name, cpr);
5964                app.addPackage(cpi.applicationInfo.packageName);
5965                ensurePackageDexOpt(cpi.applicationInfo.packageName);
5966            }
5967        }
5968        return providers;
5969    }
5970
5971    /**
5972     * Check if {@link ProcessRecord} has a possible chance at accessing the
5973     * given {@link ProviderInfo}. Final permission checking is always done
5974     * in {@link ContentProvider}.
5975     */
5976    private final String checkContentProviderPermissionLocked(
5977            ProviderInfo cpi, ProcessRecord r) {
5978        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5979        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
5980        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
5981                cpi.applicationInfo.uid, cpi.exported)
5982                == PackageManager.PERMISSION_GRANTED) {
5983            return null;
5984        }
5985        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
5986                cpi.applicationInfo.uid, cpi.exported)
5987                == PackageManager.PERMISSION_GRANTED) {
5988            return null;
5989        }
5990
5991        PathPermission[] pps = cpi.pathPermissions;
5992        if (pps != null) {
5993            int i = pps.length;
5994            while (i > 0) {
5995                i--;
5996                PathPermission pp = pps[i];
5997                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
5998                        cpi.applicationInfo.uid, cpi.exported)
5999                        == PackageManager.PERMISSION_GRANTED) {
6000                    return null;
6001                }
6002                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6003                        cpi.applicationInfo.uid, cpi.exported)
6004                        == PackageManager.PERMISSION_GRANTED) {
6005                    return null;
6006                }
6007            }
6008        }
6009
6010        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6011        if (perms != null) {
6012            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6013                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6014                    return null;
6015                }
6016            }
6017        }
6018
6019        String msg;
6020        if (!cpi.exported) {
6021            msg = "Permission Denial: opening provider " + cpi.name
6022                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6023                    + ", uid=" + callingUid + ") that is not exported from uid "
6024                    + cpi.applicationInfo.uid;
6025        } else {
6026            msg = "Permission Denial: opening provider " + cpi.name
6027                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6028                    + ", uid=" + callingUid + ") requires "
6029                    + cpi.readPermission + " or " + cpi.writePermission;
6030        }
6031        Slog.w(TAG, msg);
6032        return msg;
6033    }
6034
6035    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6036            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6037        if (r != null) {
6038            for (int i=0; i<r.conProviders.size(); i++) {
6039                ContentProviderConnection conn = r.conProviders.get(i);
6040                if (conn.provider == cpr) {
6041                    if (DEBUG_PROVIDER) Slog.v(TAG,
6042                            "Adding provider requested by "
6043                            + r.processName + " from process "
6044                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6045                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6046                    if (stable) {
6047                        conn.stableCount++;
6048                        conn.numStableIncs++;
6049                    } else {
6050                        conn.unstableCount++;
6051                        conn.numUnstableIncs++;
6052                    }
6053                    return conn;
6054                }
6055            }
6056            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6057            if (stable) {
6058                conn.stableCount = 1;
6059                conn.numStableIncs = 1;
6060            } else {
6061                conn.unstableCount = 1;
6062                conn.numUnstableIncs = 1;
6063            }
6064            cpr.connections.add(conn);
6065            r.conProviders.add(conn);
6066            return conn;
6067        }
6068        cpr.addExternalProcessHandleLocked(externalProcessToken);
6069        return null;
6070    }
6071
6072    boolean decProviderCountLocked(ContentProviderConnection conn,
6073            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6074        if (conn != null) {
6075            cpr = conn.provider;
6076            if (DEBUG_PROVIDER) Slog.v(TAG,
6077                    "Removing provider requested by "
6078                    + conn.client.processName + " from process "
6079                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6080                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6081            if (stable) {
6082                conn.stableCount--;
6083            } else {
6084                conn.unstableCount--;
6085            }
6086            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6087                cpr.connections.remove(conn);
6088                conn.client.conProviders.remove(conn);
6089                return true;
6090            }
6091            return false;
6092        }
6093        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6094        return false;
6095    }
6096
6097    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6098            String name, IBinder token, boolean stable) {
6099        ContentProviderRecord cpr;
6100        ContentProviderConnection conn = null;
6101        ProviderInfo cpi = null;
6102
6103        synchronized(this) {
6104            ProcessRecord r = null;
6105            if (caller != null) {
6106                r = getRecordForAppLocked(caller);
6107                if (r == null) {
6108                    throw new SecurityException(
6109                            "Unable to find app for caller " + caller
6110                          + " (pid=" + Binder.getCallingPid()
6111                          + ") when getting content provider " + name);
6112                }
6113            }
6114
6115            // First check if this content provider has been published...
6116            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6117            cpr = mProviderMap.getProviderByName(name, userId);
6118            boolean providerRunning = cpr != null;
6119            if (providerRunning) {
6120                cpi = cpr.info;
6121                String msg;
6122                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6123                    throw new SecurityException(msg);
6124                }
6125
6126                if (r != null && cpr.canRunHere(r)) {
6127                    // This provider has been published or is in the process
6128                    // of being published...  but it is also allowed to run
6129                    // in the caller's process, so don't make a connection
6130                    // and just let the caller instantiate its own instance.
6131                    ContentProviderHolder holder = cpr.newHolder(null);
6132                    // don't give caller the provider object, it needs
6133                    // to make its own.
6134                    holder.provider = null;
6135                    return holder;
6136                }
6137
6138                final long origId = Binder.clearCallingIdentity();
6139
6140                // In this case the provider instance already exists, so we can
6141                // return it right away.
6142                conn = incProviderCountLocked(r, cpr, token, stable);
6143                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6144                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6145                        // If this is a perceptible app accessing the provider,
6146                        // make sure to count it as being accessed and thus
6147                        // back up on the LRU list.  This is good because
6148                        // content providers are often expensive to start.
6149                        updateLruProcessLocked(cpr.proc, false, true);
6150                    }
6151                }
6152
6153                if (cpr.proc != null) {
6154                    if (false) {
6155                        if (cpr.name.flattenToShortString().equals(
6156                                "com.android.providers.calendar/.CalendarProvider2")) {
6157                            Slog.v(TAG, "****************** KILLING "
6158                                + cpr.name.flattenToShortString());
6159                            Process.killProcess(cpr.proc.pid);
6160                        }
6161                    }
6162                    boolean success = updateOomAdjLocked(cpr.proc);
6163                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6164                    // NOTE: there is still a race here where a signal could be
6165                    // pending on the process even though we managed to update its
6166                    // adj level.  Not sure what to do about this, but at least
6167                    // the race is now smaller.
6168                    if (!success) {
6169                        // Uh oh...  it looks like the provider's process
6170                        // has been killed on us.  We need to wait for a new
6171                        // process to be started, and make sure its death
6172                        // doesn't kill our process.
6173                        Slog.i(TAG,
6174                                "Existing provider " + cpr.name.flattenToShortString()
6175                                + " is crashing; detaching " + r);
6176                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6177                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6178                        if (!lastRef) {
6179                            // This wasn't the last ref our process had on
6180                            // the provider...  we have now been killed, bail.
6181                            return null;
6182                        }
6183                        providerRunning = false;
6184                        conn = null;
6185                    }
6186                }
6187
6188                Binder.restoreCallingIdentity(origId);
6189            }
6190
6191            boolean singleton;
6192            if (!providerRunning) {
6193                try {
6194                    cpi = AppGlobals.getPackageManager().
6195                        resolveContentProvider(name,
6196                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6197                } catch (RemoteException ex) {
6198                }
6199                if (cpi == null) {
6200                    return null;
6201                }
6202                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6203                        cpi.name, cpi.flags);
6204                if (singleton) {
6205                    userId = 0;
6206                }
6207                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6208
6209                String msg;
6210                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6211                    throw new SecurityException(msg);
6212                }
6213
6214                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6215                        && !cpi.processName.equals("system")) {
6216                    // If this content provider does not run in the system
6217                    // process, and the system is not yet ready to run other
6218                    // processes, then fail fast instead of hanging.
6219                    throw new IllegalArgumentException(
6220                            "Attempt to launch content provider before system ready");
6221                }
6222
6223                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6224                cpr = mProviderMap.getProviderByClass(comp, userId);
6225                final boolean firstClass = cpr == null;
6226                if (firstClass) {
6227                    try {
6228                        ApplicationInfo ai =
6229                            AppGlobals.getPackageManager().
6230                                getApplicationInfo(
6231                                        cpi.applicationInfo.packageName,
6232                                        STOCK_PM_FLAGS, userId);
6233                        if (ai == null) {
6234                            Slog.w(TAG, "No package info for content provider "
6235                                    + cpi.name);
6236                            return null;
6237                        }
6238                        ai = getAppInfoForUser(ai, userId);
6239                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6240                    } catch (RemoteException ex) {
6241                        // pm is in same process, this will never happen.
6242                    }
6243                }
6244
6245                if (r != null && cpr.canRunHere(r)) {
6246                    // If this is a multiprocess provider, then just return its
6247                    // info and allow the caller to instantiate it.  Only do
6248                    // this if the provider is the same user as the caller's
6249                    // process, or can run as root (so can be in any process).
6250                    return cpr.newHolder(null);
6251                }
6252
6253                if (DEBUG_PROVIDER) {
6254                    RuntimeException e = new RuntimeException("here");
6255                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6256                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6257                }
6258
6259                // This is single process, and our app is now connecting to it.
6260                // See if we are already in the process of launching this
6261                // provider.
6262                final int N = mLaunchingProviders.size();
6263                int i;
6264                for (i=0; i<N; i++) {
6265                    if (mLaunchingProviders.get(i) == cpr) {
6266                        break;
6267                    }
6268                }
6269
6270                // If the provider is not already being launched, then get it
6271                // started.
6272                if (i >= N) {
6273                    final long origId = Binder.clearCallingIdentity();
6274
6275                    try {
6276                        // Content provider is now in use, its package can't be stopped.
6277                        try {
6278                            AppGlobals.getPackageManager().setPackageStoppedState(
6279                                    cpr.appInfo.packageName, false, userId);
6280                        } catch (RemoteException e) {
6281                        } catch (IllegalArgumentException e) {
6282                            Slog.w(TAG, "Failed trying to unstop package "
6283                                    + cpr.appInfo.packageName + ": " + e);
6284                        }
6285
6286                        ProcessRecord proc = startProcessLocked(cpi.processName,
6287                                cpr.appInfo, false, 0, "content provider",
6288                                new ComponentName(cpi.applicationInfo.packageName,
6289                                        cpi.name), false, false);
6290                        if (proc == null) {
6291                            Slog.w(TAG, "Unable to launch app "
6292                                    + cpi.applicationInfo.packageName + "/"
6293                                    + cpi.applicationInfo.uid + " for provider "
6294                                    + name + ": process is bad");
6295                            return null;
6296                        }
6297                        cpr.launchingApp = proc;
6298                        mLaunchingProviders.add(cpr);
6299                    } finally {
6300                        Binder.restoreCallingIdentity(origId);
6301                    }
6302                }
6303
6304                // Make sure the provider is published (the same provider class
6305                // may be published under multiple names).
6306                if (firstClass) {
6307                    mProviderMap.putProviderByClass(comp, cpr);
6308                }
6309
6310                mProviderMap.putProviderByName(name, cpr);
6311                conn = incProviderCountLocked(r, cpr, token, stable);
6312                if (conn != null) {
6313                    conn.waiting = true;
6314                }
6315            }
6316        }
6317
6318        // Wait for the provider to be published...
6319        synchronized (cpr) {
6320            while (cpr.provider == null) {
6321                if (cpr.launchingApp == null) {
6322                    Slog.w(TAG, "Unable to launch app "
6323                            + cpi.applicationInfo.packageName + "/"
6324                            + cpi.applicationInfo.uid + " for provider "
6325                            + name + ": launching app became null");
6326                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6327                            cpi.applicationInfo.packageName,
6328                            cpi.applicationInfo.uid, name);
6329                    return null;
6330                }
6331                try {
6332                    if (DEBUG_MU) {
6333                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6334                                + cpr.launchingApp);
6335                    }
6336                    if (conn != null) {
6337                        conn.waiting = true;
6338                    }
6339                    cpr.wait();
6340                } catch (InterruptedException ex) {
6341                } finally {
6342                    if (conn != null) {
6343                        conn.waiting = false;
6344                    }
6345                }
6346            }
6347        }
6348        return cpr != null ? cpr.newHolder(conn) : null;
6349    }
6350
6351    public final ContentProviderHolder getContentProvider(
6352            IApplicationThread caller, String name, boolean stable) {
6353        enforceNotIsolatedCaller("getContentProvider");
6354        if (caller == null) {
6355            String msg = "null IApplicationThread when getting content provider "
6356                    + name;
6357            Slog.w(TAG, msg);
6358            throw new SecurityException(msg);
6359        }
6360
6361        return getContentProviderImpl(caller, name, null, stable);
6362    }
6363
6364    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6365        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6366            "Do not have permission in call getContentProviderExternal()");
6367        return getContentProviderExternalUnchecked(name, token);
6368    }
6369
6370    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6371        return getContentProviderImpl(null, name, token, true);
6372    }
6373
6374    /**
6375     * Drop a content provider from a ProcessRecord's bookkeeping
6376     * @param cpr
6377     */
6378    public void removeContentProvider(IBinder connection, boolean stable) {
6379        enforceNotIsolatedCaller("removeContentProvider");
6380        synchronized (this) {
6381            ContentProviderConnection conn;
6382            try {
6383                conn = (ContentProviderConnection)connection;
6384            } catch (ClassCastException e) {
6385                String msg ="removeContentProvider: " + connection
6386                        + " not a ContentProviderConnection";
6387                Slog.w(TAG, msg);
6388                throw new IllegalArgumentException(msg);
6389            }
6390            if (conn == null) {
6391                throw new NullPointerException("connection is null");
6392            }
6393            if (decProviderCountLocked(conn, null, null, stable)) {
6394                updateOomAdjLocked();
6395            }
6396        }
6397    }
6398
6399    public void removeContentProviderExternal(String name, IBinder token) {
6400        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6401            "Do not have permission in call removeContentProviderExternal()");
6402        removeContentProviderExternalUnchecked(name, token);
6403    }
6404
6405    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6406        synchronized (this) {
6407            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6408                    Binder.getOrigCallingUser());
6409            if(cpr == null) {
6410                //remove from mProvidersByClass
6411                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6412                return;
6413            }
6414
6415            //update content provider record entry info
6416            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6417            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6418                    Binder.getOrigCallingUser());
6419            if (localCpr.hasExternalProcessHandles()) {
6420                if (localCpr.removeExternalProcessHandleLocked(token)) {
6421                    updateOomAdjLocked();
6422                } else {
6423                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6424                            + " with no external reference for token: "
6425                            + token + ".");
6426                }
6427            } else {
6428                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6429                        + " with no external references.");
6430            }
6431        }
6432    }
6433
6434    public final void publishContentProviders(IApplicationThread caller,
6435            List<ContentProviderHolder> providers) {
6436        if (providers == null) {
6437            return;
6438        }
6439
6440        enforceNotIsolatedCaller("publishContentProviders");
6441        synchronized (this) {
6442            final ProcessRecord r = getRecordForAppLocked(caller);
6443            if (DEBUG_MU)
6444                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6445            if (r == null) {
6446                throw new SecurityException(
6447                        "Unable to find app for caller " + caller
6448                      + " (pid=" + Binder.getCallingPid()
6449                      + ") when publishing content providers");
6450            }
6451
6452            final long origId = Binder.clearCallingIdentity();
6453
6454            final int N = providers.size();
6455            for (int i=0; i<N; i++) {
6456                ContentProviderHolder src = providers.get(i);
6457                if (src == null || src.info == null || src.provider == null) {
6458                    continue;
6459                }
6460                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6461                if (DEBUG_MU)
6462                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6463                if (dst != null) {
6464                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6465                    mProviderMap.putProviderByClass(comp, dst);
6466                    String names[] = dst.info.authority.split(";");
6467                    for (int j = 0; j < names.length; j++) {
6468                        mProviderMap.putProviderByName(names[j], dst);
6469                    }
6470
6471                    int NL = mLaunchingProviders.size();
6472                    int j;
6473                    for (j=0; j<NL; j++) {
6474                        if (mLaunchingProviders.get(j) == dst) {
6475                            mLaunchingProviders.remove(j);
6476                            j--;
6477                            NL--;
6478                        }
6479                    }
6480                    synchronized (dst) {
6481                        dst.provider = src.provider;
6482                        dst.proc = r;
6483                        dst.notifyAll();
6484                    }
6485                    updateOomAdjLocked(r);
6486                }
6487            }
6488
6489            Binder.restoreCallingIdentity(origId);
6490        }
6491    }
6492
6493    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6494        ContentProviderConnection conn;
6495        try {
6496            conn = (ContentProviderConnection)connection;
6497        } catch (ClassCastException e) {
6498            String msg ="refContentProvider: " + connection
6499                    + " not a ContentProviderConnection";
6500            Slog.w(TAG, msg);
6501            throw new IllegalArgumentException(msg);
6502        }
6503        if (conn == null) {
6504            throw new NullPointerException("connection is null");
6505        }
6506
6507        synchronized (this) {
6508            if (stable > 0) {
6509                conn.numStableIncs += stable;
6510            }
6511            stable = conn.stableCount + stable;
6512            if (stable < 0) {
6513                throw new IllegalStateException("stableCount < 0: " + stable);
6514            }
6515
6516            if (unstable > 0) {
6517                conn.numUnstableIncs += unstable;
6518            }
6519            unstable = conn.unstableCount + unstable;
6520            if (unstable < 0) {
6521                throw new IllegalStateException("unstableCount < 0: " + unstable);
6522            }
6523
6524            if ((stable+unstable) <= 0) {
6525                throw new IllegalStateException("ref counts can't go to zero here: stable="
6526                        + stable + " unstable=" + unstable);
6527            }
6528            conn.stableCount = stable;
6529            conn.unstableCount = unstable;
6530            return !conn.dead;
6531        }
6532    }
6533
6534    public void unstableProviderDied(IBinder connection) {
6535        ContentProviderConnection conn;
6536        try {
6537            conn = (ContentProviderConnection)connection;
6538        } catch (ClassCastException e) {
6539            String msg ="refContentProvider: " + connection
6540                    + " not a ContentProviderConnection";
6541            Slog.w(TAG, msg);
6542            throw new IllegalArgumentException(msg);
6543        }
6544        if (conn == null) {
6545            throw new NullPointerException("connection is null");
6546        }
6547
6548        // Safely retrieve the content provider associated with the connection.
6549        IContentProvider provider;
6550        synchronized (this) {
6551            provider = conn.provider.provider;
6552        }
6553
6554        if (provider == null) {
6555            // Um, yeah, we're way ahead of you.
6556            return;
6557        }
6558
6559        // Make sure the caller is being honest with us.
6560        if (provider.asBinder().pingBinder()) {
6561            // Er, no, still looks good to us.
6562            synchronized (this) {
6563                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6564                        + " says " + conn + " died, but we don't agree");
6565                return;
6566            }
6567        }
6568
6569        // Well look at that!  It's dead!
6570        synchronized (this) {
6571            if (conn.provider.provider != provider) {
6572                // But something changed...  good enough.
6573                return;
6574            }
6575
6576            ProcessRecord proc = conn.provider.proc;
6577            if (proc == null || proc.thread == null) {
6578                // Seems like the process is already cleaned up.
6579                return;
6580            }
6581
6582            // As far as we're concerned, this is just like receiving a
6583            // death notification...  just a bit prematurely.
6584            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6585                    + ") early provider death");
6586            final long ident = Binder.clearCallingIdentity();
6587            try {
6588                appDiedLocked(proc, proc.pid, proc.thread);
6589            } finally {
6590                Binder.restoreCallingIdentity(ident);
6591            }
6592        }
6593    }
6594
6595    public static final void installSystemProviders() {
6596        List<ProviderInfo> providers;
6597        synchronized (mSelf) {
6598            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6599            providers = mSelf.generateApplicationProvidersLocked(app);
6600            if (providers != null) {
6601                for (int i=providers.size()-1; i>=0; i--) {
6602                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6603                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6604                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6605                                + ": not system .apk");
6606                        providers.remove(i);
6607                    }
6608                }
6609            }
6610        }
6611        if (providers != null) {
6612            mSystemThread.installSystemProviders(providers);
6613        }
6614
6615        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6616
6617        mSelf.mUsageStatsService.monitorPackages();
6618    }
6619
6620    /**
6621     * Allows app to retrieve the MIME type of a URI without having permission
6622     * to access its content provider.
6623     *
6624     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6625     *
6626     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6627     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6628     */
6629    public String getProviderMimeType(Uri uri) {
6630        enforceNotIsolatedCaller("getProviderMimeType");
6631        final String name = uri.getAuthority();
6632        final long ident = Binder.clearCallingIdentity();
6633        ContentProviderHolder holder = null;
6634
6635        try {
6636            holder = getContentProviderExternalUnchecked(name, null);
6637            if (holder != null) {
6638                return holder.provider.getType(uri);
6639            }
6640        } catch (RemoteException e) {
6641            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6642            return null;
6643        } finally {
6644            if (holder != null) {
6645                removeContentProviderExternalUnchecked(name, null);
6646            }
6647            Binder.restoreCallingIdentity(ident);
6648        }
6649
6650        return null;
6651    }
6652
6653    // =========================================================
6654    // GLOBAL MANAGEMENT
6655    // =========================================================
6656
6657    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6658            ApplicationInfo info, String customProcess, boolean isolated) {
6659        String proc = customProcess != null ? customProcess : info.processName;
6660        BatteryStatsImpl.Uid.Proc ps = null;
6661        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6662        int uid = info.uid;
6663        if (isolated) {
6664            int userId = UserId.getUserId(uid);
6665            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6666            uid = 0;
6667            while (true) {
6668                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6669                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6670                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6671                }
6672                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6673                mNextIsolatedProcessUid++;
6674                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6675                    // No process for this uid, use it.
6676                    break;
6677                }
6678                stepsLeft--;
6679                if (stepsLeft <= 0) {
6680                    return null;
6681                }
6682            }
6683        }
6684        synchronized (stats) {
6685            ps = stats.getProcessStatsLocked(info.uid, proc);
6686        }
6687        return new ProcessRecord(ps, thread, info, proc, uid);
6688    }
6689
6690    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6691        ProcessRecord app;
6692        if (!isolated) {
6693            app = getProcessRecordLocked(info.processName, info.uid);
6694        } else {
6695            app = null;
6696        }
6697
6698        if (app == null) {
6699            app = newProcessRecordLocked(null, info, null, isolated);
6700            mProcessNames.put(info.processName, app.uid, app);
6701            if (isolated) {
6702                mIsolatedProcesses.put(app.uid, app);
6703            }
6704            updateLruProcessLocked(app, true, true);
6705        }
6706
6707        // This package really, really can not be stopped.
6708        try {
6709            AppGlobals.getPackageManager().setPackageStoppedState(
6710                    info.packageName, false, UserId.getUserId(app.uid));
6711        } catch (RemoteException e) {
6712        } catch (IllegalArgumentException e) {
6713            Slog.w(TAG, "Failed trying to unstop package "
6714                    + info.packageName + ": " + e);
6715        }
6716
6717        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6718                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6719            app.persistent = true;
6720            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6721        }
6722        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6723            mPersistentStartingProcesses.add(app);
6724            startProcessLocked(app, "added application", app.processName);
6725        }
6726
6727        return app;
6728    }
6729
6730    public void unhandledBack() {
6731        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6732                "unhandledBack()");
6733
6734        synchronized(this) {
6735            int count = mMainStack.mHistory.size();
6736            if (DEBUG_SWITCH) Slog.d(
6737                TAG, "Performing unhandledBack(): stack size = " + count);
6738            if (count > 1) {
6739                final long origId = Binder.clearCallingIdentity();
6740                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6741                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6742                Binder.restoreCallingIdentity(origId);
6743            }
6744        }
6745    }
6746
6747    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6748        enforceNotIsolatedCaller("openContentUri");
6749        String name = uri.getAuthority();
6750        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6751        ParcelFileDescriptor pfd = null;
6752        if (cph != null) {
6753            // We record the binder invoker's uid in thread-local storage before
6754            // going to the content provider to open the file.  Later, in the code
6755            // that handles all permissions checks, we look for this uid and use
6756            // that rather than the Activity Manager's own uid.  The effect is that
6757            // we do the check against the caller's permissions even though it looks
6758            // to the content provider like the Activity Manager itself is making
6759            // the request.
6760            sCallerIdentity.set(new Identity(
6761                    Binder.getCallingPid(), Binder.getCallingUid()));
6762            try {
6763                pfd = cph.provider.openFile(uri, "r");
6764            } catch (FileNotFoundException e) {
6765                // do nothing; pfd will be returned null
6766            } finally {
6767                // Ensure that whatever happens, we clean up the identity state
6768                sCallerIdentity.remove();
6769            }
6770
6771            // We've got the fd now, so we're done with the provider.
6772            removeContentProviderExternalUnchecked(name, null);
6773        } else {
6774            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6775        }
6776        return pfd;
6777    }
6778
6779    // Actually is sleeping or shutting down or whatever else in the future
6780    // is an inactive state.
6781    public boolean isSleeping() {
6782        return mSleeping || mShuttingDown;
6783    }
6784
6785    public void goingToSleep() {
6786        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6787                != PackageManager.PERMISSION_GRANTED) {
6788            throw new SecurityException("Requires permission "
6789                    + android.Manifest.permission.DEVICE_POWER);
6790        }
6791
6792        synchronized(this) {
6793            mWentToSleep = true;
6794            updateEventDispatchingLocked();
6795
6796            if (!mSleeping) {
6797                mSleeping = true;
6798                mMainStack.stopIfSleepingLocked();
6799
6800                // Initialize the wake times of all processes.
6801                checkExcessivePowerUsageLocked(false);
6802                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6803                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6804                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6805            }
6806        }
6807    }
6808
6809    public boolean shutdown(int timeout) {
6810        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6811                != PackageManager.PERMISSION_GRANTED) {
6812            throw new SecurityException("Requires permission "
6813                    + android.Manifest.permission.SHUTDOWN);
6814        }
6815
6816        boolean timedout = false;
6817
6818        synchronized(this) {
6819            mShuttingDown = true;
6820            updateEventDispatchingLocked();
6821
6822            if (mMainStack.mResumedActivity != null) {
6823                mMainStack.stopIfSleepingLocked();
6824                final long endTime = System.currentTimeMillis() + timeout;
6825                while (mMainStack.mResumedActivity != null
6826                        || mMainStack.mPausingActivity != null) {
6827                    long delay = endTime - System.currentTimeMillis();
6828                    if (delay <= 0) {
6829                        Slog.w(TAG, "Activity manager shutdown timed out");
6830                        timedout = true;
6831                        break;
6832                    }
6833                    try {
6834                        this.wait();
6835                    } catch (InterruptedException e) {
6836                    }
6837                }
6838            }
6839        }
6840
6841        mUsageStatsService.shutdown();
6842        mBatteryStatsService.shutdown();
6843
6844        return timedout;
6845    }
6846
6847    public final void activitySlept(IBinder token) {
6848        if (localLOGV) Slog.v(
6849            TAG, "Activity slept: token=" + token);
6850
6851        ActivityRecord r = null;
6852
6853        final long origId = Binder.clearCallingIdentity();
6854
6855        synchronized (this) {
6856            r = mMainStack.isInStackLocked(token);
6857            if (r != null) {
6858                mMainStack.activitySleptLocked(r);
6859            }
6860        }
6861
6862        Binder.restoreCallingIdentity(origId);
6863    }
6864
6865    private void comeOutOfSleepIfNeededLocked() {
6866        if (!mWentToSleep && !mLockScreenShown) {
6867            if (mSleeping) {
6868                mSleeping = false;
6869                mMainStack.awakeFromSleepingLocked();
6870                mMainStack.resumeTopActivityLocked(null);
6871            }
6872        }
6873    }
6874
6875    public void wakingUp() {
6876        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6877                != PackageManager.PERMISSION_GRANTED) {
6878            throw new SecurityException("Requires permission "
6879                    + android.Manifest.permission.DEVICE_POWER);
6880        }
6881
6882        synchronized(this) {
6883            mWentToSleep = false;
6884            updateEventDispatchingLocked();
6885            comeOutOfSleepIfNeededLocked();
6886        }
6887    }
6888
6889    private void updateEventDispatchingLocked() {
6890        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6891    }
6892
6893    public void setLockScreenShown(boolean shown) {
6894        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6895                != PackageManager.PERMISSION_GRANTED) {
6896            throw new SecurityException("Requires permission "
6897                    + android.Manifest.permission.DEVICE_POWER);
6898        }
6899
6900        synchronized(this) {
6901            mLockScreenShown = shown;
6902            comeOutOfSleepIfNeededLocked();
6903        }
6904    }
6905
6906    public void stopAppSwitches() {
6907        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6908                != PackageManager.PERMISSION_GRANTED) {
6909            throw new SecurityException("Requires permission "
6910                    + android.Manifest.permission.STOP_APP_SWITCHES);
6911        }
6912
6913        synchronized(this) {
6914            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6915                    + APP_SWITCH_DELAY_TIME;
6916            mDidAppSwitch = false;
6917            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6918            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6919            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6920        }
6921    }
6922
6923    public void resumeAppSwitches() {
6924        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6925                != PackageManager.PERMISSION_GRANTED) {
6926            throw new SecurityException("Requires permission "
6927                    + android.Manifest.permission.STOP_APP_SWITCHES);
6928        }
6929
6930        synchronized(this) {
6931            // Note that we don't execute any pending app switches... we will
6932            // let those wait until either the timeout, or the next start
6933            // activity request.
6934            mAppSwitchesAllowedTime = 0;
6935        }
6936    }
6937
6938    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6939            String name) {
6940        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6941            return true;
6942        }
6943
6944        final int perm = checkComponentPermission(
6945                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
6946                callingUid, -1, true);
6947        if (perm == PackageManager.PERMISSION_GRANTED) {
6948            return true;
6949        }
6950
6951        Slog.w(TAG, name + " request from " + callingUid + " stopped");
6952        return false;
6953    }
6954
6955    public void setDebugApp(String packageName, boolean waitForDebugger,
6956            boolean persistent) {
6957        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6958                "setDebugApp()");
6959
6960        // Note that this is not really thread safe if there are multiple
6961        // callers into it at the same time, but that's not a situation we
6962        // care about.
6963        if (persistent) {
6964            final ContentResolver resolver = mContext.getContentResolver();
6965            Settings.System.putString(
6966                resolver, Settings.System.DEBUG_APP,
6967                packageName);
6968            Settings.System.putInt(
6969                resolver, Settings.System.WAIT_FOR_DEBUGGER,
6970                waitForDebugger ? 1 : 0);
6971        }
6972
6973        synchronized (this) {
6974            if (!persistent) {
6975                mOrigDebugApp = mDebugApp;
6976                mOrigWaitForDebugger = mWaitForDebugger;
6977            }
6978            mDebugApp = packageName;
6979            mWaitForDebugger = waitForDebugger;
6980            mDebugTransient = !persistent;
6981            if (packageName != null) {
6982                final long origId = Binder.clearCallingIdentity();
6983                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
6984                Binder.restoreCallingIdentity(origId);
6985            }
6986        }
6987    }
6988
6989    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
6990        synchronized (this) {
6991            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6992            if (!isDebuggable) {
6993                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6994                    throw new SecurityException("Process not debuggable: " + app.packageName);
6995                }
6996            }
6997
6998            mOpenGlTraceApp = processName;
6999        }
7000    }
7001
7002    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7003            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7004        synchronized (this) {
7005            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7006            if (!isDebuggable) {
7007                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7008                    throw new SecurityException("Process not debuggable: " + app.packageName);
7009                }
7010            }
7011            mProfileApp = processName;
7012            mProfileFile = profileFile;
7013            if (mProfileFd != null) {
7014                try {
7015                    mProfileFd.close();
7016                } catch (IOException e) {
7017                }
7018                mProfileFd = null;
7019            }
7020            mProfileFd = profileFd;
7021            mProfileType = 0;
7022            mAutoStopProfiler = autoStopProfiler;
7023        }
7024    }
7025
7026    public void setAlwaysFinish(boolean enabled) {
7027        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7028                "setAlwaysFinish()");
7029
7030        Settings.System.putInt(
7031                mContext.getContentResolver(),
7032                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7033
7034        synchronized (this) {
7035            mAlwaysFinishActivities = enabled;
7036        }
7037    }
7038
7039    public void setActivityController(IActivityController controller) {
7040        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7041                "setActivityController()");
7042        synchronized (this) {
7043            mController = controller;
7044        }
7045    }
7046
7047    public boolean isUserAMonkey() {
7048        // For now the fact that there is a controller implies
7049        // we have a monkey.
7050        synchronized (this) {
7051            return mController != null;
7052        }
7053    }
7054
7055    public void registerProcessObserver(IProcessObserver observer) {
7056        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7057                "registerProcessObserver()");
7058        synchronized (this) {
7059            mProcessObservers.register(observer);
7060        }
7061    }
7062
7063    public void unregisterProcessObserver(IProcessObserver observer) {
7064        synchronized (this) {
7065            mProcessObservers.unregister(observer);
7066        }
7067    }
7068
7069    public void setImmersive(IBinder token, boolean immersive) {
7070        synchronized(this) {
7071            ActivityRecord r = mMainStack.isInStackLocked(token);
7072            if (r == null) {
7073                throw new IllegalArgumentException();
7074            }
7075            r.immersive = immersive;
7076        }
7077    }
7078
7079    public boolean isImmersive(IBinder token) {
7080        synchronized (this) {
7081            ActivityRecord r = mMainStack.isInStackLocked(token);
7082            if (r == null) {
7083                throw new IllegalArgumentException();
7084            }
7085            return r.immersive;
7086        }
7087    }
7088
7089    public boolean isTopActivityImmersive() {
7090        enforceNotIsolatedCaller("startActivity");
7091        synchronized (this) {
7092            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7093            return (r != null) ? r.immersive : false;
7094        }
7095    }
7096
7097    public final void enterSafeMode() {
7098        synchronized(this) {
7099            // It only makes sense to do this before the system is ready
7100            // and started launching other packages.
7101            if (!mSystemReady) {
7102                try {
7103                    AppGlobals.getPackageManager().enterSafeMode();
7104                } catch (RemoteException e) {
7105                }
7106            }
7107        }
7108    }
7109
7110    public final void showSafeModeOverlay() {
7111        View v = LayoutInflater.from(mContext).inflate(
7112                com.android.internal.R.layout.safe_mode, null);
7113        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7114        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7115        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7116        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7117        lp.gravity = Gravity.BOTTOM | Gravity.START;
7118        lp.format = v.getBackground().getOpacity();
7119        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7120                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7121        ((WindowManager)mContext.getSystemService(
7122                Context.WINDOW_SERVICE)).addView(v, lp);
7123    }
7124
7125    public void noteWakeupAlarm(IIntentSender sender) {
7126        if (!(sender instanceof PendingIntentRecord)) {
7127            return;
7128        }
7129        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7130        synchronized (stats) {
7131            if (mBatteryStatsService.isOnBattery()) {
7132                mBatteryStatsService.enforceCallingPermission();
7133                PendingIntentRecord rec = (PendingIntentRecord)sender;
7134                int MY_UID = Binder.getCallingUid();
7135                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7136                BatteryStatsImpl.Uid.Pkg pkg =
7137                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7138                pkg.incWakeupsLocked();
7139            }
7140        }
7141    }
7142
7143    public boolean killPids(int[] pids, String pReason, boolean secure) {
7144        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7145            throw new SecurityException("killPids only available to the system");
7146        }
7147        String reason = (pReason == null) ? "Unknown" : pReason;
7148        // XXX Note: don't acquire main activity lock here, because the window
7149        // manager calls in with its locks held.
7150
7151        boolean killed = false;
7152        synchronized (mPidsSelfLocked) {
7153            int[] types = new int[pids.length];
7154            int worstType = 0;
7155            for (int i=0; i<pids.length; i++) {
7156                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7157                if (proc != null) {
7158                    int type = proc.setAdj;
7159                    types[i] = type;
7160                    if (type > worstType) {
7161                        worstType = type;
7162                    }
7163                }
7164            }
7165
7166            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7167            // then constrain it so we will kill all hidden procs.
7168            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7169                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7170                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7171            }
7172
7173            // If this is not a secure call, don't let it kill processes that
7174            // are important.
7175            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7176                worstType = ProcessList.SERVICE_ADJ;
7177            }
7178
7179            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7180            for (int i=0; i<pids.length; i++) {
7181                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7182                if (proc == null) {
7183                    continue;
7184                }
7185                int adj = proc.setAdj;
7186                if (adj >= worstType && !proc.killedBackground) {
7187                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7188                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7189                            proc.processName, adj, reason);
7190                    killed = true;
7191                    proc.killedBackground = true;
7192                    Process.killProcessQuiet(pids[i]);
7193                }
7194            }
7195        }
7196        return killed;
7197    }
7198
7199    @Override
7200    public boolean killProcessesBelowForeground(String reason) {
7201        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7202            throw new SecurityException("killProcessesBelowForeground() only available to system");
7203        }
7204
7205        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7206    }
7207
7208    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7209        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7210            throw new SecurityException("killProcessesBelowAdj() only available to system");
7211        }
7212
7213        boolean killed = false;
7214        synchronized (mPidsSelfLocked) {
7215            final int size = mPidsSelfLocked.size();
7216            for (int i = 0; i < size; i++) {
7217                final int pid = mPidsSelfLocked.keyAt(i);
7218                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7219                if (proc == null) continue;
7220
7221                final int adj = proc.setAdj;
7222                if (adj > belowAdj && !proc.killedBackground) {
7223                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7224                    EventLog.writeEvent(
7225                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7226                    killed = true;
7227                    proc.killedBackground = true;
7228                    Process.killProcessQuiet(pid);
7229                }
7230            }
7231        }
7232        return killed;
7233    }
7234
7235    public final void startRunning(String pkg, String cls, String action,
7236            String data) {
7237        synchronized(this) {
7238            if (mStartRunning) {
7239                return;
7240            }
7241            mStartRunning = true;
7242            mTopComponent = pkg != null && cls != null
7243                    ? new ComponentName(pkg, cls) : null;
7244            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7245            mTopData = data;
7246            if (!mSystemReady) {
7247                return;
7248            }
7249        }
7250
7251        systemReady(null);
7252    }
7253
7254    private void retrieveSettings() {
7255        final ContentResolver resolver = mContext.getContentResolver();
7256        String debugApp = Settings.System.getString(
7257            resolver, Settings.System.DEBUG_APP);
7258        boolean waitForDebugger = Settings.System.getInt(
7259            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7260        boolean alwaysFinishActivities = Settings.System.getInt(
7261            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7262
7263        Configuration configuration = new Configuration();
7264        Settings.System.getConfiguration(resolver, configuration);
7265
7266        synchronized (this) {
7267            mDebugApp = mOrigDebugApp = debugApp;
7268            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7269            mAlwaysFinishActivities = alwaysFinishActivities;
7270            // This happens before any activities are started, so we can
7271            // change mConfiguration in-place.
7272            updateConfigurationLocked(configuration, null, false, true);
7273            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7274        }
7275    }
7276
7277    public boolean testIsSystemReady() {
7278        // no need to synchronize(this) just to read & return the value
7279        return mSystemReady;
7280    }
7281
7282    private static File getCalledPreBootReceiversFile() {
7283        File dataDir = Environment.getDataDirectory();
7284        File systemDir = new File(dataDir, "system");
7285        File fname = new File(systemDir, "called_pre_boots.dat");
7286        return fname;
7287    }
7288
7289    static final int LAST_DONE_VERSION = 10000;
7290
7291    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7292        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7293        File file = getCalledPreBootReceiversFile();
7294        FileInputStream fis = null;
7295        try {
7296            fis = new FileInputStream(file);
7297            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7298            int fvers = dis.readInt();
7299            if (fvers == LAST_DONE_VERSION) {
7300                String vers = dis.readUTF();
7301                String codename = dis.readUTF();
7302                String build = dis.readUTF();
7303                if (android.os.Build.VERSION.RELEASE.equals(vers)
7304                        && android.os.Build.VERSION.CODENAME.equals(codename)
7305                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7306                    int num = dis.readInt();
7307                    while (num > 0) {
7308                        num--;
7309                        String pkg = dis.readUTF();
7310                        String cls = dis.readUTF();
7311                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7312                    }
7313                }
7314            }
7315        } catch (FileNotFoundException e) {
7316        } catch (IOException e) {
7317            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7318        } finally {
7319            if (fis != null) {
7320                try {
7321                    fis.close();
7322                } catch (IOException e) {
7323                }
7324            }
7325        }
7326        return lastDoneReceivers;
7327    }
7328
7329    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7330        File file = getCalledPreBootReceiversFile();
7331        FileOutputStream fos = null;
7332        DataOutputStream dos = null;
7333        try {
7334            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7335            fos = new FileOutputStream(file);
7336            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7337            dos.writeInt(LAST_DONE_VERSION);
7338            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7339            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7340            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7341            dos.writeInt(list.size());
7342            for (int i=0; i<list.size(); i++) {
7343                dos.writeUTF(list.get(i).getPackageName());
7344                dos.writeUTF(list.get(i).getClassName());
7345            }
7346        } catch (IOException e) {
7347            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7348            file.delete();
7349        } finally {
7350            FileUtils.sync(fos);
7351            if (dos != null) {
7352                try {
7353                    dos.close();
7354                } catch (IOException e) {
7355                    // TODO Auto-generated catch block
7356                    e.printStackTrace();
7357                }
7358            }
7359        }
7360    }
7361
7362    public void systemReady(final Runnable goingCallback) {
7363        synchronized(this) {
7364            if (mSystemReady) {
7365                if (goingCallback != null) goingCallback.run();
7366                return;
7367            }
7368
7369            // Check to see if there are any update receivers to run.
7370            if (!mDidUpdate) {
7371                if (mWaitingUpdate) {
7372                    return;
7373                }
7374                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7375                List<ResolveInfo> ris = null;
7376                try {
7377                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7378                            intent, null, 0, 0);
7379                } catch (RemoteException e) {
7380                }
7381                if (ris != null) {
7382                    for (int i=ris.size()-1; i>=0; i--) {
7383                        if ((ris.get(i).activityInfo.applicationInfo.flags
7384                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7385                            ris.remove(i);
7386                        }
7387                    }
7388                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7389
7390                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7391
7392                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7393                    for (int i=0; i<ris.size(); i++) {
7394                        ActivityInfo ai = ris.get(i).activityInfo;
7395                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7396                        if (lastDoneReceivers.contains(comp)) {
7397                            ris.remove(i);
7398                            i--;
7399                        }
7400                    }
7401
7402                    for (int i=0; i<ris.size(); i++) {
7403                        ActivityInfo ai = ris.get(i).activityInfo;
7404                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7405                        doneReceivers.add(comp);
7406                        intent.setComponent(comp);
7407                        IIntentReceiver finisher = null;
7408                        if (i == ris.size()-1) {
7409                            finisher = new IIntentReceiver.Stub() {
7410                                public void performReceive(Intent intent, int resultCode,
7411                                        String data, Bundle extras, boolean ordered,
7412                                        boolean sticky) {
7413                                    // The raw IIntentReceiver interface is called
7414                                    // with the AM lock held, so redispatch to
7415                                    // execute our code without the lock.
7416                                    mHandler.post(new Runnable() {
7417                                        public void run() {
7418                                            synchronized (ActivityManagerService.this) {
7419                                                mDidUpdate = true;
7420                                            }
7421                                            writeLastDonePreBootReceivers(doneReceivers);
7422                                            showBootMessage(mContext.getText(
7423                                                    R.string.android_upgrading_complete),
7424                                                    false);
7425                                            systemReady(goingCallback);
7426                                        }
7427                                    });
7428                                }
7429                            };
7430                        }
7431                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7432                        /* TODO: Send this to all users */
7433                        broadcastIntentLocked(null, null, intent, null, finisher,
7434                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7435                                0 /* UserId zero */);
7436                        if (finisher != null) {
7437                            mWaitingUpdate = true;
7438                        }
7439                    }
7440                }
7441                if (mWaitingUpdate) {
7442                    return;
7443                }
7444                mDidUpdate = true;
7445            }
7446
7447            mSystemReady = true;
7448            if (!mStartRunning) {
7449                return;
7450            }
7451        }
7452
7453        ArrayList<ProcessRecord> procsToKill = null;
7454        synchronized(mPidsSelfLocked) {
7455            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7456                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7457                if (!isAllowedWhileBooting(proc.info)){
7458                    if (procsToKill == null) {
7459                        procsToKill = new ArrayList<ProcessRecord>();
7460                    }
7461                    procsToKill.add(proc);
7462                }
7463            }
7464        }
7465
7466        synchronized(this) {
7467            if (procsToKill != null) {
7468                for (int i=procsToKill.size()-1; i>=0; i--) {
7469                    ProcessRecord proc = procsToKill.get(i);
7470                    Slog.i(TAG, "Removing system update proc: " + proc);
7471                    removeProcessLocked(proc, true, false, "system update done");
7472                }
7473            }
7474
7475            // Now that we have cleaned up any update processes, we
7476            // are ready to start launching real processes and know that
7477            // we won't trample on them any more.
7478            mProcessesReady = true;
7479        }
7480
7481        Slog.i(TAG, "System now ready");
7482        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7483            SystemClock.uptimeMillis());
7484
7485        synchronized(this) {
7486            // Make sure we have no pre-ready processes sitting around.
7487
7488            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7489                ResolveInfo ri = mContext.getPackageManager()
7490                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7491                                STOCK_PM_FLAGS);
7492                CharSequence errorMsg = null;
7493                if (ri != null) {
7494                    ActivityInfo ai = ri.activityInfo;
7495                    ApplicationInfo app = ai.applicationInfo;
7496                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7497                        mTopAction = Intent.ACTION_FACTORY_TEST;
7498                        mTopData = null;
7499                        mTopComponent = new ComponentName(app.packageName,
7500                                ai.name);
7501                    } else {
7502                        errorMsg = mContext.getResources().getText(
7503                                com.android.internal.R.string.factorytest_not_system);
7504                    }
7505                } else {
7506                    errorMsg = mContext.getResources().getText(
7507                            com.android.internal.R.string.factorytest_no_action);
7508                }
7509                if (errorMsg != null) {
7510                    mTopAction = null;
7511                    mTopData = null;
7512                    mTopComponent = null;
7513                    Message msg = Message.obtain();
7514                    msg.what = SHOW_FACTORY_ERROR_MSG;
7515                    msg.getData().putCharSequence("msg", errorMsg);
7516                    mHandler.sendMessage(msg);
7517                }
7518            }
7519        }
7520
7521        retrieveSettings();
7522
7523        if (goingCallback != null) goingCallback.run();
7524
7525        synchronized (this) {
7526            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7527                try {
7528                    List apps = AppGlobals.getPackageManager().
7529                        getPersistentApplications(STOCK_PM_FLAGS);
7530                    if (apps != null) {
7531                        int N = apps.size();
7532                        int i;
7533                        for (i=0; i<N; i++) {
7534                            ApplicationInfo info
7535                                = (ApplicationInfo)apps.get(i);
7536                            if (info != null &&
7537                                    !info.packageName.equals("android")) {
7538                                addAppLocked(info, false);
7539                            }
7540                        }
7541                    }
7542                } catch (RemoteException ex) {
7543                    // pm is in same process, this will never happen.
7544                }
7545            }
7546
7547            // Start up initial activity.
7548            mBooting = true;
7549
7550            try {
7551                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7552                    Message msg = Message.obtain();
7553                    msg.what = SHOW_UID_ERROR_MSG;
7554                    mHandler.sendMessage(msg);
7555                }
7556            } catch (RemoteException e) {
7557            }
7558
7559            mMainStack.resumeTopActivityLocked(null);
7560        }
7561    }
7562
7563    private boolean makeAppCrashingLocked(ProcessRecord app,
7564            String shortMsg, String longMsg, String stackTrace) {
7565        app.crashing = true;
7566        app.crashingReport = generateProcessError(app,
7567                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7568        startAppProblemLocked(app);
7569        app.stopFreezingAllLocked();
7570        return handleAppCrashLocked(app);
7571    }
7572
7573    private void makeAppNotRespondingLocked(ProcessRecord app,
7574            String activity, String shortMsg, String longMsg) {
7575        app.notResponding = true;
7576        app.notRespondingReport = generateProcessError(app,
7577                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7578                activity, shortMsg, longMsg, null);
7579        startAppProblemLocked(app);
7580        app.stopFreezingAllLocked();
7581    }
7582
7583    /**
7584     * Generate a process error record, suitable for attachment to a ProcessRecord.
7585     *
7586     * @param app The ProcessRecord in which the error occurred.
7587     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7588     *                      ActivityManager.AppErrorStateInfo
7589     * @param activity The activity associated with the crash, if known.
7590     * @param shortMsg Short message describing the crash.
7591     * @param longMsg Long message describing the crash.
7592     * @param stackTrace Full crash stack trace, may be null.
7593     *
7594     * @return Returns a fully-formed AppErrorStateInfo record.
7595     */
7596    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7597            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7598        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7599
7600        report.condition = condition;
7601        report.processName = app.processName;
7602        report.pid = app.pid;
7603        report.uid = app.info.uid;
7604        report.tag = activity;
7605        report.shortMsg = shortMsg;
7606        report.longMsg = longMsg;
7607        report.stackTrace = stackTrace;
7608
7609        return report;
7610    }
7611
7612    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7613        synchronized (this) {
7614            app.crashing = false;
7615            app.crashingReport = null;
7616            app.notResponding = false;
7617            app.notRespondingReport = null;
7618            if (app.anrDialog == fromDialog) {
7619                app.anrDialog = null;
7620            }
7621            if (app.waitDialog == fromDialog) {
7622                app.waitDialog = null;
7623            }
7624            if (app.pid > 0 && app.pid != MY_PID) {
7625                handleAppCrashLocked(app);
7626                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7627                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7628                        app.processName, app.setAdj, "user's request after error");
7629                Process.killProcessQuiet(app.pid);
7630            }
7631        }
7632    }
7633
7634    private boolean handleAppCrashLocked(ProcessRecord app) {
7635        if (mHeadless) {
7636            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7637            return false;
7638        }
7639        long now = SystemClock.uptimeMillis();
7640
7641        Long crashTime;
7642        if (!app.isolated) {
7643            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7644        } else {
7645            crashTime = null;
7646        }
7647        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7648            // This process loses!
7649            Slog.w(TAG, "Process " + app.info.processName
7650                    + " has crashed too many times: killing!");
7651            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7652                    app.info.processName, app.uid);
7653            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7654                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7655                if (r.app == app) {
7656                    Slog.w(TAG, "  Force finishing activity "
7657                        + r.intent.getComponent().flattenToShortString());
7658                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7659                }
7660            }
7661            if (!app.persistent) {
7662                // We don't want to start this process again until the user
7663                // explicitly does so...  but for persistent process, we really
7664                // need to keep it running.  If a persistent process is actually
7665                // repeatedly crashing, then badness for everyone.
7666                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7667                        app.info.processName);
7668                if (!app.isolated) {
7669                    // XXX We don't have a way to mark isolated processes
7670                    // as bad, since they don't have a peristent identity.
7671                    mBadProcesses.put(app.info.processName, app.uid, now);
7672                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7673                }
7674                app.bad = true;
7675                app.removed = true;
7676                // Don't let services in this process be restarted and potentially
7677                // annoy the user repeatedly.  Unless it is persistent, since those
7678                // processes run critical code.
7679                removeProcessLocked(app, false, false, "crash");
7680                mMainStack.resumeTopActivityLocked(null);
7681                return false;
7682            }
7683            mMainStack.resumeTopActivityLocked(null);
7684        } else {
7685            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7686            if (r != null && r.app == app) {
7687                // If the top running activity is from this crashing
7688                // process, then terminate it to avoid getting in a loop.
7689                Slog.w(TAG, "  Force finishing activity "
7690                        + r.intent.getComponent().flattenToShortString());
7691                int index = mMainStack.indexOfActivityLocked(r);
7692                r.stack.finishActivityLocked(r, index,
7693                        Activity.RESULT_CANCELED, null, "crashed");
7694                // Also terminate any activities below it that aren't yet
7695                // stopped, to avoid a situation where one will get
7696                // re-start our crashing activity once it gets resumed again.
7697                index--;
7698                if (index >= 0) {
7699                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7700                    if (r.state == ActivityState.RESUMED
7701                            || r.state == ActivityState.PAUSING
7702                            || r.state == ActivityState.PAUSED) {
7703                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7704                            Slog.w(TAG, "  Force finishing activity "
7705                                    + r.intent.getComponent().flattenToShortString());
7706                            r.stack.finishActivityLocked(r, index,
7707                                    Activity.RESULT_CANCELED, null, "crashed");
7708                        }
7709                    }
7710                }
7711            }
7712        }
7713
7714        // Bump up the crash count of any services currently running in the proc.
7715        if (app.services.size() != 0) {
7716            // Any services running in the application need to be placed
7717            // back in the pending list.
7718            Iterator<ServiceRecord> it = app.services.iterator();
7719            while (it.hasNext()) {
7720                ServiceRecord sr = it.next();
7721                sr.crashCount++;
7722            }
7723        }
7724
7725        // If the crashing process is what we consider to be the "home process" and it has been
7726        // replaced by a third-party app, clear the package preferred activities from packages
7727        // with a home activity running in the process to prevent a repeatedly crashing app
7728        // from blocking the user to manually clear the list.
7729        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7730                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7731            Iterator it = mHomeProcess.activities.iterator();
7732            while (it.hasNext()) {
7733                ActivityRecord r = (ActivityRecord)it.next();
7734                if (r.isHomeActivity) {
7735                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7736                    try {
7737                        ActivityThread.getPackageManager()
7738                                .clearPackagePreferredActivities(r.packageName);
7739                    } catch (RemoteException c) {
7740                        // pm is in same process, this will never happen.
7741                    }
7742                }
7743            }
7744        }
7745
7746        if (!app.isolated) {
7747            // XXX Can't keep track of crash times for isolated processes,
7748            // because they don't have a perisistent identity.
7749            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7750        }
7751
7752        return true;
7753    }
7754
7755    void startAppProblemLocked(ProcessRecord app) {
7756        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7757                mContext, app.info.packageName, app.info.flags);
7758        skipCurrentReceiverLocked(app);
7759    }
7760
7761    void skipCurrentReceiverLocked(ProcessRecord app) {
7762        for (BroadcastQueue queue : mBroadcastQueues) {
7763            queue.skipCurrentReceiverLocked(app);
7764        }
7765    }
7766
7767    /**
7768     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7769     * The application process will exit immediately after this call returns.
7770     * @param app object of the crashing app, null for the system server
7771     * @param crashInfo describing the exception
7772     */
7773    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7774        ProcessRecord r = findAppProcess(app, "Crash");
7775        final String processName = app == null ? "system_server"
7776                : (r == null ? "unknown" : r.processName);
7777
7778        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7779                processName,
7780                r == null ? -1 : r.info.flags,
7781                crashInfo.exceptionClassName,
7782                crashInfo.exceptionMessage,
7783                crashInfo.throwFileName,
7784                crashInfo.throwLineNumber);
7785
7786        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7787
7788        crashApplication(r, crashInfo);
7789    }
7790
7791    public void handleApplicationStrictModeViolation(
7792            IBinder app,
7793            int violationMask,
7794            StrictMode.ViolationInfo info) {
7795        ProcessRecord r = findAppProcess(app, "StrictMode");
7796        if (r == null) {
7797            return;
7798        }
7799
7800        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7801            Integer stackFingerprint = info.hashCode();
7802            boolean logIt = true;
7803            synchronized (mAlreadyLoggedViolatedStacks) {
7804                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7805                    logIt = false;
7806                    // TODO: sub-sample into EventLog for these, with
7807                    // the info.durationMillis?  Then we'd get
7808                    // the relative pain numbers, without logging all
7809                    // the stack traces repeatedly.  We'd want to do
7810                    // likewise in the client code, which also does
7811                    // dup suppression, before the Binder call.
7812                } else {
7813                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7814                        mAlreadyLoggedViolatedStacks.clear();
7815                    }
7816                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7817                }
7818            }
7819            if (logIt) {
7820                logStrictModeViolationToDropBox(r, info);
7821            }
7822        }
7823
7824        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7825            AppErrorResult result = new AppErrorResult();
7826            synchronized (this) {
7827                final long origId = Binder.clearCallingIdentity();
7828
7829                Message msg = Message.obtain();
7830                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7831                HashMap<String, Object> data = new HashMap<String, Object>();
7832                data.put("result", result);
7833                data.put("app", r);
7834                data.put("violationMask", violationMask);
7835                data.put("info", info);
7836                msg.obj = data;
7837                mHandler.sendMessage(msg);
7838
7839                Binder.restoreCallingIdentity(origId);
7840            }
7841            int res = result.get();
7842            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7843        }
7844    }
7845
7846    // Depending on the policy in effect, there could be a bunch of
7847    // these in quick succession so we try to batch these together to
7848    // minimize disk writes, number of dropbox entries, and maximize
7849    // compression, by having more fewer, larger records.
7850    private void logStrictModeViolationToDropBox(
7851            ProcessRecord process,
7852            StrictMode.ViolationInfo info) {
7853        if (info == null) {
7854            return;
7855        }
7856        final boolean isSystemApp = process == null ||
7857                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7858                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7859        final String processName = process == null ? "unknown" : process.processName;
7860        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7861        final DropBoxManager dbox = (DropBoxManager)
7862                mContext.getSystemService(Context.DROPBOX_SERVICE);
7863
7864        // Exit early if the dropbox isn't configured to accept this report type.
7865        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7866
7867        boolean bufferWasEmpty;
7868        boolean needsFlush;
7869        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7870        synchronized (sb) {
7871            bufferWasEmpty = sb.length() == 0;
7872            appendDropBoxProcessHeaders(process, processName, sb);
7873            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7874            sb.append("System-App: ").append(isSystemApp).append("\n");
7875            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7876            if (info.violationNumThisLoop != 0) {
7877                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7878            }
7879            if (info.numAnimationsRunning != 0) {
7880                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7881            }
7882            if (info.broadcastIntentAction != null) {
7883                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7884            }
7885            if (info.durationMillis != -1) {
7886                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7887            }
7888            if (info.numInstances != -1) {
7889                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7890            }
7891            if (info.tags != null) {
7892                for (String tag : info.tags) {
7893                    sb.append("Span-Tag: ").append(tag).append("\n");
7894                }
7895            }
7896            sb.append("\n");
7897            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7898                sb.append(info.crashInfo.stackTrace);
7899            }
7900            sb.append("\n");
7901
7902            // Only buffer up to ~64k.  Various logging bits truncate
7903            // things at 128k.
7904            needsFlush = (sb.length() > 64 * 1024);
7905        }
7906
7907        // Flush immediately if the buffer's grown too large, or this
7908        // is a non-system app.  Non-system apps are isolated with a
7909        // different tag & policy and not batched.
7910        //
7911        // Batching is useful during internal testing with
7912        // StrictMode settings turned up high.  Without batching,
7913        // thousands of separate files could be created on boot.
7914        if (!isSystemApp || needsFlush) {
7915            new Thread("Error dump: " + dropboxTag) {
7916                @Override
7917                public void run() {
7918                    String report;
7919                    synchronized (sb) {
7920                        report = sb.toString();
7921                        sb.delete(0, sb.length());
7922                        sb.trimToSize();
7923                    }
7924                    if (report.length() != 0) {
7925                        dbox.addText(dropboxTag, report);
7926                    }
7927                }
7928            }.start();
7929            return;
7930        }
7931
7932        // System app batching:
7933        if (!bufferWasEmpty) {
7934            // An existing dropbox-writing thread is outstanding, so
7935            // we don't need to start it up.  The existing thread will
7936            // catch the buffer appends we just did.
7937            return;
7938        }
7939
7940        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7941        // (After this point, we shouldn't access AMS internal data structures.)
7942        new Thread("Error dump: " + dropboxTag) {
7943            @Override
7944            public void run() {
7945                // 5 second sleep to let stacks arrive and be batched together
7946                try {
7947                    Thread.sleep(5000);  // 5 seconds
7948                } catch (InterruptedException e) {}
7949
7950                String errorReport;
7951                synchronized (mStrictModeBuffer) {
7952                    errorReport = mStrictModeBuffer.toString();
7953                    if (errorReport.length() == 0) {
7954                        return;
7955                    }
7956                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7957                    mStrictModeBuffer.trimToSize();
7958                }
7959                dbox.addText(dropboxTag, errorReport);
7960            }
7961        }.start();
7962    }
7963
7964    /**
7965     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7966     * @param app object of the crashing app, null for the system server
7967     * @param tag reported by the caller
7968     * @param crashInfo describing the context of the error
7969     * @return true if the process should exit immediately (WTF is fatal)
7970     */
7971    public boolean handleApplicationWtf(IBinder app, String tag,
7972            ApplicationErrorReport.CrashInfo crashInfo) {
7973        ProcessRecord r = findAppProcess(app, "WTF");
7974        final String processName = app == null ? "system_server"
7975                : (r == null ? "unknown" : r.processName);
7976
7977        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7978                processName,
7979                r == null ? -1 : r.info.flags,
7980                tag, crashInfo.exceptionMessage);
7981
7982        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
7983
7984        if (r != null && r.pid != Process.myPid() &&
7985                Settings.Secure.getInt(mContext.getContentResolver(),
7986                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
7987            crashApplication(r, crashInfo);
7988            return true;
7989        } else {
7990            return false;
7991        }
7992    }
7993
7994    /**
7995     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7996     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7997     */
7998    private ProcessRecord findAppProcess(IBinder app, String reason) {
7999        if (app == null) {
8000            return null;
8001        }
8002
8003        synchronized (this) {
8004            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8005                final int NA = apps.size();
8006                for (int ia=0; ia<NA; ia++) {
8007                    ProcessRecord p = apps.valueAt(ia);
8008                    if (p.thread != null && p.thread.asBinder() == app) {
8009                        return p;
8010                    }
8011                }
8012            }
8013
8014            Slog.w(TAG, "Can't find mystery application for " + reason
8015                    + " from pid=" + Binder.getCallingPid()
8016                    + " uid=" + Binder.getCallingUid() + ": " + app);
8017            return null;
8018        }
8019    }
8020
8021    /**
8022     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8023     * to append various headers to the dropbox log text.
8024     */
8025    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8026            StringBuilder sb) {
8027        // Watchdog thread ends up invoking this function (with
8028        // a null ProcessRecord) to add the stack file to dropbox.
8029        // Do not acquire a lock on this (am) in such cases, as it
8030        // could cause a potential deadlock, if and when watchdog
8031        // is invoked due to unavailability of lock on am and it
8032        // would prevent watchdog from killing system_server.
8033        if (process == null) {
8034            sb.append("Process: ").append(processName).append("\n");
8035            return;
8036        }
8037        // Note: ProcessRecord 'process' is guarded by the service
8038        // instance.  (notably process.pkgList, which could otherwise change
8039        // concurrently during execution of this method)
8040        synchronized (this) {
8041            sb.append("Process: ").append(processName).append("\n");
8042            int flags = process.info.flags;
8043            IPackageManager pm = AppGlobals.getPackageManager();
8044            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8045            for (String pkg : process.pkgList) {
8046                sb.append("Package: ").append(pkg);
8047                try {
8048                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8049                    if (pi != null) {
8050                        sb.append(" v").append(pi.versionCode);
8051                        if (pi.versionName != null) {
8052                            sb.append(" (").append(pi.versionName).append(")");
8053                        }
8054                    }
8055                } catch (RemoteException e) {
8056                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8057                }
8058                sb.append("\n");
8059            }
8060        }
8061    }
8062
8063    private static String processClass(ProcessRecord process) {
8064        if (process == null || process.pid == MY_PID) {
8065            return "system_server";
8066        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8067            return "system_app";
8068        } else {
8069            return "data_app";
8070        }
8071    }
8072
8073    /**
8074     * Write a description of an error (crash, WTF, ANR) to the drop box.
8075     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8076     * @param process which caused the error, null means the system server
8077     * @param activity which triggered the error, null if unknown
8078     * @param parent activity related to the error, null if unknown
8079     * @param subject line related to the error, null if absent
8080     * @param report in long form describing the error, null if absent
8081     * @param logFile to include in the report, null if none
8082     * @param crashInfo giving an application stack trace, null if absent
8083     */
8084    public void addErrorToDropBox(String eventType,
8085            ProcessRecord process, String processName, ActivityRecord activity,
8086            ActivityRecord parent, String subject,
8087            final String report, final File logFile,
8088            final ApplicationErrorReport.CrashInfo crashInfo) {
8089        // NOTE -- this must never acquire the ActivityManagerService lock,
8090        // otherwise the watchdog may be prevented from resetting the system.
8091
8092        final String dropboxTag = processClass(process) + "_" + eventType;
8093        final DropBoxManager dbox = (DropBoxManager)
8094                mContext.getSystemService(Context.DROPBOX_SERVICE);
8095
8096        // Exit early if the dropbox isn't configured to accept this report type.
8097        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8098
8099        final StringBuilder sb = new StringBuilder(1024);
8100        appendDropBoxProcessHeaders(process, processName, sb);
8101        if (activity != null) {
8102            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8103        }
8104        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8105            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8106        }
8107        if (parent != null && parent != activity) {
8108            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8109        }
8110        if (subject != null) {
8111            sb.append("Subject: ").append(subject).append("\n");
8112        }
8113        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8114        if (Debug.isDebuggerConnected()) {
8115            sb.append("Debugger: Connected\n");
8116        }
8117        sb.append("\n");
8118
8119        // Do the rest in a worker thread to avoid blocking the caller on I/O
8120        // (After this point, we shouldn't access AMS internal data structures.)
8121        Thread worker = new Thread("Error dump: " + dropboxTag) {
8122            @Override
8123            public void run() {
8124                if (report != null) {
8125                    sb.append(report);
8126                }
8127                if (logFile != null) {
8128                    try {
8129                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8130                    } catch (IOException e) {
8131                        Slog.e(TAG, "Error reading " + logFile, e);
8132                    }
8133                }
8134                if (crashInfo != null && crashInfo.stackTrace != null) {
8135                    sb.append(crashInfo.stackTrace);
8136                }
8137
8138                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8139                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8140                if (lines > 0) {
8141                    sb.append("\n");
8142
8143                    // Merge several logcat streams, and take the last N lines
8144                    InputStreamReader input = null;
8145                    try {
8146                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8147                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8148                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8149
8150                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8151                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8152                        input = new InputStreamReader(logcat.getInputStream());
8153
8154                        int num;
8155                        char[] buf = new char[8192];
8156                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8157                    } catch (IOException e) {
8158                        Slog.e(TAG, "Error running logcat", e);
8159                    } finally {
8160                        if (input != null) try { input.close(); } catch (IOException e) {}
8161                    }
8162                }
8163
8164                dbox.addText(dropboxTag, sb.toString());
8165            }
8166        };
8167
8168        if (process == null) {
8169            // If process is null, we are being called from some internal code
8170            // and may be about to die -- run this synchronously.
8171            worker.run();
8172        } else {
8173            worker.start();
8174        }
8175    }
8176
8177    /**
8178     * Bring up the "unexpected error" dialog box for a crashing app.
8179     * Deal with edge cases (intercepts from instrumented applications,
8180     * ActivityController, error intent receivers, that sort of thing).
8181     * @param r the application crashing
8182     * @param crashInfo describing the failure
8183     */
8184    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8185        long timeMillis = System.currentTimeMillis();
8186        String shortMsg = crashInfo.exceptionClassName;
8187        String longMsg = crashInfo.exceptionMessage;
8188        String stackTrace = crashInfo.stackTrace;
8189        if (shortMsg != null && longMsg != null) {
8190            longMsg = shortMsg + ": " + longMsg;
8191        } else if (shortMsg != null) {
8192            longMsg = shortMsg;
8193        }
8194
8195        AppErrorResult result = new AppErrorResult();
8196        synchronized (this) {
8197            if (mController != null) {
8198                try {
8199                    String name = r != null ? r.processName : null;
8200                    int pid = r != null ? r.pid : Binder.getCallingPid();
8201                    if (!mController.appCrashed(name, pid,
8202                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8203                        Slog.w(TAG, "Force-killing crashed app " + name
8204                                + " at watcher's request");
8205                        Process.killProcess(pid);
8206                        return;
8207                    }
8208                } catch (RemoteException e) {
8209                    mController = null;
8210                }
8211            }
8212
8213            final long origId = Binder.clearCallingIdentity();
8214
8215            // If this process is running instrumentation, finish it.
8216            if (r != null && r.instrumentationClass != null) {
8217                Slog.w(TAG, "Error in app " + r.processName
8218                      + " running instrumentation " + r.instrumentationClass + ":");
8219                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8220                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8221                Bundle info = new Bundle();
8222                info.putString("shortMsg", shortMsg);
8223                info.putString("longMsg", longMsg);
8224                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8225                Binder.restoreCallingIdentity(origId);
8226                return;
8227            }
8228
8229            // If we can't identify the process or it's already exceeded its crash quota,
8230            // quit right away without showing a crash dialog.
8231            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8232                Binder.restoreCallingIdentity(origId);
8233                return;
8234            }
8235
8236            Message msg = Message.obtain();
8237            msg.what = SHOW_ERROR_MSG;
8238            HashMap data = new HashMap();
8239            data.put("result", result);
8240            data.put("app", r);
8241            msg.obj = data;
8242            mHandler.sendMessage(msg);
8243
8244            Binder.restoreCallingIdentity(origId);
8245        }
8246
8247        int res = result.get();
8248
8249        Intent appErrorIntent = null;
8250        synchronized (this) {
8251            if (r != null && !r.isolated) {
8252                // XXX Can't keep track of crash time for isolated processes,
8253                // since they don't have a persistent identity.
8254                mProcessCrashTimes.put(r.info.processName, r.uid,
8255                        SystemClock.uptimeMillis());
8256            }
8257            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8258                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8259            }
8260        }
8261
8262        if (appErrorIntent != null) {
8263            try {
8264                mContext.startActivity(appErrorIntent);
8265            } catch (ActivityNotFoundException e) {
8266                Slog.w(TAG, "bug report receiver dissappeared", e);
8267            }
8268        }
8269    }
8270
8271    Intent createAppErrorIntentLocked(ProcessRecord r,
8272            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8273        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8274        if (report == null) {
8275            return null;
8276        }
8277        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8278        result.setComponent(r.errorReportReceiver);
8279        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8280        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8281        return result;
8282    }
8283
8284    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8285            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8286        if (r.errorReportReceiver == null) {
8287            return null;
8288        }
8289
8290        if (!r.crashing && !r.notResponding) {
8291            return null;
8292        }
8293
8294        ApplicationErrorReport report = new ApplicationErrorReport();
8295        report.packageName = r.info.packageName;
8296        report.installerPackageName = r.errorReportReceiver.getPackageName();
8297        report.processName = r.processName;
8298        report.time = timeMillis;
8299        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8300
8301        if (r.crashing) {
8302            report.type = ApplicationErrorReport.TYPE_CRASH;
8303            report.crashInfo = crashInfo;
8304        } else if (r.notResponding) {
8305            report.type = ApplicationErrorReport.TYPE_ANR;
8306            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8307
8308            report.anrInfo.activity = r.notRespondingReport.tag;
8309            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8310            report.anrInfo.info = r.notRespondingReport.longMsg;
8311        }
8312
8313        return report;
8314    }
8315
8316    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8317        enforceNotIsolatedCaller("getProcessesInErrorState");
8318        // assume our apps are happy - lazy create the list
8319        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8320
8321        synchronized (this) {
8322
8323            // iterate across all processes
8324            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8325                ProcessRecord app = mLruProcesses.get(i);
8326                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8327                    // This one's in trouble, so we'll generate a report for it
8328                    // crashes are higher priority (in case there's a crash *and* an anr)
8329                    ActivityManager.ProcessErrorStateInfo report = null;
8330                    if (app.crashing) {
8331                        report = app.crashingReport;
8332                    } else if (app.notResponding) {
8333                        report = app.notRespondingReport;
8334                    }
8335
8336                    if (report != null) {
8337                        if (errList == null) {
8338                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8339                        }
8340                        errList.add(report);
8341                    } else {
8342                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8343                                " crashing = " + app.crashing +
8344                                " notResponding = " + app.notResponding);
8345                    }
8346                }
8347            }
8348        }
8349
8350        return errList;
8351    }
8352
8353    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8354        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8355            if (currApp != null) {
8356                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8357            }
8358            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8359        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8360            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8361        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8362            if (currApp != null) {
8363                currApp.lru = 0;
8364            }
8365            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8366        } else if (adj >= ProcessList.SERVICE_ADJ) {
8367            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8368        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8369            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8370        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8371            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8372        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8373            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8374        } else {
8375            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8376        }
8377    }
8378
8379    private void fillInProcMemInfo(ProcessRecord app,
8380            ActivityManager.RunningAppProcessInfo outInfo) {
8381        outInfo.pid = app.pid;
8382        outInfo.uid = app.info.uid;
8383        if (mHeavyWeightProcess == app) {
8384            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8385        }
8386        if (app.persistent) {
8387            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8388        }
8389        outInfo.lastTrimLevel = app.trimMemoryLevel;
8390        int adj = app.curAdj;
8391        outInfo.importance = oomAdjToImportance(adj, outInfo);
8392        outInfo.importanceReasonCode = app.adjTypeCode;
8393    }
8394
8395    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8396        enforceNotIsolatedCaller("getRunningAppProcesses");
8397        // Lazy instantiation of list
8398        List<ActivityManager.RunningAppProcessInfo> runList = null;
8399        synchronized (this) {
8400            // Iterate across all processes
8401            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8402                ProcessRecord app = mLruProcesses.get(i);
8403                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8404                    // Generate process state info for running application
8405                    ActivityManager.RunningAppProcessInfo currApp =
8406                        new ActivityManager.RunningAppProcessInfo(app.processName,
8407                                app.pid, app.getPackageList());
8408                    fillInProcMemInfo(app, currApp);
8409                    if (app.adjSource instanceof ProcessRecord) {
8410                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8411                        currApp.importanceReasonImportance = oomAdjToImportance(
8412                                app.adjSourceOom, null);
8413                    } else if (app.adjSource instanceof ActivityRecord) {
8414                        ActivityRecord r = (ActivityRecord)app.adjSource;
8415                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8416                    }
8417                    if (app.adjTarget instanceof ComponentName) {
8418                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8419                    }
8420                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8421                    //        + " lru=" + currApp.lru);
8422                    if (runList == null) {
8423                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8424                    }
8425                    runList.add(currApp);
8426                }
8427            }
8428        }
8429        return runList;
8430    }
8431
8432    public List<ApplicationInfo> getRunningExternalApplications() {
8433        enforceNotIsolatedCaller("getRunningExternalApplications");
8434        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8435        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8436        if (runningApps != null && runningApps.size() > 0) {
8437            Set<String> extList = new HashSet<String>();
8438            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8439                if (app.pkgList != null) {
8440                    for (String pkg : app.pkgList) {
8441                        extList.add(pkg);
8442                    }
8443                }
8444            }
8445            IPackageManager pm = AppGlobals.getPackageManager();
8446            for (String pkg : extList) {
8447                try {
8448                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8449                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8450                        retList.add(info);
8451                    }
8452                } catch (RemoteException e) {
8453                }
8454            }
8455        }
8456        return retList;
8457    }
8458
8459    @Override
8460    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8461        enforceNotIsolatedCaller("getMyMemoryState");
8462        synchronized (this) {
8463            ProcessRecord proc;
8464            synchronized (mPidsSelfLocked) {
8465                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8466            }
8467            fillInProcMemInfo(proc, outInfo);
8468        }
8469    }
8470
8471    @Override
8472    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8473        if (checkCallingPermission(android.Manifest.permission.DUMP)
8474                != PackageManager.PERMISSION_GRANTED) {
8475            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8476                    + Binder.getCallingPid()
8477                    + ", uid=" + Binder.getCallingUid()
8478                    + " without permission "
8479                    + android.Manifest.permission.DUMP);
8480            return;
8481        }
8482
8483        boolean dumpAll = false;
8484        boolean dumpClient = false;
8485        String dumpPackage = null;
8486
8487        int opti = 0;
8488        while (opti < args.length) {
8489            String opt = args[opti];
8490            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8491                break;
8492            }
8493            opti++;
8494            if ("-a".equals(opt)) {
8495                dumpAll = true;
8496            } else if ("-c".equals(opt)) {
8497                dumpClient = true;
8498            } else if ("-h".equals(opt)) {
8499                pw.println("Activity manager dump options:");
8500                pw.println("  [-a] [-c] [-h] [cmd] ...");
8501                pw.println("  cmd may be one of:");
8502                pw.println("    a[ctivities]: activity stack state");
8503                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8504                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8505                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8506                pw.println("    o[om]: out of memory management");
8507                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8508                pw.println("    provider [COMP_SPEC]: provider client-side state");
8509                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8510                pw.println("    service [COMP_SPEC]: service client-side state");
8511                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8512                pw.println("    all: dump all activities");
8513                pw.println("    top: dump the top activity");
8514                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8515                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8516                pw.println("    a partial substring in a component name, a");
8517                pw.println("    hex object identifier.");
8518                pw.println("  -a: include all available server state.");
8519                pw.println("  -c: include client state.");
8520                return;
8521            } else {
8522                pw.println("Unknown argument: " + opt + "; use -h for help");
8523            }
8524        }
8525
8526        long origId = Binder.clearCallingIdentity();
8527        boolean more = false;
8528        // Is the caller requesting to dump a particular piece of data?
8529        if (opti < args.length) {
8530            String cmd = args[opti];
8531            opti++;
8532            if ("activities".equals(cmd) || "a".equals(cmd)) {
8533                synchronized (this) {
8534                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8535                }
8536            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8537                String[] newArgs;
8538                String name;
8539                if (opti >= args.length) {
8540                    name = null;
8541                    newArgs = EMPTY_STRING_ARRAY;
8542                } else {
8543                    name = args[opti];
8544                    opti++;
8545                    newArgs = new String[args.length - opti];
8546                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8547                            args.length - opti);
8548                }
8549                synchronized (this) {
8550                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8551                }
8552            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8553                String[] newArgs;
8554                String name;
8555                if (opti >= args.length) {
8556                    name = null;
8557                    newArgs = EMPTY_STRING_ARRAY;
8558                } else {
8559                    name = args[opti];
8560                    opti++;
8561                    newArgs = new String[args.length - opti];
8562                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8563                            args.length - opti);
8564                }
8565                synchronized (this) {
8566                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8567                }
8568            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8569                String[] newArgs;
8570                String name;
8571                if (opti >= args.length) {
8572                    name = null;
8573                    newArgs = EMPTY_STRING_ARRAY;
8574                } else {
8575                    name = args[opti];
8576                    opti++;
8577                    newArgs = new String[args.length - opti];
8578                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8579                            args.length - opti);
8580                }
8581                synchronized (this) {
8582                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8583                }
8584            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8585                synchronized (this) {
8586                    dumpOomLocked(fd, pw, args, opti, true);
8587                }
8588            } else if ("provider".equals(cmd)) {
8589                String[] newArgs;
8590                String name;
8591                if (opti >= args.length) {
8592                    name = null;
8593                    newArgs = EMPTY_STRING_ARRAY;
8594                } else {
8595                    name = args[opti];
8596                    opti++;
8597                    newArgs = new String[args.length - opti];
8598                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8599                }
8600                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8601                    pw.println("No providers match: " + name);
8602                    pw.println("Use -h for help.");
8603                }
8604            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8605                synchronized (this) {
8606                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8607                }
8608            } else if ("service".equals(cmd)) {
8609                String[] newArgs;
8610                String name;
8611                if (opti >= args.length) {
8612                    name = null;
8613                    newArgs = EMPTY_STRING_ARRAY;
8614                } else {
8615                    name = args[opti];
8616                    opti++;
8617                    newArgs = new String[args.length - opti];
8618                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8619                            args.length - opti);
8620                }
8621                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8622                    pw.println("No services match: " + name);
8623                    pw.println("Use -h for help.");
8624                }
8625            } else if ("package".equals(cmd)) {
8626                String[] newArgs;
8627                if (opti >= args.length) {
8628                    pw.println("package: no package name specified");
8629                    pw.println("Use -h for help.");
8630                } else {
8631                    dumpPackage = args[opti];
8632                    opti++;
8633                    newArgs = new String[args.length - opti];
8634                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8635                            args.length - opti);
8636                    args = newArgs;
8637                    opti = 0;
8638                    more = true;
8639                }
8640            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8641                synchronized (this) {
8642                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8643                }
8644            } else {
8645                // Dumping a single activity?
8646                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8647                    pw.println("Bad activity command, or no activities match: " + cmd);
8648                    pw.println("Use -h for help.");
8649                }
8650            }
8651            if (!more) {
8652                Binder.restoreCallingIdentity(origId);
8653                return;
8654            }
8655        }
8656
8657        // No piece of data specified, dump everything.
8658        synchronized (this) {
8659            boolean needSep;
8660            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8661            if (needSep) {
8662                pw.println(" ");
8663            }
8664            if (dumpAll) {
8665                pw.println("-------------------------------------------------------------------------------");
8666            }
8667            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8668            if (needSep) {
8669                pw.println(" ");
8670            }
8671            if (dumpAll) {
8672                pw.println("-------------------------------------------------------------------------------");
8673            }
8674            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8675            if (needSep) {
8676                pw.println(" ");
8677            }
8678            if (dumpAll) {
8679                pw.println("-------------------------------------------------------------------------------");
8680            }
8681            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8682            if (needSep) {
8683                pw.println(" ");
8684            }
8685            if (dumpAll) {
8686                pw.println("-------------------------------------------------------------------------------");
8687            }
8688            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8689            if (needSep) {
8690                pw.println(" ");
8691            }
8692            if (dumpAll) {
8693                pw.println("-------------------------------------------------------------------------------");
8694            }
8695            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8696        }
8697        Binder.restoreCallingIdentity(origId);
8698    }
8699
8700    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8701            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8702        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8703        pw.println("  Main stack:");
8704        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8705                dumpPackage);
8706        pw.println(" ");
8707        pw.println("  Running activities (most recent first):");
8708        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8709                dumpPackage);
8710        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8711            pw.println(" ");
8712            pw.println("  Activities waiting for another to become visible:");
8713            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8714                    !dumpAll, false, dumpPackage);
8715        }
8716        if (mMainStack.mStoppingActivities.size() > 0) {
8717            pw.println(" ");
8718            pw.println("  Activities waiting to stop:");
8719            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8720                    !dumpAll, false, dumpPackage);
8721        }
8722        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8723            pw.println(" ");
8724            pw.println("  Activities waiting to sleep:");
8725            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8726                    !dumpAll, false, dumpPackage);
8727        }
8728        if (mMainStack.mFinishingActivities.size() > 0) {
8729            pw.println(" ");
8730            pw.println("  Activities waiting to finish:");
8731            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8732                    !dumpAll, false, dumpPackage);
8733        }
8734
8735        pw.println(" ");
8736        if (mMainStack.mPausingActivity != null) {
8737            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8738        }
8739        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8740        pw.println("  mFocusedActivity: " + mFocusedActivity);
8741        if (dumpAll) {
8742            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8743            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8744            pw.println("  mDismissKeyguardOnNextActivity: "
8745                    + mMainStack.mDismissKeyguardOnNextActivity);
8746        }
8747
8748        if (mRecentTasks.size() > 0) {
8749            pw.println();
8750            pw.println("  Recent tasks:");
8751
8752            final int N = mRecentTasks.size();
8753            for (int i=0; i<N; i++) {
8754                TaskRecord tr = mRecentTasks.get(i);
8755                if (dumpPackage != null) {
8756                    if (tr.realActivity == null ||
8757                            !dumpPackage.equals(tr.realActivity)) {
8758                        continue;
8759                    }
8760                }
8761                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8762                        pw.println(tr);
8763                if (dumpAll) {
8764                    mRecentTasks.get(i).dump(pw, "    ");
8765                }
8766            }
8767        }
8768
8769        if (dumpAll) {
8770            pw.println(" ");
8771            pw.println("  mCurTask: " + mCurTask);
8772        }
8773
8774        return true;
8775    }
8776
8777    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8778            int opti, boolean dumpAll, String dumpPackage) {
8779        boolean needSep = false;
8780        int numPers = 0;
8781
8782        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8783
8784        if (dumpAll) {
8785            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8786                final int NA = procs.size();
8787                for (int ia=0; ia<NA; ia++) {
8788                    ProcessRecord r = procs.valueAt(ia);
8789                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8790                        continue;
8791                    }
8792                    if (!needSep) {
8793                        pw.println("  All known processes:");
8794                        needSep = true;
8795                    }
8796                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8797                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8798                        pw.print(" "); pw.println(r);
8799                    r.dump(pw, "    ");
8800                    if (r.persistent) {
8801                        numPers++;
8802                    }
8803                }
8804            }
8805        }
8806
8807        if (mIsolatedProcesses.size() > 0) {
8808            if (needSep) pw.println(" ");
8809            needSep = true;
8810            pw.println("  Isolated process list (sorted by uid):");
8811            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8812                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8813                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8814                    continue;
8815                }
8816                pw.println(String.format("%sIsolated #%2d: %s",
8817                        "    ", i, r.toString()));
8818            }
8819        }
8820
8821        if (mLruProcesses.size() > 0) {
8822            if (needSep) pw.println(" ");
8823            needSep = true;
8824            pw.println("  Process LRU list (sorted by oom_adj):");
8825            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8826                    "Proc", "PERS", false, dumpPackage);
8827            needSep = true;
8828        }
8829
8830        if (dumpAll) {
8831            synchronized (mPidsSelfLocked) {
8832                boolean printed = false;
8833                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8834                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8835                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8836                        continue;
8837                    }
8838                    if (!printed) {
8839                        if (needSep) pw.println(" ");
8840                        needSep = true;
8841                        pw.println("  PID mappings:");
8842                        printed = true;
8843                    }
8844                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8845                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8846                }
8847            }
8848        }
8849
8850        if (mForegroundProcesses.size() > 0) {
8851            synchronized (mPidsSelfLocked) {
8852                boolean printed = false;
8853                for (int i=0; i<mForegroundProcesses.size(); i++) {
8854                    ProcessRecord r = mPidsSelfLocked.get(
8855                            mForegroundProcesses.valueAt(i).pid);
8856                    if (dumpPackage != null && (r == null
8857                            || !dumpPackage.equals(r.info.packageName))) {
8858                        continue;
8859                    }
8860                    if (!printed) {
8861                        if (needSep) pw.println(" ");
8862                        needSep = true;
8863                        pw.println("  Foreground Processes:");
8864                        printed = true;
8865                    }
8866                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8867                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8868                }
8869            }
8870        }
8871
8872        if (mPersistentStartingProcesses.size() > 0) {
8873            if (needSep) pw.println(" ");
8874            needSep = true;
8875            pw.println("  Persisent processes that are starting:");
8876            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8877                    "Starting Norm", "Restarting PERS", dumpPackage);
8878        }
8879
8880        if (mRemovedProcesses.size() > 0) {
8881            if (needSep) pw.println(" ");
8882            needSep = true;
8883            pw.println("  Processes that are being removed:");
8884            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8885                    "Removed Norm", "Removed PERS", dumpPackage);
8886        }
8887
8888        if (mProcessesOnHold.size() > 0) {
8889            if (needSep) pw.println(" ");
8890            needSep = true;
8891            pw.println("  Processes that are on old until the system is ready:");
8892            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8893                    "OnHold Norm", "OnHold PERS", dumpPackage);
8894        }
8895
8896        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8897
8898        if (mProcessCrashTimes.getMap().size() > 0) {
8899            boolean printed = false;
8900            long now = SystemClock.uptimeMillis();
8901            for (Map.Entry<String, SparseArray<Long>> procs
8902                    : mProcessCrashTimes.getMap().entrySet()) {
8903                String pname = procs.getKey();
8904                SparseArray<Long> uids = procs.getValue();
8905                final int N = uids.size();
8906                for (int i=0; i<N; i++) {
8907                    int puid = uids.keyAt(i);
8908                    ProcessRecord r = mProcessNames.get(pname, puid);
8909                    if (dumpPackage != null && (r == null
8910                            || !dumpPackage.equals(r.info.packageName))) {
8911                        continue;
8912                    }
8913                    if (!printed) {
8914                        if (needSep) pw.println(" ");
8915                        needSep = true;
8916                        pw.println("  Time since processes crashed:");
8917                        printed = true;
8918                    }
8919                    pw.print("    Process "); pw.print(pname);
8920                            pw.print(" uid "); pw.print(puid);
8921                            pw.print(": last crashed ");
8922                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
8923                            pw.println(" ago");
8924                }
8925            }
8926        }
8927
8928        if (mBadProcesses.getMap().size() > 0) {
8929            boolean printed = false;
8930            for (Map.Entry<String, SparseArray<Long>> procs
8931                    : mBadProcesses.getMap().entrySet()) {
8932                String pname = procs.getKey();
8933                SparseArray<Long> uids = procs.getValue();
8934                final int N = uids.size();
8935                for (int i=0; i<N; i++) {
8936                    int puid = uids.keyAt(i);
8937                    ProcessRecord r = mProcessNames.get(pname, puid);
8938                    if (dumpPackage != null && (r == null
8939                            || !dumpPackage.equals(r.info.packageName))) {
8940                        continue;
8941                    }
8942                    if (!printed) {
8943                        if (needSep) pw.println(" ");
8944                        needSep = true;
8945                        pw.println("  Bad processes:");
8946                    }
8947                    pw.print("    Bad process "); pw.print(pname);
8948                            pw.print(" uid "); pw.print(puid);
8949                            pw.print(": crashed at time ");
8950                            pw.println(uids.valueAt(i));
8951                }
8952            }
8953        }
8954
8955        pw.println();
8956        pw.println("  mHomeProcess: " + mHomeProcess);
8957        pw.println("  mPreviousProcess: " + mPreviousProcess);
8958        if (dumpAll) {
8959            StringBuilder sb = new StringBuilder(128);
8960            sb.append("  mPreviousProcessVisibleTime: ");
8961            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
8962            pw.println(sb);
8963        }
8964        if (mHeavyWeightProcess != null) {
8965            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
8966        }
8967        pw.println("  mConfiguration: " + mConfiguration);
8968        if (dumpAll) {
8969            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
8970            if (mCompatModePackages.getPackages().size() > 0) {
8971                boolean printed = false;
8972                for (Map.Entry<String, Integer> entry
8973                        : mCompatModePackages.getPackages().entrySet()) {
8974                    String pkg = entry.getKey();
8975                    int mode = entry.getValue();
8976                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8977                        continue;
8978                    }
8979                    if (!printed) {
8980                        pw.println("  mScreenCompatPackages:");
8981                        printed = true;
8982                    }
8983                    pw.print("    "); pw.print(pkg); pw.print(": ");
8984                            pw.print(mode); pw.println();
8985                }
8986            }
8987        }
8988        if (mSleeping || mWentToSleep || mLockScreenShown) {
8989            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
8990                    + " mLockScreenShown " + mLockScreenShown);
8991        }
8992        if (mShuttingDown) {
8993            pw.println("  mShuttingDown=" + mShuttingDown);
8994        }
8995        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8996                || mOrigWaitForDebugger) {
8997            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8998                    + " mDebugTransient=" + mDebugTransient
8999                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9000        }
9001        if (mOpenGlTraceApp != null) {
9002            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9003        }
9004        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9005                || mProfileFd != null) {
9006            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9007            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9008            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9009                    + mAutoStopProfiler);
9010        }
9011        if (mAlwaysFinishActivities || mController != null) {
9012            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9013                    + " mController=" + mController);
9014        }
9015        if (dumpAll) {
9016            pw.println("  Total persistent processes: " + numPers);
9017            pw.println("  mStartRunning=" + mStartRunning
9018                    + " mProcessesReady=" + mProcessesReady
9019                    + " mSystemReady=" + mSystemReady);
9020            pw.println("  mBooting=" + mBooting
9021                    + " mBooted=" + mBooted
9022                    + " mFactoryTest=" + mFactoryTest);
9023            pw.print("  mLastPowerCheckRealtime=");
9024                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9025                    pw.println("");
9026            pw.print("  mLastPowerCheckUptime=");
9027                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9028                    pw.println("");
9029            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9030            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9031            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9032            pw.println("  mNumServiceProcs=" + mNumServiceProcs
9033                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9034        }
9035
9036        return true;
9037    }
9038
9039    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9040            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9041        if (mProcessesToGc.size() > 0) {
9042            boolean printed = false;
9043            long now = SystemClock.uptimeMillis();
9044            for (int i=0; i<mProcessesToGc.size(); i++) {
9045                ProcessRecord proc = mProcessesToGc.get(i);
9046                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9047                    continue;
9048                }
9049                if (!printed) {
9050                    if (needSep) pw.println(" ");
9051                    needSep = true;
9052                    pw.println("  Processes that are waiting to GC:");
9053                    printed = true;
9054                }
9055                pw.print("    Process "); pw.println(proc);
9056                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9057                        pw.print(", last gced=");
9058                        pw.print(now-proc.lastRequestedGc);
9059                        pw.print(" ms ago, last lowMem=");
9060                        pw.print(now-proc.lastLowMemory);
9061                        pw.println(" ms ago");
9062
9063            }
9064        }
9065        return needSep;
9066    }
9067
9068    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9069            int opti, boolean dumpAll) {
9070        boolean needSep = false;
9071
9072        if (mLruProcesses.size() > 0) {
9073            if (needSep) pw.println(" ");
9074            needSep = true;
9075            pw.println("  OOM levels:");
9076            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9077            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9078            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9079            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9080            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9081            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9082            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9083            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9084            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9085            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9086            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9087            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9088            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9089
9090            if (needSep) pw.println(" ");
9091            needSep = true;
9092            pw.println("  Process OOM control:");
9093            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9094                    "Proc", "PERS", true, null);
9095            needSep = true;
9096        }
9097
9098        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9099
9100        pw.println();
9101        pw.println("  mHomeProcess: " + mHomeProcess);
9102        pw.println("  mPreviousProcess: " + mPreviousProcess);
9103        if (mHeavyWeightProcess != null) {
9104            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9105        }
9106
9107        return true;
9108    }
9109
9110    /**
9111     * There are three ways to call this:
9112     *  - no provider specified: dump all the providers
9113     *  - a flattened component name that matched an existing provider was specified as the
9114     *    first arg: dump that one provider
9115     *  - the first arg isn't the flattened component name of an existing provider:
9116     *    dump all providers whose component contains the first arg as a substring
9117     */
9118    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9119            int opti, boolean dumpAll) {
9120        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9121    }
9122
9123    static class ItemMatcher {
9124        ArrayList<ComponentName> components;
9125        ArrayList<String> strings;
9126        ArrayList<Integer> objects;
9127        boolean all;
9128
9129        ItemMatcher() {
9130            all = true;
9131        }
9132
9133        void build(String name) {
9134            ComponentName componentName = ComponentName.unflattenFromString(name);
9135            if (componentName != null) {
9136                if (components == null) {
9137                    components = new ArrayList<ComponentName>();
9138                }
9139                components.add(componentName);
9140                all = false;
9141            } else {
9142                int objectId = 0;
9143                // Not a '/' separated full component name; maybe an object ID?
9144                try {
9145                    objectId = Integer.parseInt(name, 16);
9146                    if (objects == null) {
9147                        objects = new ArrayList<Integer>();
9148                    }
9149                    objects.add(objectId);
9150                    all = false;
9151                } catch (RuntimeException e) {
9152                    // Not an integer; just do string match.
9153                    if (strings == null) {
9154                        strings = new ArrayList<String>();
9155                    }
9156                    strings.add(name);
9157                    all = false;
9158                }
9159            }
9160        }
9161
9162        int build(String[] args, int opti) {
9163            for (; opti<args.length; opti++) {
9164                String name = args[opti];
9165                if ("--".equals(name)) {
9166                    return opti+1;
9167                }
9168                build(name);
9169            }
9170            return opti;
9171        }
9172
9173        boolean match(Object object, ComponentName comp) {
9174            if (all) {
9175                return true;
9176            }
9177            if (components != null) {
9178                for (int i=0; i<components.size(); i++) {
9179                    if (components.get(i).equals(comp)) {
9180                        return true;
9181                    }
9182                }
9183            }
9184            if (objects != null) {
9185                for (int i=0; i<objects.size(); i++) {
9186                    if (System.identityHashCode(object) == objects.get(i)) {
9187                        return true;
9188                    }
9189                }
9190            }
9191            if (strings != null) {
9192                String flat = comp.flattenToString();
9193                for (int i=0; i<strings.size(); i++) {
9194                    if (flat.contains(strings.get(i))) {
9195                        return true;
9196                    }
9197                }
9198            }
9199            return false;
9200        }
9201    }
9202
9203    /**
9204     * There are three things that cmd can be:
9205     *  - a flattened component name that matches an existing activity
9206     *  - the cmd arg isn't the flattened component name of an existing activity:
9207     *    dump all activity whose component contains the cmd as a substring
9208     *  - A hex number of the ActivityRecord object instance.
9209     */
9210    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9211            int opti, boolean dumpAll) {
9212        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9213
9214        if ("all".equals(name)) {
9215            synchronized (this) {
9216                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9217                    activities.add(r1);
9218                }
9219            }
9220        } else if ("top".equals(name)) {
9221            synchronized (this) {
9222                final int N = mMainStack.mHistory.size();
9223                if (N > 0) {
9224                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9225                }
9226            }
9227        } else {
9228            ItemMatcher matcher = new ItemMatcher();
9229            matcher.build(name);
9230
9231            synchronized (this) {
9232                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9233                    if (matcher.match(r1, r1.intent.getComponent())) {
9234                        activities.add(r1);
9235                    }
9236                }
9237            }
9238        }
9239
9240        if (activities.size() <= 0) {
9241            return false;
9242        }
9243
9244        String[] newArgs = new String[args.length - opti];
9245        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9246
9247        TaskRecord lastTask = null;
9248        boolean needSep = false;
9249        for (int i=activities.size()-1; i>=0; i--) {
9250            ActivityRecord r = (ActivityRecord)activities.get(i);
9251            if (needSep) {
9252                pw.println();
9253            }
9254            needSep = true;
9255            synchronized (this) {
9256                if (lastTask != r.task) {
9257                    lastTask = r.task;
9258                    pw.print("TASK "); pw.print(lastTask.affinity);
9259                            pw.print(" id="); pw.println(lastTask.taskId);
9260                    if (dumpAll) {
9261                        lastTask.dump(pw, "  ");
9262                    }
9263                }
9264            }
9265            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9266        }
9267        return true;
9268    }
9269
9270    /**
9271     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9272     * there is a thread associated with the activity.
9273     */
9274    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9275            final ActivityRecord r, String[] args, boolean dumpAll) {
9276        String innerPrefix = prefix + "  ";
9277        synchronized (this) {
9278            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9279                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9280                    pw.print(" pid=");
9281                    if (r.app != null) pw.println(r.app.pid);
9282                    else pw.println("(not running)");
9283            if (dumpAll) {
9284                r.dump(pw, innerPrefix);
9285            }
9286        }
9287        if (r.app != null && r.app.thread != null) {
9288            // flush anything that is already in the PrintWriter since the thread is going
9289            // to write to the file descriptor directly
9290            pw.flush();
9291            try {
9292                TransferPipe tp = new TransferPipe();
9293                try {
9294                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9295                            r.appToken, innerPrefix, args);
9296                    tp.go(fd);
9297                } finally {
9298                    tp.kill();
9299                }
9300            } catch (IOException e) {
9301                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9302            } catch (RemoteException e) {
9303                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9304            }
9305        }
9306    }
9307
9308    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9309            int opti, boolean dumpAll, String dumpPackage) {
9310        boolean needSep = false;
9311
9312        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9313        if (dumpAll) {
9314            if (mRegisteredReceivers.size() > 0) {
9315                boolean printed = false;
9316                Iterator it = mRegisteredReceivers.values().iterator();
9317                while (it.hasNext()) {
9318                    ReceiverList r = (ReceiverList)it.next();
9319                    if (dumpPackage != null && (r.app == null ||
9320                            !dumpPackage.equals(r.app.info.packageName))) {
9321                        continue;
9322                    }
9323                    if (!printed) {
9324                        pw.println("  Registered Receivers:");
9325                        needSep = true;
9326                        printed = true;
9327                    }
9328                    pw.print("  * "); pw.println(r);
9329                    r.dump(pw, "    ");
9330                }
9331            }
9332
9333            if (mReceiverResolver.dump(pw, needSep ?
9334                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9335                    "    ", dumpPackage, false)) {
9336                needSep = true;
9337            }
9338        }
9339
9340        for (BroadcastQueue q : mBroadcastQueues) {
9341            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9342        }
9343
9344        needSep = true;
9345
9346        if (mStickyBroadcasts != null && dumpPackage == null) {
9347            if (needSep) {
9348                pw.println();
9349            }
9350            needSep = true;
9351            pw.println("  Sticky broadcasts:");
9352            StringBuilder sb = new StringBuilder(128);
9353            for (Map.Entry<String, ArrayList<Intent>> ent
9354                    : mStickyBroadcasts.entrySet()) {
9355                pw.print("  * Sticky action "); pw.print(ent.getKey());
9356                if (dumpAll) {
9357                    pw.println(":");
9358                    ArrayList<Intent> intents = ent.getValue();
9359                    final int N = intents.size();
9360                    for (int i=0; i<N; i++) {
9361                        sb.setLength(0);
9362                        sb.append("    Intent: ");
9363                        intents.get(i).toShortString(sb, false, true, false, false);
9364                        pw.println(sb.toString());
9365                        Bundle bundle = intents.get(i).getExtras();
9366                        if (bundle != null) {
9367                            pw.print("      ");
9368                            pw.println(bundle.toString());
9369                        }
9370                    }
9371                } else {
9372                    pw.println("");
9373                }
9374            }
9375            needSep = true;
9376        }
9377
9378        if (dumpAll) {
9379            pw.println();
9380            for (BroadcastQueue queue : mBroadcastQueues) {
9381                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9382                        + queue.mBroadcastsScheduled);
9383            }
9384            pw.println("  mHandler:");
9385            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9386            needSep = true;
9387        }
9388
9389        return needSep;
9390    }
9391
9392    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9393            int opti, boolean dumpAll, String dumpPackage) {
9394        boolean needSep = true;
9395
9396        ItemMatcher matcher = new ItemMatcher();
9397        matcher.build(args, opti);
9398
9399        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9400
9401        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9402
9403        if (mLaunchingProviders.size() > 0) {
9404            boolean printed = false;
9405            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9406                ContentProviderRecord r = mLaunchingProviders.get(i);
9407                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9408                    continue;
9409                }
9410                if (!printed) {
9411                    if (needSep) pw.println(" ");
9412                    needSep = true;
9413                    pw.println("  Launching content providers:");
9414                    printed = true;
9415                }
9416                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9417                        pw.println(r);
9418            }
9419        }
9420
9421        if (mGrantedUriPermissions.size() > 0) {
9422            if (needSep) pw.println();
9423            needSep = true;
9424            pw.println("Granted Uri Permissions:");
9425            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9426                int uid = mGrantedUriPermissions.keyAt(i);
9427                HashMap<Uri, UriPermission> perms
9428                        = mGrantedUriPermissions.valueAt(i);
9429                pw.print("  * UID "); pw.print(uid);
9430                        pw.println(" holds:");
9431                for (UriPermission perm : perms.values()) {
9432                    pw.print("    "); pw.println(perm);
9433                    if (dumpAll) {
9434                        perm.dump(pw, "      ");
9435                    }
9436                }
9437            }
9438            needSep = true;
9439        }
9440
9441        return needSep;
9442    }
9443
9444    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9445            int opti, boolean dumpAll, String dumpPackage) {
9446        boolean needSep = false;
9447
9448        if (mIntentSenderRecords.size() > 0) {
9449            boolean printed = false;
9450            Iterator<WeakReference<PendingIntentRecord>> it
9451                    = mIntentSenderRecords.values().iterator();
9452            while (it.hasNext()) {
9453                WeakReference<PendingIntentRecord> ref = it.next();
9454                PendingIntentRecord rec = ref != null ? ref.get(): null;
9455                if (dumpPackage != null && (rec == null
9456                        || !dumpPackage.equals(rec.key.packageName))) {
9457                    continue;
9458                }
9459                if (!printed) {
9460                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9461                    printed = true;
9462                }
9463                needSep = true;
9464                if (rec != null) {
9465                    pw.print("  * "); pw.println(rec);
9466                    if (dumpAll) {
9467                        rec.dump(pw, "    ");
9468                    }
9469                } else {
9470                    pw.print("  * "); pw.println(ref);
9471                }
9472            }
9473        }
9474
9475        return needSep;
9476    }
9477
9478    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9479            String prefix, String label, boolean complete, boolean brief, boolean client,
9480            String dumpPackage) {
9481        TaskRecord lastTask = null;
9482        boolean needNL = false;
9483        final String innerPrefix = prefix + "      ";
9484        final String[] args = new String[0];
9485        for (int i=list.size()-1; i>=0; i--) {
9486            final ActivityRecord r = (ActivityRecord)list.get(i);
9487            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9488                continue;
9489            }
9490            final boolean full = !brief && (complete || !r.isInHistory());
9491            if (needNL) {
9492                pw.println(" ");
9493                needNL = false;
9494            }
9495            if (lastTask != r.task) {
9496                lastTask = r.task;
9497                pw.print(prefix);
9498                pw.print(full ? "* " : "  ");
9499                pw.println(lastTask);
9500                if (full) {
9501                    lastTask.dump(pw, prefix + "  ");
9502                } else if (complete) {
9503                    // Complete + brief == give a summary.  Isn't that obvious?!?
9504                    if (lastTask.intent != null) {
9505                        pw.print(prefix); pw.print("  ");
9506                                pw.println(lastTask.intent.toInsecureStringWithClip());
9507                    }
9508                }
9509            }
9510            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9511            pw.print(" #"); pw.print(i); pw.print(": ");
9512            pw.println(r);
9513            if (full) {
9514                r.dump(pw, innerPrefix);
9515            } else if (complete) {
9516                // Complete + brief == give a summary.  Isn't that obvious?!?
9517                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9518                if (r.app != null) {
9519                    pw.print(innerPrefix); pw.println(r.app);
9520                }
9521            }
9522            if (client && r.app != null && r.app.thread != null) {
9523                // flush anything that is already in the PrintWriter since the thread is going
9524                // to write to the file descriptor directly
9525                pw.flush();
9526                try {
9527                    TransferPipe tp = new TransferPipe();
9528                    try {
9529                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9530                                r.appToken, innerPrefix, args);
9531                        // Short timeout, since blocking here can
9532                        // deadlock with the application.
9533                        tp.go(fd, 2000);
9534                    } finally {
9535                        tp.kill();
9536                    }
9537                } catch (IOException e) {
9538                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9539                } catch (RemoteException e) {
9540                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9541                }
9542                needNL = true;
9543            }
9544        }
9545    }
9546
9547    private static String buildOomTag(String prefix, String space, int val, int base) {
9548        if (val == base) {
9549            if (space == null) return prefix;
9550            return prefix + "  ";
9551        }
9552        return prefix + "+" + Integer.toString(val-base);
9553    }
9554
9555    private static final int dumpProcessList(PrintWriter pw,
9556            ActivityManagerService service, List list,
9557            String prefix, String normalLabel, String persistentLabel,
9558            String dumpPackage) {
9559        int numPers = 0;
9560        final int N = list.size()-1;
9561        for (int i=N; i>=0; i--) {
9562            ProcessRecord r = (ProcessRecord)list.get(i);
9563            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9564                continue;
9565            }
9566            pw.println(String.format("%s%s #%2d: %s",
9567                    prefix, (r.persistent ? persistentLabel : normalLabel),
9568                    i, r.toString()));
9569            if (r.persistent) {
9570                numPers++;
9571            }
9572        }
9573        return numPers;
9574    }
9575
9576    private static final boolean dumpProcessOomList(PrintWriter pw,
9577            ActivityManagerService service, List<ProcessRecord> origList,
9578            String prefix, String normalLabel, String persistentLabel,
9579            boolean inclDetails, String dumpPackage) {
9580
9581        ArrayList<Pair<ProcessRecord, Integer>> list
9582                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9583        for (int i=0; i<origList.size(); i++) {
9584            ProcessRecord r = origList.get(i);
9585            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9586                continue;
9587            }
9588            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9589        }
9590
9591        if (list.size() <= 0) {
9592            return false;
9593        }
9594
9595        Comparator<Pair<ProcessRecord, Integer>> comparator
9596                = new Comparator<Pair<ProcessRecord, Integer>>() {
9597            @Override
9598            public int compare(Pair<ProcessRecord, Integer> object1,
9599                    Pair<ProcessRecord, Integer> object2) {
9600                if (object1.first.setAdj != object2.first.setAdj) {
9601                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9602                }
9603                if (object1.second.intValue() != object2.second.intValue()) {
9604                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9605                }
9606                return 0;
9607            }
9608        };
9609
9610        Collections.sort(list, comparator);
9611
9612        final long curRealtime = SystemClock.elapsedRealtime();
9613        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9614        final long curUptime = SystemClock.uptimeMillis();
9615        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9616
9617        for (int i=list.size()-1; i>=0; i--) {
9618            ProcessRecord r = list.get(i).first;
9619            String oomAdj;
9620            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9621                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9622            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9623                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9624            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9625                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9626            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9627                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9628            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9629                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9630            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9631                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9632            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9633                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9634            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9635                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9636            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9637                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9638            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9639                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9640            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9641                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9642            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9643                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9644            } else {
9645                oomAdj = Integer.toString(r.setAdj);
9646            }
9647            String schedGroup;
9648            switch (r.setSchedGroup) {
9649                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9650                    schedGroup = "B";
9651                    break;
9652                case Process.THREAD_GROUP_DEFAULT:
9653                    schedGroup = "F";
9654                    break;
9655                default:
9656                    schedGroup = Integer.toString(r.setSchedGroup);
9657                    break;
9658            }
9659            String foreground;
9660            if (r.foregroundActivities) {
9661                foreground = "A";
9662            } else if (r.foregroundServices) {
9663                foreground = "S";
9664            } else {
9665                foreground = " ";
9666            }
9667            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9668                    prefix, (r.persistent ? persistentLabel : normalLabel),
9669                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9670                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9671            if (r.adjSource != null || r.adjTarget != null) {
9672                pw.print(prefix);
9673                pw.print("    ");
9674                if (r.adjTarget instanceof ComponentName) {
9675                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9676                } else if (r.adjTarget != null) {
9677                    pw.print(r.adjTarget.toString());
9678                } else {
9679                    pw.print("{null}");
9680                }
9681                pw.print("<=");
9682                if (r.adjSource instanceof ProcessRecord) {
9683                    pw.print("Proc{");
9684                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9685                    pw.println("}");
9686                } else if (r.adjSource != null) {
9687                    pw.println(r.adjSource.toString());
9688                } else {
9689                    pw.println("{null}");
9690                }
9691            }
9692            if (inclDetails) {
9693                pw.print(prefix);
9694                pw.print("    ");
9695                pw.print("oom: max="); pw.print(r.maxAdj);
9696                pw.print(" hidden="); pw.print(r.hiddenAdj);
9697                pw.print(" curRaw="); pw.print(r.curRawAdj);
9698                pw.print(" setRaw="); pw.print(r.setRawAdj);
9699                pw.print(" cur="); pw.print(r.curAdj);
9700                pw.print(" set="); pw.println(r.setAdj);
9701                pw.print(prefix);
9702                pw.print("    ");
9703                pw.print("keeping="); pw.print(r.keeping);
9704                pw.print(" hidden="); pw.print(r.hidden);
9705                pw.print(" empty="); pw.print(r.empty);
9706                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9707
9708                if (!r.keeping) {
9709                    if (r.lastWakeTime != 0) {
9710                        long wtime;
9711                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9712                        synchronized (stats) {
9713                            wtime = stats.getProcessWakeTime(r.info.uid,
9714                                    r.pid, curRealtime);
9715                        }
9716                        long timeUsed = wtime - r.lastWakeTime;
9717                        pw.print(prefix);
9718                        pw.print("    ");
9719                        pw.print("keep awake over ");
9720                        TimeUtils.formatDuration(realtimeSince, pw);
9721                        pw.print(" used ");
9722                        TimeUtils.formatDuration(timeUsed, pw);
9723                        pw.print(" (");
9724                        pw.print((timeUsed*100)/realtimeSince);
9725                        pw.println("%)");
9726                    }
9727                    if (r.lastCpuTime != 0) {
9728                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9729                        pw.print(prefix);
9730                        pw.print("    ");
9731                        pw.print("run cpu over ");
9732                        TimeUtils.formatDuration(uptimeSince, pw);
9733                        pw.print(" used ");
9734                        TimeUtils.formatDuration(timeUsed, pw);
9735                        pw.print(" (");
9736                        pw.print((timeUsed*100)/uptimeSince);
9737                        pw.println("%)");
9738                    }
9739                }
9740            }
9741        }
9742        return true;
9743    }
9744
9745    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9746        ArrayList<ProcessRecord> procs;
9747        synchronized (this) {
9748            if (args != null && args.length > start
9749                    && args[start].charAt(0) != '-') {
9750                procs = new ArrayList<ProcessRecord>();
9751                int pid = -1;
9752                try {
9753                    pid = Integer.parseInt(args[start]);
9754                } catch (NumberFormatException e) {
9755
9756                }
9757                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9758                    ProcessRecord proc = mLruProcesses.get(i);
9759                    if (proc.pid == pid) {
9760                        procs.add(proc);
9761                    } else if (proc.processName.equals(args[start])) {
9762                        procs.add(proc);
9763                    }
9764                }
9765                if (procs.size() <= 0) {
9766                    pw.println("No process found for: " + args[start]);
9767                    return null;
9768                }
9769            } else {
9770                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9771            }
9772        }
9773        return procs;
9774    }
9775
9776    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9777            PrintWriter pw, String[] args) {
9778        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9779        if (procs == null) {
9780            return;
9781        }
9782
9783        long uptime = SystemClock.uptimeMillis();
9784        long realtime = SystemClock.elapsedRealtime();
9785        pw.println("Applications Graphics Acceleration Info:");
9786        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9787
9788        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9789            ProcessRecord r = procs.get(i);
9790            if (r.thread != null) {
9791                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9792                pw.flush();
9793                try {
9794                    TransferPipe tp = new TransferPipe();
9795                    try {
9796                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9797                        tp.go(fd);
9798                    } finally {
9799                        tp.kill();
9800                    }
9801                } catch (IOException e) {
9802                    pw.println("Failure while dumping the app: " + r);
9803                    pw.flush();
9804                } catch (RemoteException e) {
9805                    pw.println("Got a RemoteException while dumping the app " + r);
9806                    pw.flush();
9807                }
9808            }
9809        }
9810    }
9811
9812    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9813        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9814        if (procs == null) {
9815            return;
9816        }
9817
9818        pw.println("Applications Database Info:");
9819
9820        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9821            ProcessRecord r = procs.get(i);
9822            if (r.thread != null) {
9823                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9824                pw.flush();
9825                try {
9826                    TransferPipe tp = new TransferPipe();
9827                    try {
9828                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9829                        tp.go(fd);
9830                    } finally {
9831                        tp.kill();
9832                    }
9833                } catch (IOException e) {
9834                    pw.println("Failure while dumping the app: " + r);
9835                    pw.flush();
9836                } catch (RemoteException e) {
9837                    pw.println("Got a RemoteException while dumping the app " + r);
9838                    pw.flush();
9839                }
9840            }
9841        }
9842    }
9843
9844    final static class MemItem {
9845        final String label;
9846        final String shortLabel;
9847        final long pss;
9848        final int id;
9849        ArrayList<MemItem> subitems;
9850
9851        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9852            label = _label;
9853            shortLabel = _shortLabel;
9854            pss = _pss;
9855            id = _id;
9856        }
9857    }
9858
9859    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9860            boolean sort) {
9861        if (sort) {
9862            Collections.sort(items, new Comparator<MemItem>() {
9863                @Override
9864                public int compare(MemItem lhs, MemItem rhs) {
9865                    if (lhs.pss < rhs.pss) {
9866                        return 1;
9867                    } else if (lhs.pss > rhs.pss) {
9868                        return -1;
9869                    }
9870                    return 0;
9871                }
9872            });
9873        }
9874
9875        for (int i=0; i<items.size(); i++) {
9876            MemItem mi = items.get(i);
9877            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9878            if (mi.subitems != null) {
9879                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9880            }
9881        }
9882    }
9883
9884    // These are in KB.
9885    static final long[] DUMP_MEM_BUCKETS = new long[] {
9886        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9887        120*1024, 160*1024, 200*1024,
9888        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9889        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9890    };
9891
9892    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9893            boolean stackLike) {
9894        int start = label.lastIndexOf('.');
9895        if (start >= 0) start++;
9896        else start = 0;
9897        int end = label.length();
9898        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9899            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9900                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9901                out.append(bucket);
9902                out.append(stackLike ? "MB." : "MB ");
9903                out.append(label, start, end);
9904                return;
9905            }
9906        }
9907        out.append(memKB/1024);
9908        out.append(stackLike ? "MB." : "MB ");
9909        out.append(label, start, end);
9910    }
9911
9912    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9913            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9914            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9915            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9916            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9917    };
9918    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9919            "System", "Persistent", "Foreground",
9920            "Visible", "Perceptible", "Heavy Weight",
9921            "Backup", "A Services", "Home", "Previous",
9922            "B Services", "Background"
9923    };
9924
9925    final void dumpApplicationMemoryUsage(FileDescriptor fd,
9926            PrintWriter pw, String prefix, String[] args, boolean brief,
9927            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
9928        boolean dumpAll = false;
9929        boolean oomOnly = false;
9930
9931        int opti = 0;
9932        while (opti < args.length) {
9933            String opt = args[opti];
9934            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9935                break;
9936            }
9937            opti++;
9938            if ("-a".equals(opt)) {
9939                dumpAll = true;
9940            } else if ("--oom".equals(opt)) {
9941                oomOnly = true;
9942            } else if ("-h".equals(opt)) {
9943                pw.println("meminfo dump options: [-a] [--oom] [process]");
9944                pw.println("  -a: include all available information for each process.");
9945                pw.println("  --oom: only show processes organized by oom adj.");
9946                pw.println("If [process] is specified it can be the name or ");
9947                pw.println("pid of a specific process to dump.");
9948                return;
9949            } else {
9950                pw.println("Unknown argument: " + opt + "; use -h for help");
9951            }
9952        }
9953
9954        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
9955        if (procs == null) {
9956            return;
9957        }
9958
9959        final boolean isCheckinRequest = scanArgs(args, "--checkin");
9960        long uptime = SystemClock.uptimeMillis();
9961        long realtime = SystemClock.elapsedRealtime();
9962
9963        if (procs.size() == 1 || isCheckinRequest) {
9964            dumpAll = true;
9965        }
9966
9967        if (isCheckinRequest) {
9968            // short checkin version
9969            pw.println(uptime + "," + realtime);
9970            pw.flush();
9971        } else {
9972            pw.println("Applications Memory Usage (kB):");
9973            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9974        }
9975
9976        String[] innerArgs = new String[args.length-opti];
9977        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9978
9979        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9980        long nativePss=0, dalvikPss=0, otherPss=0;
9981        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9982
9983        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9984        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9985                new ArrayList[DUMP_MEM_OOM_LABEL.length];
9986
9987        long totalPss = 0;
9988
9989        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9990            ProcessRecord r = procs.get(i);
9991            if (r.thread != null) {
9992                if (!isCheckinRequest && dumpAll) {
9993                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9994                    pw.flush();
9995                }
9996                Debug.MemoryInfo mi = null;
9997                if (dumpAll) {
9998                    try {
9999                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10000                    } catch (RemoteException e) {
10001                        if (!isCheckinRequest) {
10002                            pw.println("Got RemoteException!");
10003                            pw.flush();
10004                        }
10005                    }
10006                } else {
10007                    mi = new Debug.MemoryInfo();
10008                    Debug.getMemoryInfo(r.pid, mi);
10009                }
10010
10011                if (!isCheckinRequest && mi != null) {
10012                    long myTotalPss = mi.getTotalPss();
10013                    totalPss += myTotalPss;
10014                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10015                            r.processName, myTotalPss, 0);
10016                    procMems.add(pssItem);
10017
10018                    nativePss += mi.nativePss;
10019                    dalvikPss += mi.dalvikPss;
10020                    otherPss += mi.otherPss;
10021                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10022                        long mem = mi.getOtherPss(j);
10023                        miscPss[j] += mem;
10024                        otherPss -= mem;
10025                    }
10026
10027                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10028                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10029                                || oomIndex == (oomPss.length-1)) {
10030                            oomPss[oomIndex] += myTotalPss;
10031                            if (oomProcs[oomIndex] == null) {
10032                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10033                            }
10034                            oomProcs[oomIndex].add(pssItem);
10035                            break;
10036                        }
10037                    }
10038                }
10039            }
10040        }
10041
10042        if (!isCheckinRequest && procs.size() > 1) {
10043            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10044
10045            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10046            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10047            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10048            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10049                String label = Debug.MemoryInfo.getOtherLabel(j);
10050                catMems.add(new MemItem(label, label, miscPss[j], j));
10051            }
10052
10053            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10054            for (int j=0; j<oomPss.length; j++) {
10055                if (oomPss[j] != 0) {
10056                    String label = DUMP_MEM_OOM_LABEL[j];
10057                    MemItem item = new MemItem(label, label, oomPss[j],
10058                            DUMP_MEM_OOM_ADJ[j]);
10059                    item.subitems = oomProcs[j];
10060                    oomMems.add(item);
10061                }
10062            }
10063
10064            if (outTag != null || outStack != null) {
10065                if (outTag != null) {
10066                    appendMemBucket(outTag, totalPss, "total", false);
10067                }
10068                if (outStack != null) {
10069                    appendMemBucket(outStack, totalPss, "total", true);
10070                }
10071                boolean firstLine = true;
10072                for (int i=0; i<oomMems.size(); i++) {
10073                    MemItem miCat = oomMems.get(i);
10074                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10075                        continue;
10076                    }
10077                    if (miCat.id < ProcessList.SERVICE_ADJ
10078                            || miCat.id == ProcessList.HOME_APP_ADJ
10079                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10080                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10081                            outTag.append(" / ");
10082                        }
10083                        if (outStack != null) {
10084                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10085                                if (firstLine) {
10086                                    outStack.append(":");
10087                                    firstLine = false;
10088                                }
10089                                outStack.append("\n\t at ");
10090                            } else {
10091                                outStack.append("$");
10092                            }
10093                        }
10094                        for (int j=0; j<miCat.subitems.size(); j++) {
10095                            MemItem mi = miCat.subitems.get(j);
10096                            if (j > 0) {
10097                                if (outTag != null) {
10098                                    outTag.append(" ");
10099                                }
10100                                if (outStack != null) {
10101                                    outStack.append("$");
10102                                }
10103                            }
10104                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10105                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10106                            }
10107                            if (outStack != null) {
10108                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10109                            }
10110                        }
10111                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10112                            outStack.append("(");
10113                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10114                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10115                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10116                                    outStack.append(":");
10117                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10118                                }
10119                            }
10120                            outStack.append(")");
10121                        }
10122                    }
10123                }
10124            }
10125
10126            if (!brief && !oomOnly) {
10127                pw.println();
10128                pw.println("Total PSS by process:");
10129                dumpMemItems(pw, "  ", procMems, true);
10130                pw.println();
10131            }
10132            pw.println("Total PSS by OOM adjustment:");
10133            dumpMemItems(pw, "  ", oomMems, false);
10134            if (!oomOnly) {
10135                PrintWriter out = categoryPw != null ? categoryPw : pw;
10136                out.println();
10137                out.println("Total PSS by category:");
10138                dumpMemItems(out, "  ", catMems, true);
10139            }
10140            pw.println();
10141            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10142            final int[] SINGLE_LONG_FORMAT = new int[] {
10143                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10144            };
10145            long[] longOut = new long[1];
10146            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10147                    SINGLE_LONG_FORMAT, null, longOut, null);
10148            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10149            longOut[0] = 0;
10150            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10151                    SINGLE_LONG_FORMAT, null, longOut, null);
10152            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10153            longOut[0] = 0;
10154            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10155                    SINGLE_LONG_FORMAT, null, longOut, null);
10156            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10157            longOut[0] = 0;
10158            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10159                    SINGLE_LONG_FORMAT, null, longOut, null);
10160            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10161            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10162                    pw.print(shared); pw.println(" kB");
10163            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10164                    pw.print(voltile); pw.println(" kB volatile");
10165        }
10166    }
10167
10168    /**
10169     * Searches array of arguments for the specified string
10170     * @param args array of argument strings
10171     * @param value value to search for
10172     * @return true if the value is contained in the array
10173     */
10174    private static boolean scanArgs(String[] args, String value) {
10175        if (args != null) {
10176            for (String arg : args) {
10177                if (value.equals(arg)) {
10178                    return true;
10179                }
10180            }
10181        }
10182        return false;
10183    }
10184
10185    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10186            ContentProviderRecord cpr, boolean always) {
10187        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10188
10189        if (!inLaunching || always) {
10190            synchronized (cpr) {
10191                cpr.launchingApp = null;
10192                cpr.notifyAll();
10193            }
10194            mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10195            String names[] = cpr.info.authority.split(";");
10196            for (int j = 0; j < names.length; j++) {
10197                mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10198            }
10199        }
10200
10201        for (int i=0; i<cpr.connections.size(); i++) {
10202            ContentProviderConnection conn = cpr.connections.get(i);
10203            if (conn.waiting) {
10204                // If this connection is waiting for the provider, then we don't
10205                // need to mess with its process unless we are always removing
10206                // or for some reason the provider is not currently launching.
10207                if (inLaunching && !always) {
10208                    continue;
10209                }
10210            }
10211            ProcessRecord capp = conn.client;
10212            conn.dead = true;
10213            if (conn.stableCount > 0) {
10214                if (!capp.persistent && capp.thread != null
10215                        && capp.pid != 0
10216                        && capp.pid != MY_PID) {
10217                    Slog.i(TAG, "Kill " + capp.processName
10218                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10219                            + " in dying process " + (proc != null ? proc.processName : "??"));
10220                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10221                            capp.processName, capp.setAdj, "dying provider "
10222                                    + cpr.name.toShortString());
10223                    Process.killProcessQuiet(capp.pid);
10224                }
10225            } else if (capp.thread != null && conn.provider.provider != null) {
10226                try {
10227                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10228                } catch (RemoteException e) {
10229                }
10230                // In the protocol here, we don't expect the client to correctly
10231                // clean up this connection, we'll just remove it.
10232                cpr.connections.remove(i);
10233                conn.client.conProviders.remove(conn);
10234            }
10235        }
10236
10237        if (inLaunching && always) {
10238            mLaunchingProviders.remove(cpr);
10239        }
10240        return inLaunching;
10241    }
10242
10243    /**
10244     * Main code for cleaning up a process when it has gone away.  This is
10245     * called both as a result of the process dying, or directly when stopping
10246     * a process when running in single process mode.
10247     */
10248    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10249            boolean restarting, boolean allowRestart, int index) {
10250        if (index >= 0) {
10251            mLruProcesses.remove(index);
10252        }
10253
10254        mProcessesToGc.remove(app);
10255
10256        // Dismiss any open dialogs.
10257        if (app.crashDialog != null) {
10258            app.crashDialog.dismiss();
10259            app.crashDialog = null;
10260        }
10261        if (app.anrDialog != null) {
10262            app.anrDialog.dismiss();
10263            app.anrDialog = null;
10264        }
10265        if (app.waitDialog != null) {
10266            app.waitDialog.dismiss();
10267            app.waitDialog = null;
10268        }
10269
10270        app.crashing = false;
10271        app.notResponding = false;
10272
10273        app.resetPackageList();
10274        app.unlinkDeathRecipient();
10275        app.thread = null;
10276        app.forcingToForeground = null;
10277        app.foregroundServices = false;
10278        app.foregroundActivities = false;
10279        app.hasShownUi = false;
10280        app.hasAboveClient = false;
10281
10282        mServices.killServicesLocked(app, allowRestart);
10283
10284        boolean restart = false;
10285
10286        // Remove published content providers.
10287        if (!app.pubProviders.isEmpty()) {
10288            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10289            while (it.hasNext()) {
10290                ContentProviderRecord cpr = it.next();
10291
10292                final boolean always = app.bad || !allowRestart;
10293                if (removeDyingProviderLocked(app, cpr, always) || always) {
10294                    // We left the provider in the launching list, need to
10295                    // restart it.
10296                    restart = true;
10297                }
10298
10299                cpr.provider = null;
10300                cpr.proc = null;
10301            }
10302            app.pubProviders.clear();
10303        }
10304
10305        // Take care of any launching providers waiting for this process.
10306        if (checkAppInLaunchingProvidersLocked(app, false)) {
10307            restart = true;
10308        }
10309
10310        // Unregister from connected content providers.
10311        if (!app.conProviders.isEmpty()) {
10312            for (int i=0; i<app.conProviders.size(); i++) {
10313                ContentProviderConnection conn = app.conProviders.get(i);
10314                conn.provider.connections.remove(conn);
10315            }
10316            app.conProviders.clear();
10317        }
10318
10319        // At this point there may be remaining entries in mLaunchingProviders
10320        // where we were the only one waiting, so they are no longer of use.
10321        // Look for these and clean up if found.
10322        // XXX Commented out for now.  Trying to figure out a way to reproduce
10323        // the actual situation to identify what is actually going on.
10324        if (false) {
10325            for (int i=0; i<mLaunchingProviders.size(); i++) {
10326                ContentProviderRecord cpr = (ContentProviderRecord)
10327                        mLaunchingProviders.get(i);
10328                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10329                    synchronized (cpr) {
10330                        cpr.launchingApp = null;
10331                        cpr.notifyAll();
10332                    }
10333                }
10334            }
10335        }
10336
10337        skipCurrentReceiverLocked(app);
10338
10339        // Unregister any receivers.
10340        if (app.receivers.size() > 0) {
10341            Iterator<ReceiverList> it = app.receivers.iterator();
10342            while (it.hasNext()) {
10343                removeReceiverLocked(it.next());
10344            }
10345            app.receivers.clear();
10346        }
10347
10348        // If the app is undergoing backup, tell the backup manager about it
10349        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10350            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10351            try {
10352                IBackupManager bm = IBackupManager.Stub.asInterface(
10353                        ServiceManager.getService(Context.BACKUP_SERVICE));
10354                bm.agentDisconnected(app.info.packageName);
10355            } catch (RemoteException e) {
10356                // can't happen; backup manager is local
10357            }
10358        }
10359
10360        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10361            ProcessChangeItem item = mPendingProcessChanges.get(i);
10362            if (item.pid == app.pid) {
10363                mPendingProcessChanges.remove(i);
10364                mAvailProcessChanges.add(item);
10365            }
10366        }
10367        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10368
10369        // If the caller is restarting this app, then leave it in its
10370        // current lists and let the caller take care of it.
10371        if (restarting) {
10372            return;
10373        }
10374
10375        if (!app.persistent || app.isolated) {
10376            if (DEBUG_PROCESSES) Slog.v(TAG,
10377                    "Removing non-persistent process during cleanup: " + app);
10378            mProcessNames.remove(app.processName, app.uid);
10379            mIsolatedProcesses.remove(app.uid);
10380            if (mHeavyWeightProcess == app) {
10381                mHeavyWeightProcess = null;
10382                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10383            }
10384        } else if (!app.removed) {
10385            // This app is persistent, so we need to keep its record around.
10386            // If it is not already on the pending app list, add it there
10387            // and start a new process for it.
10388            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10389                mPersistentStartingProcesses.add(app);
10390                restart = true;
10391            }
10392        }
10393        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10394                "Clean-up removing on hold: " + app);
10395        mProcessesOnHold.remove(app);
10396
10397        if (app == mHomeProcess) {
10398            mHomeProcess = null;
10399        }
10400        if (app == mPreviousProcess) {
10401            mPreviousProcess = null;
10402        }
10403
10404        if (restart && !app.isolated) {
10405            // We have components that still need to be running in the
10406            // process, so re-launch it.
10407            mProcessNames.put(app.processName, app.uid, app);
10408            startProcessLocked(app, "restart", app.processName);
10409        } else if (app.pid > 0 && app.pid != MY_PID) {
10410            // Goodbye!
10411            synchronized (mPidsSelfLocked) {
10412                mPidsSelfLocked.remove(app.pid);
10413                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10414            }
10415            app.setPid(0);
10416        }
10417    }
10418
10419    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10420        // Look through the content providers we are waiting to have launched,
10421        // and if any run in this process then either schedule a restart of
10422        // the process or kill the client waiting for it if this process has
10423        // gone bad.
10424        int NL = mLaunchingProviders.size();
10425        boolean restart = false;
10426        for (int i=0; i<NL; i++) {
10427            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10428            if (cpr.launchingApp == app) {
10429                if (!alwaysBad && !app.bad) {
10430                    restart = true;
10431                } else {
10432                    removeDyingProviderLocked(app, cpr, true);
10433                    NL = mLaunchingProviders.size();
10434                }
10435            }
10436        }
10437        return restart;
10438    }
10439
10440    // =========================================================
10441    // SERVICES
10442    // =========================================================
10443
10444    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10445            int flags) {
10446        enforceNotIsolatedCaller("getServices");
10447        synchronized (this) {
10448            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10449        }
10450    }
10451
10452    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10453        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10454        synchronized (this) {
10455            return mServices.getRunningServiceControlPanelLocked(name);
10456        }
10457    }
10458
10459    public ComponentName startService(IApplicationThread caller, Intent service,
10460            String resolvedType) {
10461        enforceNotIsolatedCaller("startService");
10462        // Refuse possible leaked file descriptors
10463        if (service != null && service.hasFileDescriptors() == true) {
10464            throw new IllegalArgumentException("File descriptors passed in Intent");
10465        }
10466
10467        if (DEBUG_SERVICE)
10468            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10469        synchronized(this) {
10470            final int callingPid = Binder.getCallingPid();
10471            final int callingUid = Binder.getCallingUid();
10472            final long origId = Binder.clearCallingIdentity();
10473            ComponentName res = mServices.startServiceLocked(caller, service,
10474                    resolvedType, callingPid, callingUid);
10475            Binder.restoreCallingIdentity(origId);
10476            return res;
10477        }
10478    }
10479
10480    ComponentName startServiceInPackage(int uid,
10481            Intent service, String resolvedType) {
10482        synchronized(this) {
10483            if (DEBUG_SERVICE)
10484                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10485            final long origId = Binder.clearCallingIdentity();
10486            ComponentName res = mServices.startServiceLocked(null, service,
10487                    resolvedType, -1, uid);
10488            Binder.restoreCallingIdentity(origId);
10489            return res;
10490        }
10491    }
10492
10493    public int stopService(IApplicationThread caller, Intent service,
10494            String resolvedType) {
10495        enforceNotIsolatedCaller("stopService");
10496        // Refuse possible leaked file descriptors
10497        if (service != null && service.hasFileDescriptors() == true) {
10498            throw new IllegalArgumentException("File descriptors passed in Intent");
10499        }
10500
10501        synchronized(this) {
10502            return mServices.stopServiceLocked(caller, service, resolvedType);
10503        }
10504    }
10505
10506    public IBinder peekService(Intent service, String resolvedType) {
10507        enforceNotIsolatedCaller("peekService");
10508        // Refuse possible leaked file descriptors
10509        if (service != null && service.hasFileDescriptors() == true) {
10510            throw new IllegalArgumentException("File descriptors passed in Intent");
10511        }
10512        synchronized(this) {
10513            return mServices.peekServiceLocked(service, resolvedType);
10514        }
10515    }
10516
10517    public boolean stopServiceToken(ComponentName className, IBinder token,
10518            int startId) {
10519        synchronized(this) {
10520            return mServices.stopServiceTokenLocked(className, token, startId);
10521        }
10522    }
10523
10524    public void setServiceForeground(ComponentName className, IBinder token,
10525            int id, Notification notification, boolean removeNotification) {
10526        synchronized(this) {
10527            mServices.setServiceForegroundLocked(className, token, id, notification,
10528                    removeNotification);
10529        }
10530    }
10531
10532    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10533            String className, int flags) {
10534        boolean result = false;
10535        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10536            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10537                if (ActivityManager.checkUidPermission(
10538                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10539                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10540                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10541                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10542                            + " requests FLAG_SINGLE_USER, but app does not hold "
10543                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10544                    Slog.w(TAG, msg);
10545                    throw new SecurityException(msg);
10546                }
10547                result = true;
10548            }
10549        } else if (componentProcessName == aInfo.packageName) {
10550            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10551        } else if ("system".equals(componentProcessName)) {
10552            result = true;
10553        }
10554        if (DEBUG_MU) {
10555            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10556                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10557        }
10558        return result;
10559    }
10560
10561    public int bindService(IApplicationThread caller, IBinder token,
10562            Intent service, String resolvedType,
10563            IServiceConnection connection, int flags, int userId) {
10564        enforceNotIsolatedCaller("bindService");
10565        // Refuse possible leaked file descriptors
10566        if (service != null && service.hasFileDescriptors() == true) {
10567            throw new IllegalArgumentException("File descriptors passed in Intent");
10568        }
10569
10570        checkValidCaller(Binder.getCallingUid(), userId);
10571
10572        synchronized(this) {
10573            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10574                    connection, flags, userId);
10575        }
10576    }
10577
10578    public boolean unbindService(IServiceConnection connection) {
10579        synchronized (this) {
10580            return mServices.unbindServiceLocked(connection);
10581        }
10582    }
10583
10584    public void publishService(IBinder token, Intent intent, IBinder service) {
10585        // Refuse possible leaked file descriptors
10586        if (intent != null && intent.hasFileDescriptors() == true) {
10587            throw new IllegalArgumentException("File descriptors passed in Intent");
10588        }
10589
10590        synchronized(this) {
10591            if (!(token instanceof ServiceRecord)) {
10592                throw new IllegalArgumentException("Invalid service token");
10593            }
10594            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10595        }
10596    }
10597
10598    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10599        // Refuse possible leaked file descriptors
10600        if (intent != null && intent.hasFileDescriptors() == true) {
10601            throw new IllegalArgumentException("File descriptors passed in Intent");
10602        }
10603
10604        synchronized(this) {
10605            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10606        }
10607    }
10608
10609    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10610        synchronized(this) {
10611            if (!(token instanceof ServiceRecord)) {
10612                throw new IllegalArgumentException("Invalid service token");
10613            }
10614            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10615        }
10616    }
10617
10618    // =========================================================
10619    // BACKUP AND RESTORE
10620    // =========================================================
10621
10622    // Cause the target app to be launched if necessary and its backup agent
10623    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10624    // activity manager to announce its creation.
10625    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10626        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10627        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10628
10629        synchronized(this) {
10630            // !!! TODO: currently no check here that we're already bound
10631            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10632            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10633            synchronized (stats) {
10634                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10635            }
10636
10637            // Backup agent is now in use, its package can't be stopped.
10638            try {
10639                AppGlobals.getPackageManager().setPackageStoppedState(
10640                        app.packageName, false, UserId.getUserId(app.uid));
10641            } catch (RemoteException e) {
10642            } catch (IllegalArgumentException e) {
10643                Slog.w(TAG, "Failed trying to unstop package "
10644                        + app.packageName + ": " + e);
10645            }
10646
10647            BackupRecord r = new BackupRecord(ss, app, backupMode);
10648            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10649                    ? new ComponentName(app.packageName, app.backupAgentName)
10650                    : new ComponentName("android", "FullBackupAgent");
10651            // startProcessLocked() returns existing proc's record if it's already running
10652            ProcessRecord proc = startProcessLocked(app.processName, app,
10653                    false, 0, "backup", hostingName, false, false);
10654            if (proc == null) {
10655                Slog.e(TAG, "Unable to start backup agent process " + r);
10656                return false;
10657            }
10658
10659            r.app = proc;
10660            mBackupTarget = r;
10661            mBackupAppName = app.packageName;
10662
10663            // Try not to kill the process during backup
10664            updateOomAdjLocked(proc);
10665
10666            // If the process is already attached, schedule the creation of the backup agent now.
10667            // If it is not yet live, this will be done when it attaches to the framework.
10668            if (proc.thread != null) {
10669                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10670                try {
10671                    proc.thread.scheduleCreateBackupAgent(app,
10672                            compatibilityInfoForPackageLocked(app), backupMode);
10673                } catch (RemoteException e) {
10674                    // Will time out on the backup manager side
10675                }
10676            } else {
10677                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10678            }
10679            // Invariants: at this point, the target app process exists and the application
10680            // is either already running or in the process of coming up.  mBackupTarget and
10681            // mBackupAppName describe the app, so that when it binds back to the AM we
10682            // know that it's scheduled for a backup-agent operation.
10683        }
10684
10685        return true;
10686    }
10687
10688    // A backup agent has just come up
10689    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10690        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10691                + " = " + agent);
10692
10693        synchronized(this) {
10694            if (!agentPackageName.equals(mBackupAppName)) {
10695                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10696                return;
10697            }
10698        }
10699
10700        long oldIdent = Binder.clearCallingIdentity();
10701        try {
10702            IBackupManager bm = IBackupManager.Stub.asInterface(
10703                    ServiceManager.getService(Context.BACKUP_SERVICE));
10704            bm.agentConnected(agentPackageName, agent);
10705        } catch (RemoteException e) {
10706            // can't happen; the backup manager service is local
10707        } catch (Exception e) {
10708            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10709            e.printStackTrace();
10710        } finally {
10711            Binder.restoreCallingIdentity(oldIdent);
10712        }
10713    }
10714
10715    // done with this agent
10716    public void unbindBackupAgent(ApplicationInfo appInfo) {
10717        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10718        if (appInfo == null) {
10719            Slog.w(TAG, "unbind backup agent for null app");
10720            return;
10721        }
10722
10723        synchronized(this) {
10724            if (mBackupAppName == null) {
10725                Slog.w(TAG, "Unbinding backup agent with no active backup");
10726                return;
10727            }
10728
10729            if (!mBackupAppName.equals(appInfo.packageName)) {
10730                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10731                return;
10732            }
10733
10734            ProcessRecord proc = mBackupTarget.app;
10735            mBackupTarget = null;
10736            mBackupAppName = null;
10737
10738            // Not backing this app up any more; reset its OOM adjustment
10739            updateOomAdjLocked(proc);
10740
10741            // If the app crashed during backup, 'thread' will be null here
10742            if (proc.thread != null) {
10743                try {
10744                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10745                            compatibilityInfoForPackageLocked(appInfo));
10746                } catch (Exception e) {
10747                    Slog.e(TAG, "Exception when unbinding backup agent:");
10748                    e.printStackTrace();
10749                }
10750            }
10751        }
10752    }
10753    // =========================================================
10754    // BROADCASTS
10755    // =========================================================
10756
10757    private final List getStickiesLocked(String action, IntentFilter filter,
10758            List cur) {
10759        final ContentResolver resolver = mContext.getContentResolver();
10760        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10761        if (list == null) {
10762            return cur;
10763        }
10764        int N = list.size();
10765        for (int i=0; i<N; i++) {
10766            Intent intent = list.get(i);
10767            if (filter.match(resolver, intent, true, TAG) >= 0) {
10768                if (cur == null) {
10769                    cur = new ArrayList<Intent>();
10770                }
10771                cur.add(intent);
10772            }
10773        }
10774        return cur;
10775    }
10776
10777    boolean isPendingBroadcastProcessLocked(int pid) {
10778        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10779                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10780    }
10781
10782    void skipPendingBroadcastLocked(int pid) {
10783            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10784            for (BroadcastQueue queue : mBroadcastQueues) {
10785                queue.skipPendingBroadcastLocked(pid);
10786            }
10787    }
10788
10789    // The app just attached; send any pending broadcasts that it should receive
10790    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10791        boolean didSomething = false;
10792        for (BroadcastQueue queue : mBroadcastQueues) {
10793            didSomething |= queue.sendPendingBroadcastsLocked(app);
10794        }
10795        return didSomething;
10796    }
10797
10798    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10799            IIntentReceiver receiver, IntentFilter filter, String permission) {
10800        enforceNotIsolatedCaller("registerReceiver");
10801        int callingUid;
10802        synchronized(this) {
10803            ProcessRecord callerApp = null;
10804            if (caller != null) {
10805                callerApp = getRecordForAppLocked(caller);
10806                if (callerApp == null) {
10807                    throw new SecurityException(
10808                            "Unable to find app for caller " + caller
10809                            + " (pid=" + Binder.getCallingPid()
10810                            + ") when registering receiver " + receiver);
10811                }
10812                if (callerApp.info.uid != Process.SYSTEM_UID &&
10813                        !callerApp.pkgList.contains(callerPackage)) {
10814                    throw new SecurityException("Given caller package " + callerPackage
10815                            + " is not running in process " + callerApp);
10816                }
10817                callingUid = callerApp.info.uid;
10818            } else {
10819                callerPackage = null;
10820                callingUid = Binder.getCallingUid();
10821            }
10822
10823            List allSticky = null;
10824
10825            // Look for any matching sticky broadcasts...
10826            Iterator actions = filter.actionsIterator();
10827            if (actions != null) {
10828                while (actions.hasNext()) {
10829                    String action = (String)actions.next();
10830                    allSticky = getStickiesLocked(action, filter, allSticky);
10831                }
10832            } else {
10833                allSticky = getStickiesLocked(null, filter, allSticky);
10834            }
10835
10836            // The first sticky in the list is returned directly back to
10837            // the client.
10838            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10839
10840            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10841                    + ": " + sticky);
10842
10843            if (receiver == null) {
10844                return sticky;
10845            }
10846
10847            ReceiverList rl
10848                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10849            if (rl == null) {
10850                rl = new ReceiverList(this, callerApp,
10851                        Binder.getCallingPid(),
10852                        Binder.getCallingUid(), receiver);
10853                if (rl.app != null) {
10854                    rl.app.receivers.add(rl);
10855                } else {
10856                    try {
10857                        receiver.asBinder().linkToDeath(rl, 0);
10858                    } catch (RemoteException e) {
10859                        return sticky;
10860                    }
10861                    rl.linkedToDeath = true;
10862                }
10863                mRegisteredReceivers.put(receiver.asBinder(), rl);
10864            }
10865            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10866                    permission, callingUid);
10867            rl.add(bf);
10868            if (!bf.debugCheck()) {
10869                Slog.w(TAG, "==> For Dynamic broadast");
10870            }
10871            mReceiverResolver.addFilter(bf);
10872
10873            // Enqueue broadcasts for all existing stickies that match
10874            // this filter.
10875            if (allSticky != null) {
10876                ArrayList receivers = new ArrayList();
10877                receivers.add(bf);
10878
10879                int N = allSticky.size();
10880                for (int i=0; i<N; i++) {
10881                    Intent intent = (Intent)allSticky.get(i);
10882                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10883                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10884                            null, -1, -1, null, receivers, null, 0, null, null,
10885                            false, true, true, false);
10886                    queue.enqueueParallelBroadcastLocked(r);
10887                    queue.scheduleBroadcastsLocked();
10888                }
10889            }
10890
10891            return sticky;
10892        }
10893    }
10894
10895    public void unregisterReceiver(IIntentReceiver receiver) {
10896        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10897
10898        final long origId = Binder.clearCallingIdentity();
10899        try {
10900            boolean doTrim = false;
10901
10902            synchronized(this) {
10903                ReceiverList rl
10904                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10905                if (rl != null) {
10906                    if (rl.curBroadcast != null) {
10907                        BroadcastRecord r = rl.curBroadcast;
10908                        final boolean doNext = finishReceiverLocked(
10909                                receiver.asBinder(), r.resultCode, r.resultData,
10910                                r.resultExtras, r.resultAbort, true);
10911                        if (doNext) {
10912                            doTrim = true;
10913                            r.queue.processNextBroadcast(false);
10914                        }
10915                    }
10916
10917                    if (rl.app != null) {
10918                        rl.app.receivers.remove(rl);
10919                    }
10920                    removeReceiverLocked(rl);
10921                    if (rl.linkedToDeath) {
10922                        rl.linkedToDeath = false;
10923                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
10924                    }
10925                }
10926            }
10927
10928            // If we actually concluded any broadcasts, we might now be able
10929            // to trim the recipients' apps from our working set
10930            if (doTrim) {
10931                trimApplications();
10932                return;
10933            }
10934
10935        } finally {
10936            Binder.restoreCallingIdentity(origId);
10937        }
10938    }
10939
10940    void removeReceiverLocked(ReceiverList rl) {
10941        mRegisteredReceivers.remove(rl.receiver.asBinder());
10942        int N = rl.size();
10943        for (int i=0; i<N; i++) {
10944            mReceiverResolver.removeFilter(rl.get(i));
10945        }
10946    }
10947
10948    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10949        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10950            ProcessRecord r = mLruProcesses.get(i);
10951            if (r.thread != null) {
10952                try {
10953                    r.thread.dispatchPackageBroadcast(cmd, packages);
10954                } catch (RemoteException ex) {
10955                }
10956            }
10957        }
10958    }
10959
10960    private final int broadcastIntentLocked(ProcessRecord callerApp,
10961            String callerPackage, Intent intent, String resolvedType,
10962            IIntentReceiver resultTo, int resultCode, String resultData,
10963            Bundle map, String requiredPermission,
10964            boolean ordered, boolean sticky, int callingPid, int callingUid,
10965            int userId) {
10966        intent = new Intent(intent);
10967
10968        // By default broadcasts do not go to stopped apps.
10969        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
10970
10971        if (DEBUG_BROADCAST_LIGHT) Slog.v(
10972            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10973            + " ordered=" + ordered + " userid=" + userId);
10974        if ((resultTo != null) && !ordered) {
10975            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
10976        }
10977
10978        boolean onlySendToCaller = false;
10979
10980        // If the caller is trying to send this broadcast to a different
10981        // user, verify that is allowed.
10982        if (UserId.getUserId(callingUid) != userId) {
10983            if (checkComponentPermission(
10984                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10985                    callingPid, callingUid, -1, true)
10986                    != PackageManager.PERMISSION_GRANTED) {
10987                if (checkComponentPermission(
10988                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10989                        callingPid, callingUid, -1, true)
10990                        == PackageManager.PERMISSION_GRANTED) {
10991                    onlySendToCaller = true;
10992                } else {
10993                    String msg = "Permission Denial: " + intent.getAction()
10994                            + " broadcast from " + callerPackage
10995                            + " asks to send as user " + userId
10996                            + " but is calling from user " + UserId.getUserId(callingUid)
10997                            + "; this requires "
10998                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10999                    Slog.w(TAG, msg);
11000                    throw new SecurityException(msg);
11001                }
11002            }
11003        }
11004
11005        // Handle special intents: if this broadcast is from the package
11006        // manager about a package being removed, we need to remove all of
11007        // its activities from the history stack.
11008        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11009                intent.getAction());
11010        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11011                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11012                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11013                || uidRemoved) {
11014            if (checkComponentPermission(
11015                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11016                    callingPid, callingUid, -1, true)
11017                    == PackageManager.PERMISSION_GRANTED) {
11018                if (uidRemoved) {
11019                    final Bundle intentExtras = intent.getExtras();
11020                    final int uid = intentExtras != null
11021                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11022                    if (uid >= 0) {
11023                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11024                        synchronized (bs) {
11025                            bs.removeUidStatsLocked(uid);
11026                        }
11027                    }
11028                } else {
11029                    // If resources are unvailble just force stop all
11030                    // those packages and flush the attribute cache as well.
11031                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11032                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11033                        if (list != null && (list.length > 0)) {
11034                            for (String pkg : list) {
11035                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11036                            }
11037                            sendPackageBroadcastLocked(
11038                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11039                        }
11040                    } else {
11041                        Uri data = intent.getData();
11042                        String ssp;
11043                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11044                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11045                                forceStopPackageLocked(ssp,
11046                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11047                                        false, userId);
11048                            }
11049                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11050                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11051                                        new String[] {ssp});
11052                            }
11053                        }
11054                    }
11055                }
11056            } else {
11057                String msg = "Permission Denial: " + intent.getAction()
11058                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11059                        + ", uid=" + callingUid + ")"
11060                        + " requires "
11061                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11062                Slog.w(TAG, msg);
11063                throw new SecurityException(msg);
11064            }
11065
11066        // Special case for adding a package: by default turn on compatibility
11067        // mode.
11068        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11069            Uri data = intent.getData();
11070            String ssp;
11071            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11072                mCompatModePackages.handlePackageAddedLocked(ssp,
11073                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11074            }
11075        }
11076
11077        /*
11078         * If this is the time zone changed action, queue up a message that will reset the timezone
11079         * of all currently running processes. This message will get queued up before the broadcast
11080         * happens.
11081         */
11082        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11083            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11084        }
11085
11086        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11087            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11088        }
11089
11090        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11091            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11092            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11093        }
11094
11095        /*
11096         * Prevent non-system code (defined here to be non-persistent
11097         * processes) from sending protected broadcasts.
11098         */
11099        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11100            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11101            callingUid == 0) {
11102            // Always okay.
11103        } else if (callerApp == null || !callerApp.persistent) {
11104            try {
11105                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11106                        intent.getAction())) {
11107                    String msg = "Permission Denial: not allowed to send broadcast "
11108                            + intent.getAction() + " from pid="
11109                            + callingPid + ", uid=" + callingUid;
11110                    Slog.w(TAG, msg);
11111                    throw new SecurityException(msg);
11112                }
11113            } catch (RemoteException e) {
11114                Slog.w(TAG, "Remote exception", e);
11115                return ActivityManager.BROADCAST_SUCCESS;
11116            }
11117        }
11118
11119        // Add to the sticky list if requested.
11120        if (sticky) {
11121            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11122                    callingPid, callingUid)
11123                    != PackageManager.PERMISSION_GRANTED) {
11124                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11125                        + callingPid + ", uid=" + callingUid
11126                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11127                Slog.w(TAG, msg);
11128                throw new SecurityException(msg);
11129            }
11130            if (requiredPermission != null) {
11131                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11132                        + " and enforce permission " + requiredPermission);
11133                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11134            }
11135            if (intent.getComponent() != null) {
11136                throw new SecurityException(
11137                        "Sticky broadcasts can't target a specific component");
11138            }
11139            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11140            if (list == null) {
11141                list = new ArrayList<Intent>();
11142                mStickyBroadcasts.put(intent.getAction(), list);
11143            }
11144            int N = list.size();
11145            int i;
11146            for (i=0; i<N; i++) {
11147                if (intent.filterEquals(list.get(i))) {
11148                    // This sticky already exists, replace it.
11149                    list.set(i, new Intent(intent));
11150                    break;
11151                }
11152            }
11153            if (i >= N) {
11154                list.add(new Intent(intent));
11155            }
11156        }
11157
11158        // Figure out who all will receive this broadcast.
11159        List receivers = null;
11160        List<BroadcastFilter> registeredReceivers = null;
11161        try {
11162            // Need to resolve the intent to interested receivers...
11163            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11164                     == 0) {
11165                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11166                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11167            }
11168            if (intent.getComponent() == null) {
11169                registeredReceivers = mReceiverResolver.queryIntent(intent,
11170                        resolvedType, false, userId);
11171            }
11172        } catch (RemoteException ex) {
11173            // pm is in same process, this will never happen.
11174        }
11175
11176        final boolean replacePending =
11177                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11178
11179        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11180                + " replacePending=" + replacePending);
11181
11182        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11183        if (!ordered && NR > 0) {
11184            // If we are not serializing this broadcast, then send the
11185            // registered receivers separately so they don't wait for the
11186            // components to be launched.
11187            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11188            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11189                    callerPackage, callingPid, callingUid, requiredPermission,
11190                    registeredReceivers, resultTo, resultCode, resultData, map,
11191                    ordered, sticky, false, onlySendToCaller);
11192            if (DEBUG_BROADCAST) Slog.v(
11193                    TAG, "Enqueueing parallel broadcast " + r);
11194            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11195            if (!replaced) {
11196                queue.enqueueParallelBroadcastLocked(r);
11197                queue.scheduleBroadcastsLocked();
11198            }
11199            registeredReceivers = null;
11200            NR = 0;
11201        }
11202
11203        // Merge into one list.
11204        int ir = 0;
11205        if (receivers != null) {
11206            // A special case for PACKAGE_ADDED: do not allow the package
11207            // being added to see this broadcast.  This prevents them from
11208            // using this as a back door to get run as soon as they are
11209            // installed.  Maybe in the future we want to have a special install
11210            // broadcast or such for apps, but we'd like to deliberately make
11211            // this decision.
11212            String skipPackages[] = null;
11213            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11214                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11215                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11216                Uri data = intent.getData();
11217                if (data != null) {
11218                    String pkgName = data.getSchemeSpecificPart();
11219                    if (pkgName != null) {
11220                        skipPackages = new String[] { pkgName };
11221                    }
11222                }
11223            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11224                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11225            }
11226            if (skipPackages != null && (skipPackages.length > 0)) {
11227                for (String skipPackage : skipPackages) {
11228                    if (skipPackage != null) {
11229                        int NT = receivers.size();
11230                        for (int it=0; it<NT; it++) {
11231                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11232                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11233                                receivers.remove(it);
11234                                it--;
11235                                NT--;
11236                            }
11237                        }
11238                    }
11239                }
11240            }
11241
11242            int NT = receivers != null ? receivers.size() : 0;
11243            int it = 0;
11244            ResolveInfo curt = null;
11245            BroadcastFilter curr = null;
11246            while (it < NT && ir < NR) {
11247                if (curt == null) {
11248                    curt = (ResolveInfo)receivers.get(it);
11249                }
11250                if (curr == null) {
11251                    curr = registeredReceivers.get(ir);
11252                }
11253                if (curr.getPriority() >= curt.priority) {
11254                    // Insert this broadcast record into the final list.
11255                    receivers.add(it, curr);
11256                    ir++;
11257                    curr = null;
11258                    it++;
11259                    NT++;
11260                } else {
11261                    // Skip to the next ResolveInfo in the final list.
11262                    it++;
11263                    curt = null;
11264                }
11265            }
11266        }
11267        while (ir < NR) {
11268            if (receivers == null) {
11269                receivers = new ArrayList();
11270            }
11271            receivers.add(registeredReceivers.get(ir));
11272            ir++;
11273        }
11274
11275        if ((receivers != null && receivers.size() > 0)
11276                || resultTo != null) {
11277            BroadcastQueue queue = broadcastQueueForIntent(intent);
11278            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11279                    callerPackage, callingPid, callingUid, requiredPermission,
11280                    receivers, resultTo, resultCode, resultData, map, ordered,
11281                    sticky, false, onlySendToCaller);
11282            if (DEBUG_BROADCAST) Slog.v(
11283                    TAG, "Enqueueing ordered broadcast " + r
11284                    + ": prev had " + queue.mOrderedBroadcasts.size());
11285            if (DEBUG_BROADCAST) {
11286                int seq = r.intent.getIntExtra("seq", -1);
11287                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11288            }
11289            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11290            if (!replaced) {
11291                queue.enqueueOrderedBroadcastLocked(r);
11292                queue.scheduleBroadcastsLocked();
11293            }
11294        }
11295
11296        return ActivityManager.BROADCAST_SUCCESS;
11297    }
11298
11299    final Intent verifyBroadcastLocked(Intent intent) {
11300        // Refuse possible leaked file descriptors
11301        if (intent != null && intent.hasFileDescriptors() == true) {
11302            throw new IllegalArgumentException("File descriptors passed in Intent");
11303        }
11304
11305        int flags = intent.getFlags();
11306
11307        if (!mProcessesReady) {
11308            // if the caller really truly claims to know what they're doing, go
11309            // ahead and allow the broadcast without launching any receivers
11310            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11311                intent = new Intent(intent);
11312                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11313            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11314                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11315                        + " before boot completion");
11316                throw new IllegalStateException("Cannot broadcast before boot completed");
11317            }
11318        }
11319
11320        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11321            throw new IllegalArgumentException(
11322                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11323        }
11324
11325        return intent;
11326    }
11327
11328    public final int broadcastIntent(IApplicationThread caller,
11329            Intent intent, String resolvedType, IIntentReceiver resultTo,
11330            int resultCode, String resultData, Bundle map,
11331            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11332        enforceNotIsolatedCaller("broadcastIntent");
11333        synchronized(this) {
11334            intent = verifyBroadcastLocked(intent);
11335
11336            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11337            final int callingPid = Binder.getCallingPid();
11338            final int callingUid = Binder.getCallingUid();
11339            final long origId = Binder.clearCallingIdentity();
11340            int res = broadcastIntentLocked(callerApp,
11341                    callerApp != null ? callerApp.info.packageName : null,
11342                    intent, resolvedType, resultTo,
11343                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11344                    callingPid, callingUid, userId);
11345            Binder.restoreCallingIdentity(origId);
11346            return res;
11347        }
11348    }
11349
11350    int broadcastIntentInPackage(String packageName, int uid,
11351            Intent intent, String resolvedType, IIntentReceiver resultTo,
11352            int resultCode, String resultData, Bundle map,
11353            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11354        synchronized(this) {
11355            intent = verifyBroadcastLocked(intent);
11356
11357            final long origId = Binder.clearCallingIdentity();
11358            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11359                    resultTo, resultCode, resultData, map, requiredPermission,
11360                    serialized, sticky, -1, uid, userId);
11361            Binder.restoreCallingIdentity(origId);
11362            return res;
11363        }
11364    }
11365
11366    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11367    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11368        // Refuse possible leaked file descriptors
11369        if (intent != null && intent.hasFileDescriptors() == true) {
11370            throw new IllegalArgumentException("File descriptors passed in Intent");
11371        }
11372
11373        synchronized(this) {
11374            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11375                    != PackageManager.PERMISSION_GRANTED) {
11376                String msg = "Permission Denial: unbroadcastIntent() from pid="
11377                        + Binder.getCallingPid()
11378                        + ", uid=" + Binder.getCallingUid()
11379                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11380                Slog.w(TAG, msg);
11381                throw new SecurityException(msg);
11382            }
11383            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11384            if (list != null) {
11385                int N = list.size();
11386                int i;
11387                for (i=0; i<N; i++) {
11388                    if (intent.filterEquals(list.get(i))) {
11389                        list.remove(i);
11390                        break;
11391                    }
11392                }
11393            }
11394        }
11395    }
11396
11397    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11398            String resultData, Bundle resultExtras, boolean resultAbort,
11399            boolean explicit) {
11400        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11401        if (r == null) {
11402            Slog.w(TAG, "finishReceiver called but not found on queue");
11403            return false;
11404        }
11405
11406        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11407                explicit);
11408    }
11409
11410    public void finishReceiver(IBinder who, int resultCode, String resultData,
11411            Bundle resultExtras, boolean resultAbort) {
11412        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11413
11414        // Refuse possible leaked file descriptors
11415        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11416            throw new IllegalArgumentException("File descriptors passed in Bundle");
11417        }
11418
11419        final long origId = Binder.clearCallingIdentity();
11420        try {
11421            boolean doNext = false;
11422            BroadcastRecord r = null;
11423
11424            synchronized(this) {
11425                r = broadcastRecordForReceiverLocked(who);
11426                if (r != null) {
11427                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11428                        resultData, resultExtras, resultAbort, true);
11429                }
11430            }
11431
11432            if (doNext) {
11433                r.queue.processNextBroadcast(false);
11434            }
11435            trimApplications();
11436        } finally {
11437            Binder.restoreCallingIdentity(origId);
11438        }
11439    }
11440
11441    // =========================================================
11442    // INSTRUMENTATION
11443    // =========================================================
11444
11445    public boolean startInstrumentation(ComponentName className,
11446            String profileFile, int flags, Bundle arguments,
11447            IInstrumentationWatcher watcher) {
11448        enforceNotIsolatedCaller("startInstrumentation");
11449        // Refuse possible leaked file descriptors
11450        if (arguments != null && arguments.hasFileDescriptors()) {
11451            throw new IllegalArgumentException("File descriptors passed in Bundle");
11452        }
11453
11454        synchronized(this) {
11455            InstrumentationInfo ii = null;
11456            ApplicationInfo ai = null;
11457            try {
11458                ii = mContext.getPackageManager().getInstrumentationInfo(
11459                    className, STOCK_PM_FLAGS);
11460                ai = mContext.getPackageManager().getApplicationInfo(
11461                        ii.targetPackage, STOCK_PM_FLAGS);
11462            } catch (PackageManager.NameNotFoundException e) {
11463            }
11464            if (ii == null) {
11465                reportStartInstrumentationFailure(watcher, className,
11466                        "Unable to find instrumentation info for: " + className);
11467                return false;
11468            }
11469            if (ai == null) {
11470                reportStartInstrumentationFailure(watcher, className,
11471                        "Unable to find instrumentation target package: " + ii.targetPackage);
11472                return false;
11473            }
11474
11475            int match = mContext.getPackageManager().checkSignatures(
11476                    ii.targetPackage, ii.packageName);
11477            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11478                String msg = "Permission Denial: starting instrumentation "
11479                        + className + " from pid="
11480                        + Binder.getCallingPid()
11481                        + ", uid=" + Binder.getCallingPid()
11482                        + " not allowed because package " + ii.packageName
11483                        + " does not have a signature matching the target "
11484                        + ii.targetPackage;
11485                reportStartInstrumentationFailure(watcher, className, msg);
11486                throw new SecurityException(msg);
11487            }
11488
11489            int userId = UserId.getCallingUserId();
11490            final long origId = Binder.clearCallingIdentity();
11491            // Instrumentation can kill and relaunch even persistent processes
11492            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11493            ProcessRecord app = addAppLocked(ai, false);
11494            app.instrumentationClass = className;
11495            app.instrumentationInfo = ai;
11496            app.instrumentationProfileFile = profileFile;
11497            app.instrumentationArguments = arguments;
11498            app.instrumentationWatcher = watcher;
11499            app.instrumentationResultClass = className;
11500            Binder.restoreCallingIdentity(origId);
11501        }
11502
11503        return true;
11504    }
11505
11506    /**
11507     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11508     * error to the logs, but if somebody is watching, send the report there too.  This enables
11509     * the "am" command to report errors with more information.
11510     *
11511     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11512     * @param cn The component name of the instrumentation.
11513     * @param report The error report.
11514     */
11515    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11516            ComponentName cn, String report) {
11517        Slog.w(TAG, report);
11518        try {
11519            if (watcher != null) {
11520                Bundle results = new Bundle();
11521                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11522                results.putString("Error", report);
11523                watcher.instrumentationStatus(cn, -1, results);
11524            }
11525        } catch (RemoteException e) {
11526            Slog.w(TAG, e);
11527        }
11528    }
11529
11530    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11531        if (app.instrumentationWatcher != null) {
11532            try {
11533                // NOTE:  IInstrumentationWatcher *must* be oneway here
11534                app.instrumentationWatcher.instrumentationFinished(
11535                    app.instrumentationClass,
11536                    resultCode,
11537                    results);
11538            } catch (RemoteException e) {
11539            }
11540        }
11541        app.instrumentationWatcher = null;
11542        app.instrumentationClass = null;
11543        app.instrumentationInfo = null;
11544        app.instrumentationProfileFile = null;
11545        app.instrumentationArguments = null;
11546
11547        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11548    }
11549
11550    public void finishInstrumentation(IApplicationThread target,
11551            int resultCode, Bundle results) {
11552        int userId = UserId.getCallingUserId();
11553        // Refuse possible leaked file descriptors
11554        if (results != null && results.hasFileDescriptors()) {
11555            throw new IllegalArgumentException("File descriptors passed in Intent");
11556        }
11557
11558        synchronized(this) {
11559            ProcessRecord app = getRecordForAppLocked(target);
11560            if (app == null) {
11561                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11562                return;
11563            }
11564            final long origId = Binder.clearCallingIdentity();
11565            finishInstrumentationLocked(app, resultCode, results);
11566            Binder.restoreCallingIdentity(origId);
11567        }
11568    }
11569
11570    // =========================================================
11571    // CONFIGURATION
11572    // =========================================================
11573
11574    public ConfigurationInfo getDeviceConfigurationInfo() {
11575        ConfigurationInfo config = new ConfigurationInfo();
11576        synchronized (this) {
11577            config.reqTouchScreen = mConfiguration.touchscreen;
11578            config.reqKeyboardType = mConfiguration.keyboard;
11579            config.reqNavigation = mConfiguration.navigation;
11580            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11581                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11582                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11583            }
11584            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11585                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11586                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11587            }
11588            config.reqGlEsVersion = GL_ES_VERSION;
11589        }
11590        return config;
11591    }
11592
11593    public Configuration getConfiguration() {
11594        Configuration ci;
11595        synchronized(this) {
11596            ci = new Configuration(mConfiguration);
11597        }
11598        return ci;
11599    }
11600
11601    public void updatePersistentConfiguration(Configuration values) {
11602        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11603                "updateConfiguration()");
11604        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11605                "updateConfiguration()");
11606        if (values == null) {
11607            throw new NullPointerException("Configuration must not be null");
11608        }
11609
11610        synchronized(this) {
11611            final long origId = Binder.clearCallingIdentity();
11612            updateConfigurationLocked(values, null, true, false);
11613            Binder.restoreCallingIdentity(origId);
11614        }
11615    }
11616
11617    public void updateConfiguration(Configuration values) {
11618        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11619                "updateConfiguration()");
11620
11621        synchronized(this) {
11622            if (values == null && mWindowManager != null) {
11623                // sentinel: fetch the current configuration from the window manager
11624                values = mWindowManager.computeNewConfiguration();
11625            }
11626
11627            if (mWindowManager != null) {
11628                mProcessList.applyDisplaySize(mWindowManager);
11629            }
11630
11631            final long origId = Binder.clearCallingIdentity();
11632            if (values != null) {
11633                Settings.System.clearConfiguration(values);
11634            }
11635            updateConfigurationLocked(values, null, false, false);
11636            Binder.restoreCallingIdentity(origId);
11637        }
11638    }
11639
11640    /**
11641     * Do either or both things: (1) change the current configuration, and (2)
11642     * make sure the given activity is running with the (now) current
11643     * configuration.  Returns true if the activity has been left running, or
11644     * false if <var>starting</var> is being destroyed to match the new
11645     * configuration.
11646     * @param persistent TODO
11647     */
11648    boolean updateConfigurationLocked(Configuration values,
11649            ActivityRecord starting, boolean persistent, boolean initLocale) {
11650        // do nothing if we are headless
11651        if (mHeadless) return true;
11652
11653        int changes = 0;
11654
11655        boolean kept = true;
11656
11657        if (values != null) {
11658            Configuration newConfig = new Configuration(mConfiguration);
11659            changes = newConfig.updateFrom(values);
11660            if (changes != 0) {
11661                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11662                    Slog.i(TAG, "Updating configuration to: " + values);
11663                }
11664
11665                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11666
11667                if (values.locale != null && !initLocale) {
11668                    saveLocaleLocked(values.locale,
11669                                     !values.locale.equals(mConfiguration.locale),
11670                                     values.userSetLocale);
11671                }
11672
11673                mConfigurationSeq++;
11674                if (mConfigurationSeq <= 0) {
11675                    mConfigurationSeq = 1;
11676                }
11677                newConfig.seq = mConfigurationSeq;
11678                mConfiguration = newConfig;
11679                Slog.i(TAG, "Config changed: " + newConfig);
11680
11681                final Configuration configCopy = new Configuration(mConfiguration);
11682
11683                // TODO: If our config changes, should we auto dismiss any currently
11684                // showing dialogs?
11685                mShowDialogs = shouldShowDialogs(newConfig);
11686
11687                AttributeCache ac = AttributeCache.instance();
11688                if (ac != null) {
11689                    ac.updateConfiguration(configCopy);
11690                }
11691
11692                // Make sure all resources in our process are updated
11693                // right now, so that anyone who is going to retrieve
11694                // resource values after we return will be sure to get
11695                // the new ones.  This is especially important during
11696                // boot, where the first config change needs to guarantee
11697                // all resources have that config before following boot
11698                // code is executed.
11699                mSystemThread.applyConfigurationToResources(configCopy);
11700
11701                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11702                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11703                    msg.obj = new Configuration(configCopy);
11704                    mHandler.sendMessage(msg);
11705                }
11706
11707                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11708                    ProcessRecord app = mLruProcesses.get(i);
11709                    try {
11710                        if (app.thread != null) {
11711                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11712                                    + app.processName + " new config " + mConfiguration);
11713                            app.thread.scheduleConfigurationChanged(configCopy);
11714                        }
11715                    } catch (Exception e) {
11716                    }
11717                }
11718                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11719                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11720                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11721                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11722                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11723                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11724                    broadcastIntentLocked(null, null,
11725                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11726                            null, null, 0, null, null,
11727                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11728                }
11729            }
11730        }
11731
11732        if (changes != 0 && starting == null) {
11733            // If the configuration changed, and the caller is not already
11734            // in the process of starting an activity, then find the top
11735            // activity to check if its configuration needs to change.
11736            starting = mMainStack.topRunningActivityLocked(null);
11737        }
11738
11739        if (starting != null) {
11740            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11741            // And we need to make sure at this point that all other activities
11742            // are made visible with the correct configuration.
11743            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11744        }
11745
11746        if (values != null && mWindowManager != null) {
11747            mWindowManager.setNewConfiguration(mConfiguration);
11748        }
11749
11750        return kept;
11751    }
11752
11753    /**
11754     * Decide based on the configuration whether we should shouw the ANR,
11755     * crash, etc dialogs.  The idea is that if there is no affordnace to
11756     * press the on-screen buttons, we shouldn't show the dialog.
11757     *
11758     * A thought: SystemUI might also want to get told about this, the Power
11759     * dialog / global actions also might want different behaviors.
11760     */
11761    private static final boolean shouldShowDialogs(Configuration config) {
11762        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11763                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11764    }
11765
11766    /**
11767     * Save the locale.  You must be inside a synchronized (this) block.
11768     */
11769    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11770        if(isDiff) {
11771            SystemProperties.set("user.language", l.getLanguage());
11772            SystemProperties.set("user.region", l.getCountry());
11773        }
11774
11775        if(isPersist) {
11776            SystemProperties.set("persist.sys.language", l.getLanguage());
11777            SystemProperties.set("persist.sys.country", l.getCountry());
11778            SystemProperties.set("persist.sys.localevar", l.getVariant());
11779        }
11780    }
11781
11782    @Override
11783    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11784        ActivityRecord srec = ActivityRecord.forToken(token);
11785        return srec != null && srec.task.affinity != null &&
11786                srec.task.affinity.equals(destAffinity);
11787    }
11788
11789    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11790            Intent resultData) {
11791        ComponentName dest = destIntent.getComponent();
11792
11793        synchronized (this) {
11794            ActivityRecord srec = ActivityRecord.forToken(token);
11795            if (srec == null) {
11796                return false;
11797            }
11798            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11799            final int start = history.indexOf(srec);
11800            if (start < 0) {
11801                // Current activity is not in history stack; do nothing.
11802                return false;
11803            }
11804            int finishTo = start - 1;
11805            ActivityRecord parent = null;
11806            boolean foundParentInTask = false;
11807            if (dest != null) {
11808                TaskRecord tr = srec.task;
11809                for (int i = start - 1; i >= 0; i--) {
11810                    ActivityRecord r = history.get(i);
11811                    if (tr != r.task) {
11812                        // Couldn't find parent in the same task; stop at the one above this.
11813                        // (Root of current task; in-app "home" behavior)
11814                        // Always at least finish the current activity.
11815                        finishTo = Math.min(start - 1, i + 1);
11816                        parent = history.get(finishTo);
11817                        break;
11818                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11819                            r.info.name.equals(dest.getClassName())) {
11820                        finishTo = i;
11821                        parent = r;
11822                        foundParentInTask = true;
11823                        break;
11824                    }
11825                }
11826            }
11827
11828            if (mController != null) {
11829                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11830                if (next != null) {
11831                    // ask watcher if this is allowed
11832                    boolean resumeOK = true;
11833                    try {
11834                        resumeOK = mController.activityResuming(next.packageName);
11835                    } catch (RemoteException e) {
11836                        mController = null;
11837                    }
11838
11839                    if (!resumeOK) {
11840                        return false;
11841                    }
11842                }
11843            }
11844            final long origId = Binder.clearCallingIdentity();
11845            for (int i = start; i > finishTo; i--) {
11846                ActivityRecord r = history.get(i);
11847                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11848                        "navigate-up");
11849                // Only return the supplied result for the first activity finished
11850                resultCode = Activity.RESULT_CANCELED;
11851                resultData = null;
11852            }
11853
11854            if (parent != null && foundParentInTask) {
11855                final int parentLaunchMode = parent.info.launchMode;
11856                final int destIntentFlags = destIntent.getFlags();
11857                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11858                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11859                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11860                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11861                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11862                } else {
11863                    try {
11864                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11865                                destIntent.getComponent(), 0, UserId.getCallingUserId());
11866                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11867                                null, aInfo, parent.appToken, null,
11868                                0, -1, parent.launchedFromUid, 0, null, true, null);
11869                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11870                    } catch (RemoteException e) {
11871                        foundParentInTask = false;
11872                    }
11873                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11874                            resultData, "navigate-up");
11875                }
11876            }
11877            Binder.restoreCallingIdentity(origId);
11878            return foundParentInTask;
11879        }
11880    }
11881
11882    public int getLaunchedFromUid(IBinder activityToken) {
11883        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11884        if (srec == null) {
11885            return -1;
11886        }
11887        return srec.launchedFromUid;
11888    }
11889
11890    // =========================================================
11891    // LIFETIME MANAGEMENT
11892    // =========================================================
11893
11894    // Returns which broadcast queue the app is the current [or imminent] receiver
11895    // on, or 'null' if the app is not an active broadcast recipient.
11896    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11897        BroadcastRecord r = app.curReceiver;
11898        if (r != null) {
11899            return r.queue;
11900        }
11901
11902        // It's not the current receiver, but it might be starting up to become one
11903        synchronized (this) {
11904            for (BroadcastQueue queue : mBroadcastQueues) {
11905                r = queue.mPendingBroadcast;
11906                if (r != null && r.curApp == app) {
11907                    // found it; report which queue it's in
11908                    return queue;
11909                }
11910            }
11911        }
11912
11913        return null;
11914    }
11915
11916    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11917            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
11918        if (mAdjSeq == app.adjSeq) {
11919            // This adjustment has already been computed.  If we are calling
11920            // from the top, we may have already computed our adjustment with
11921            // an earlier hidden adjustment that isn't really for us... if
11922            // so, use the new hidden adjustment.
11923            if (!recursed && app.hidden) {
11924                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
11925            }
11926            return app.curRawAdj;
11927        }
11928
11929        if (app.thread == null) {
11930            app.adjSeq = mAdjSeq;
11931            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11932            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
11933        }
11934
11935        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
11936        app.adjSource = null;
11937        app.adjTarget = null;
11938        app.empty = false;
11939        app.hidden = false;
11940
11941        final int activitiesSize = app.activities.size();
11942
11943        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
11944            // The max adjustment doesn't allow this app to be anything
11945            // below foreground, so it is not worth doing work for it.
11946            app.adjType = "fixed";
11947            app.adjSeq = mAdjSeq;
11948            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
11949            app.foregroundActivities = false;
11950            app.keeping = true;
11951            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
11952            // System process can do UI, and when they do we want to have
11953            // them trim their memory after the user leaves the UI.  To
11954            // facilitate this, here we need to determine whether or not it
11955            // is currently showing UI.
11956            app.systemNoUi = true;
11957            if (app == TOP_APP) {
11958                app.systemNoUi = false;
11959            } else if (activitiesSize > 0) {
11960                for (int j = 0; j < activitiesSize; j++) {
11961                    final ActivityRecord r = app.activities.get(j);
11962                    if (r.visible) {
11963                        app.systemNoUi = false;
11964                        break;
11965                    }
11966                }
11967            }
11968            return (app.curAdj=app.maxAdj);
11969        }
11970
11971        app.keeping = false;
11972        app.systemNoUi = false;
11973
11974        // Determine the importance of the process, starting with most
11975        // important to least, and assign an appropriate OOM adjustment.
11976        int adj;
11977        int schedGroup;
11978        boolean foregroundActivities = false;
11979        boolean interesting = false;
11980        BroadcastQueue queue;
11981        if (app == TOP_APP) {
11982            // The last app on the list is the foreground app.
11983            adj = ProcessList.FOREGROUND_APP_ADJ;
11984            schedGroup = Process.THREAD_GROUP_DEFAULT;
11985            app.adjType = "top-activity";
11986            foregroundActivities = true;
11987            interesting = true;
11988        } else if (app.instrumentationClass != null) {
11989            // Don't want to kill running instrumentation.
11990            adj = ProcessList.FOREGROUND_APP_ADJ;
11991            schedGroup = Process.THREAD_GROUP_DEFAULT;
11992            app.adjType = "instrumentation";
11993            interesting = true;
11994        } else if ((queue = isReceivingBroadcast(app)) != null) {
11995            // An app that is currently receiving a broadcast also
11996            // counts as being in the foreground for OOM killer purposes.
11997            // It's placed in a sched group based on the nature of the
11998            // broadcast as reflected by which queue it's active in.
11999            adj = ProcessList.FOREGROUND_APP_ADJ;
12000            schedGroup = (queue == mFgBroadcastQueue)
12001                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12002            app.adjType = "broadcast";
12003        } else if (app.executingServices.size() > 0) {
12004            // An app that is currently executing a service callback also
12005            // counts as being in the foreground.
12006            adj = ProcessList.FOREGROUND_APP_ADJ;
12007            schedGroup = Process.THREAD_GROUP_DEFAULT;
12008            app.adjType = "exec-service";
12009        } else if (activitiesSize > 0) {
12010            // This app is in the background with paused activities.
12011            // We inspect activities to potentially upgrade adjustment further below.
12012            adj = hiddenAdj;
12013            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12014            app.hidden = true;
12015            app.adjType = "bg-activities";
12016        } else {
12017            // A very not-needed process.  If this is lower in the lru list,
12018            // we will push it in to the empty bucket.
12019            adj = hiddenAdj;
12020            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12021            app.hidden = true;
12022            app.empty = true;
12023            app.adjType = "bg-empty";
12024        }
12025
12026        boolean hasStoppingActivities = false;
12027
12028        // Examine all activities if not already foreground.
12029        if (!foregroundActivities && activitiesSize > 0) {
12030            for (int j = 0; j < activitiesSize; j++) {
12031                final ActivityRecord r = app.activities.get(j);
12032                if (r.visible) {
12033                    // App has a visible activity; only upgrade adjustment.
12034                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12035                        adj = ProcessList.VISIBLE_APP_ADJ;
12036                        app.adjType = "visible";
12037                    }
12038                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12039                    app.hidden = false;
12040                    foregroundActivities = true;
12041                    break;
12042                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12043                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12044                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12045                        app.adjType = "pausing";
12046                    }
12047                    app.hidden = false;
12048                    foregroundActivities = true;
12049                } else if (r.state == ActivityState.STOPPING) {
12050                    // We will apply the actual adjustment later, because
12051                    // we want to allow this process to immediately go through
12052                    // any memory trimming that is in effect.
12053                    app.hidden = false;
12054                    foregroundActivities = true;
12055                    hasStoppingActivities = true;
12056                }
12057            }
12058        }
12059
12060        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12061            if (app.foregroundServices) {
12062                // The user is aware of this app, so make it visible.
12063                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12064                app.hidden = false;
12065                app.adjType = "foreground-service";
12066                schedGroup = Process.THREAD_GROUP_DEFAULT;
12067            } else if (app.forcingToForeground != null) {
12068                // The user is aware of this app, so make it visible.
12069                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12070                app.hidden = false;
12071                app.adjType = "force-foreground";
12072                app.adjSource = app.forcingToForeground;
12073                schedGroup = Process.THREAD_GROUP_DEFAULT;
12074            }
12075        }
12076
12077        if (app.foregroundServices) {
12078            interesting = true;
12079        }
12080
12081        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12082            // We don't want to kill the current heavy-weight process.
12083            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12084            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12085            app.hidden = false;
12086            app.adjType = "heavy";
12087        }
12088
12089        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12090            // This process is hosting what we currently consider to be the
12091            // home app, so we don't want to let it go into the background.
12092            adj = ProcessList.HOME_APP_ADJ;
12093            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12094            app.hidden = false;
12095            app.adjType = "home";
12096        }
12097
12098        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12099                && app.activities.size() > 0) {
12100            // This was the previous process that showed UI to the user.
12101            // We want to try to keep it around more aggressively, to give
12102            // a good experience around switching between two apps.
12103            adj = ProcessList.PREVIOUS_APP_ADJ;
12104            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12105            app.hidden = false;
12106            app.adjType = "previous";
12107        }
12108
12109        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12110                + " reason=" + app.adjType);
12111
12112        // By default, we use the computed adjustment.  It may be changed if
12113        // there are applications dependent on our services or providers, but
12114        // this gives us a baseline and makes sure we don't get into an
12115        // infinite recursion.
12116        app.adjSeq = mAdjSeq;
12117        app.curRawAdj = app.nonStoppingAdj = adj;
12118
12119        if (mBackupTarget != null && app == mBackupTarget.app) {
12120            // If possible we want to avoid killing apps while they're being backed up
12121            if (adj > ProcessList.BACKUP_APP_ADJ) {
12122                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12123                adj = ProcessList.BACKUP_APP_ADJ;
12124                app.adjType = "backup";
12125                app.hidden = false;
12126            }
12127        }
12128
12129        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12130                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12131            final long now = SystemClock.uptimeMillis();
12132            // This process is more important if the top activity is
12133            // bound to the service.
12134            Iterator<ServiceRecord> jt = app.services.iterator();
12135            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12136                ServiceRecord s = jt.next();
12137                if (s.startRequested) {
12138                    if (app.hasShownUi && app != mHomeProcess) {
12139                        // If this process has shown some UI, let it immediately
12140                        // go to the LRU list because it may be pretty heavy with
12141                        // UI stuff.  We'll tag it with a label just to help
12142                        // debug and understand what is going on.
12143                        if (adj > ProcessList.SERVICE_ADJ) {
12144                            app.adjType = "started-bg-ui-services";
12145                        }
12146                    } else {
12147                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12148                            // This service has seen some activity within
12149                            // recent memory, so we will keep its process ahead
12150                            // of the background processes.
12151                            if (adj > ProcessList.SERVICE_ADJ) {
12152                                adj = ProcessList.SERVICE_ADJ;
12153                                app.adjType = "started-services";
12154                                app.hidden = false;
12155                            }
12156                        }
12157                        // If we have let the service slide into the background
12158                        // state, still have some text describing what it is doing
12159                        // even though the service no longer has an impact.
12160                        if (adj > ProcessList.SERVICE_ADJ) {
12161                            app.adjType = "started-bg-services";
12162                        }
12163                    }
12164                    // Don't kill this process because it is doing work; it
12165                    // has said it is doing work.
12166                    app.keeping = true;
12167                }
12168                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12169                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12170                    Iterator<ArrayList<ConnectionRecord>> kt
12171                            = s.connections.values().iterator();
12172                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12173                        ArrayList<ConnectionRecord> clist = kt.next();
12174                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12175                            // XXX should compute this based on the max of
12176                            // all connected clients.
12177                            ConnectionRecord cr = clist.get(i);
12178                            if (cr.binding.client == app) {
12179                                // Binding to ourself is not interesting.
12180                                continue;
12181                            }
12182                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12183                                ProcessRecord client = cr.binding.client;
12184                                int clientAdj = adj;
12185                                int myHiddenAdj = hiddenAdj;
12186                                if (myHiddenAdj > client.hiddenAdj) {
12187                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12188                                        myHiddenAdj = client.hiddenAdj;
12189                                    } else {
12190                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12191                                    }
12192                                }
12193                                clientAdj = computeOomAdjLocked(
12194                                    client, myHiddenAdj, TOP_APP, true, doingAll);
12195                                String adjType = null;
12196                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12197                                    // Not doing bind OOM management, so treat
12198                                    // this guy more like a started service.
12199                                    if (app.hasShownUi && app != mHomeProcess) {
12200                                        // If this process has shown some UI, let it immediately
12201                                        // go to the LRU list because it may be pretty heavy with
12202                                        // UI stuff.  We'll tag it with a label just to help
12203                                        // debug and understand what is going on.
12204                                        if (adj > clientAdj) {
12205                                            adjType = "bound-bg-ui-services";
12206                                        }
12207                                        app.hidden = false;
12208                                        clientAdj = adj;
12209                                    } else {
12210                                        if (now >= (s.lastActivity
12211                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12212                                            // This service has not seen activity within
12213                                            // recent memory, so allow it to drop to the
12214                                            // LRU list if there is no other reason to keep
12215                                            // it around.  We'll also tag it with a label just
12216                                            // to help debug and undertand what is going on.
12217                                            if (adj > clientAdj) {
12218                                                adjType = "bound-bg-services";
12219                                            }
12220                                            clientAdj = adj;
12221                                        }
12222                                    }
12223                                }
12224                                if (adj > clientAdj) {
12225                                    // If this process has recently shown UI, and
12226                                    // the process that is binding to it is less
12227                                    // important than being visible, then we don't
12228                                    // care about the binding as much as we care
12229                                    // about letting this process get into the LRU
12230                                    // list to be killed and restarted if needed for
12231                                    // memory.
12232                                    if (app.hasShownUi && app != mHomeProcess
12233                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12234                                        adjType = "bound-bg-ui-services";
12235                                    } else {
12236                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12237                                                |Context.BIND_IMPORTANT)) != 0) {
12238                                            adj = clientAdj;
12239                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12240                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12241                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12242                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12243                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12244                                            adj = clientAdj;
12245                                        } else {
12246                                            app.pendingUiClean = true;
12247                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12248                                                adj = ProcessList.VISIBLE_APP_ADJ;
12249                                            }
12250                                        }
12251                                        if (!client.hidden) {
12252                                            app.hidden = false;
12253                                        }
12254                                        if (client.keeping) {
12255                                            app.keeping = true;
12256                                        }
12257                                        adjType = "service";
12258                                    }
12259                                }
12260                                if (adjType != null) {
12261                                    app.adjType = adjType;
12262                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12263                                            .REASON_SERVICE_IN_USE;
12264                                    app.adjSource = cr.binding.client;
12265                                    app.adjSourceOom = clientAdj;
12266                                    app.adjTarget = s.name;
12267                                }
12268                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12269                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12270                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12271                                    }
12272                                }
12273                            }
12274                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12275                                ActivityRecord a = cr.activity;
12276                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12277                                        (a.visible || a.state == ActivityState.RESUMED
12278                                         || a.state == ActivityState.PAUSING)) {
12279                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12280                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12281                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12282                                    }
12283                                    app.hidden = false;
12284                                    app.adjType = "service";
12285                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12286                                            .REASON_SERVICE_IN_USE;
12287                                    app.adjSource = a;
12288                                    app.adjSourceOom = adj;
12289                                    app.adjTarget = s.name;
12290                                }
12291                            }
12292                        }
12293                    }
12294                }
12295            }
12296
12297            // Finally, if this process has active services running in it, we
12298            // would like to avoid killing it unless it would prevent the current
12299            // application from running.  By default we put the process in
12300            // with the rest of the background processes; as we scan through
12301            // its services we may bump it up from there.
12302            if (adj > hiddenAdj) {
12303                adj = hiddenAdj;
12304                app.hidden = false;
12305                app.adjType = "bg-services";
12306            }
12307        }
12308
12309        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12310                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12311            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12312            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12313                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12314                ContentProviderRecord cpr = jt.next();
12315                for (int i = cpr.connections.size()-1;
12316                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12317                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12318                        i--) {
12319                    ContentProviderConnection conn = cpr.connections.get(i);
12320                    ProcessRecord client = conn.client;
12321                    if (client == app) {
12322                        // Being our own client is not interesting.
12323                        continue;
12324                    }
12325                    int myHiddenAdj = hiddenAdj;
12326                    if (myHiddenAdj > client.hiddenAdj) {
12327                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12328                            myHiddenAdj = client.hiddenAdj;
12329                        } else {
12330                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12331                        }
12332                    }
12333                    int clientAdj = computeOomAdjLocked(
12334                        client, myHiddenAdj, TOP_APP, true, doingAll);
12335                    if (adj > clientAdj) {
12336                        if (app.hasShownUi && app != mHomeProcess
12337                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12338                            app.adjType = "bg-ui-provider";
12339                        } else {
12340                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12341                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12342                            app.adjType = "provider";
12343                        }
12344                        if (!client.hidden) {
12345                            app.hidden = false;
12346                        }
12347                        if (client.keeping) {
12348                            app.keeping = true;
12349                        }
12350                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12351                                .REASON_PROVIDER_IN_USE;
12352                        app.adjSource = client;
12353                        app.adjSourceOom = clientAdj;
12354                        app.adjTarget = cpr.name;
12355                    }
12356                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12357                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12358                    }
12359                }
12360                // If the provider has external (non-framework) process
12361                // dependencies, ensure that its adjustment is at least
12362                // FOREGROUND_APP_ADJ.
12363                if (cpr.hasExternalProcessHandles()) {
12364                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12365                        adj = ProcessList.FOREGROUND_APP_ADJ;
12366                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12367                        app.hidden = false;
12368                        app.keeping = true;
12369                        app.adjType = "provider";
12370                        app.adjTarget = cpr.name;
12371                    }
12372                }
12373            }
12374        }
12375
12376        if (adj == ProcessList.SERVICE_ADJ) {
12377            if (doingAll) {
12378                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12379                mNewNumServiceProcs++;
12380            }
12381            if (app.serviceb) {
12382                adj = ProcessList.SERVICE_B_ADJ;
12383            }
12384        } else {
12385            app.serviceb = false;
12386        }
12387
12388        app.nonStoppingAdj = adj;
12389
12390        if (hasStoppingActivities) {
12391            // Only upgrade adjustment.
12392            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12393                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12394                app.adjType = "stopping";
12395            }
12396        }
12397
12398        app.curRawAdj = adj;
12399
12400        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12401        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12402        if (adj > app.maxAdj) {
12403            adj = app.maxAdj;
12404            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12405                schedGroup = Process.THREAD_GROUP_DEFAULT;
12406            }
12407        }
12408        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12409            app.keeping = true;
12410        }
12411
12412        if (app.hasAboveClient) {
12413            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12414            // then we need to drop its adjustment to be lower than the service's
12415            // in order to honor the request.  We want to drop it by one adjustment
12416            // level...  but there is special meaning applied to various levels so
12417            // we will skip some of them.
12418            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12419                // System process will not get dropped, ever
12420            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12421                adj = ProcessList.VISIBLE_APP_ADJ;
12422            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12423                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12424            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12425                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12426            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12427                adj++;
12428            }
12429        }
12430
12431        int importance = app.memImportance;
12432        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12433            app.curAdj = adj;
12434            app.curSchedGroup = schedGroup;
12435            if (!interesting) {
12436                // For this reporting, if there is not something explicitly
12437                // interesting in this process then we will push it to the
12438                // background importance.
12439                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12440            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12441                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12442            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12443                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12444            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12445                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12446            } else if (adj >= ProcessList.SERVICE_ADJ) {
12447                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12448            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12449                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12450            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12451                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12452            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12453                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12454            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12455                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12456            } else {
12457                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12458            }
12459        }
12460
12461        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12462        if (foregroundActivities != app.foregroundActivities) {
12463            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12464        }
12465        if (changes != 0) {
12466            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12467            app.memImportance = importance;
12468            app.foregroundActivities = foregroundActivities;
12469            int i = mPendingProcessChanges.size()-1;
12470            ProcessChangeItem item = null;
12471            while (i >= 0) {
12472                item = mPendingProcessChanges.get(i);
12473                if (item.pid == app.pid) {
12474                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12475                    break;
12476                }
12477                i--;
12478            }
12479            if (i < 0) {
12480                // No existing item in pending changes; need a new one.
12481                final int NA = mAvailProcessChanges.size();
12482                if (NA > 0) {
12483                    item = mAvailProcessChanges.remove(NA-1);
12484                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12485                } else {
12486                    item = new ProcessChangeItem();
12487                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12488                }
12489                item.changes = 0;
12490                item.pid = app.pid;
12491                item.uid = app.info.uid;
12492                if (mPendingProcessChanges.size() == 0) {
12493                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12494                            "*** Enqueueing dispatch processes changed!");
12495                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12496                }
12497                mPendingProcessChanges.add(item);
12498            }
12499            item.changes |= changes;
12500            item.importance = importance;
12501            item.foregroundActivities = foregroundActivities;
12502            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12503                    + Integer.toHexString(System.identityHashCode(item))
12504                    + " " + app.toShortString() + ": changes=" + item.changes
12505                    + " importance=" + item.importance
12506                    + " foreground=" + item.foregroundActivities
12507                    + " type=" + app.adjType + " source=" + app.adjSource
12508                    + " target=" + app.adjTarget);
12509        }
12510
12511        return app.curRawAdj;
12512    }
12513
12514    /**
12515     * Ask a given process to GC right now.
12516     */
12517    final void performAppGcLocked(ProcessRecord app) {
12518        try {
12519            app.lastRequestedGc = SystemClock.uptimeMillis();
12520            if (app.thread != null) {
12521                if (app.reportLowMemory) {
12522                    app.reportLowMemory = false;
12523                    app.thread.scheduleLowMemory();
12524                } else {
12525                    app.thread.processInBackground();
12526                }
12527            }
12528        } catch (Exception e) {
12529            // whatever.
12530        }
12531    }
12532
12533    /**
12534     * Returns true if things are idle enough to perform GCs.
12535     */
12536    private final boolean canGcNowLocked() {
12537        boolean processingBroadcasts = false;
12538        for (BroadcastQueue q : mBroadcastQueues) {
12539            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12540                processingBroadcasts = true;
12541            }
12542        }
12543        return !processingBroadcasts
12544                && (mSleeping || (mMainStack.mResumedActivity != null &&
12545                        mMainStack.mResumedActivity.idle));
12546    }
12547
12548    /**
12549     * Perform GCs on all processes that are waiting for it, but only
12550     * if things are idle.
12551     */
12552    final void performAppGcsLocked() {
12553        final int N = mProcessesToGc.size();
12554        if (N <= 0) {
12555            return;
12556        }
12557        if (canGcNowLocked()) {
12558            while (mProcessesToGc.size() > 0) {
12559                ProcessRecord proc = mProcessesToGc.remove(0);
12560                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12561                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12562                            <= SystemClock.uptimeMillis()) {
12563                        // To avoid spamming the system, we will GC processes one
12564                        // at a time, waiting a few seconds between each.
12565                        performAppGcLocked(proc);
12566                        scheduleAppGcsLocked();
12567                        return;
12568                    } else {
12569                        // It hasn't been long enough since we last GCed this
12570                        // process...  put it in the list to wait for its time.
12571                        addProcessToGcListLocked(proc);
12572                        break;
12573                    }
12574                }
12575            }
12576
12577            scheduleAppGcsLocked();
12578        }
12579    }
12580
12581    /**
12582     * If all looks good, perform GCs on all processes waiting for them.
12583     */
12584    final void performAppGcsIfAppropriateLocked() {
12585        if (canGcNowLocked()) {
12586            performAppGcsLocked();
12587            return;
12588        }
12589        // Still not idle, wait some more.
12590        scheduleAppGcsLocked();
12591    }
12592
12593    /**
12594     * Schedule the execution of all pending app GCs.
12595     */
12596    final void scheduleAppGcsLocked() {
12597        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12598
12599        if (mProcessesToGc.size() > 0) {
12600            // Schedule a GC for the time to the next process.
12601            ProcessRecord proc = mProcessesToGc.get(0);
12602            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12603
12604            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12605            long now = SystemClock.uptimeMillis();
12606            if (when < (now+GC_TIMEOUT)) {
12607                when = now + GC_TIMEOUT;
12608            }
12609            mHandler.sendMessageAtTime(msg, when);
12610        }
12611    }
12612
12613    /**
12614     * Add a process to the array of processes waiting to be GCed.  Keeps the
12615     * list in sorted order by the last GC time.  The process can't already be
12616     * on the list.
12617     */
12618    final void addProcessToGcListLocked(ProcessRecord proc) {
12619        boolean added = false;
12620        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12621            if (mProcessesToGc.get(i).lastRequestedGc <
12622                    proc.lastRequestedGc) {
12623                added = true;
12624                mProcessesToGc.add(i+1, proc);
12625                break;
12626            }
12627        }
12628        if (!added) {
12629            mProcessesToGc.add(0, proc);
12630        }
12631    }
12632
12633    /**
12634     * Set up to ask a process to GC itself.  This will either do it
12635     * immediately, or put it on the list of processes to gc the next
12636     * time things are idle.
12637     */
12638    final void scheduleAppGcLocked(ProcessRecord app) {
12639        long now = SystemClock.uptimeMillis();
12640        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12641            return;
12642        }
12643        if (!mProcessesToGc.contains(app)) {
12644            addProcessToGcListLocked(app);
12645            scheduleAppGcsLocked();
12646        }
12647    }
12648
12649    final void checkExcessivePowerUsageLocked(boolean doKills) {
12650        updateCpuStatsNow();
12651
12652        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12653        boolean doWakeKills = doKills;
12654        boolean doCpuKills = doKills;
12655        if (mLastPowerCheckRealtime == 0) {
12656            doWakeKills = false;
12657        }
12658        if (mLastPowerCheckUptime == 0) {
12659            doCpuKills = false;
12660        }
12661        if (stats.isScreenOn()) {
12662            doWakeKills = false;
12663        }
12664        final long curRealtime = SystemClock.elapsedRealtime();
12665        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12666        final long curUptime = SystemClock.uptimeMillis();
12667        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12668        mLastPowerCheckRealtime = curRealtime;
12669        mLastPowerCheckUptime = curUptime;
12670        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12671            doWakeKills = false;
12672        }
12673        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12674            doCpuKills = false;
12675        }
12676        int i = mLruProcesses.size();
12677        while (i > 0) {
12678            i--;
12679            ProcessRecord app = mLruProcesses.get(i);
12680            if (!app.keeping) {
12681                long wtime;
12682                synchronized (stats) {
12683                    wtime = stats.getProcessWakeTime(app.info.uid,
12684                            app.pid, curRealtime);
12685                }
12686                long wtimeUsed = wtime - app.lastWakeTime;
12687                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12688                if (DEBUG_POWER) {
12689                    StringBuilder sb = new StringBuilder(128);
12690                    sb.append("Wake for ");
12691                    app.toShortString(sb);
12692                    sb.append(": over ");
12693                    TimeUtils.formatDuration(realtimeSince, sb);
12694                    sb.append(" used ");
12695                    TimeUtils.formatDuration(wtimeUsed, sb);
12696                    sb.append(" (");
12697                    sb.append((wtimeUsed*100)/realtimeSince);
12698                    sb.append("%)");
12699                    Slog.i(TAG, sb.toString());
12700                    sb.setLength(0);
12701                    sb.append("CPU for ");
12702                    app.toShortString(sb);
12703                    sb.append(": over ");
12704                    TimeUtils.formatDuration(uptimeSince, sb);
12705                    sb.append(" used ");
12706                    TimeUtils.formatDuration(cputimeUsed, sb);
12707                    sb.append(" (");
12708                    sb.append((cputimeUsed*100)/uptimeSince);
12709                    sb.append("%)");
12710                    Slog.i(TAG, sb.toString());
12711                }
12712                // If a process has held a wake lock for more
12713                // than 50% of the time during this period,
12714                // that sounds bad.  Kill!
12715                if (doWakeKills && realtimeSince > 0
12716                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12717                    synchronized (stats) {
12718                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12719                                realtimeSince, wtimeUsed);
12720                    }
12721                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12722                            + " (pid " + app.pid + "): held " + wtimeUsed
12723                            + " during " + realtimeSince);
12724                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12725                            app.processName, app.setAdj, "excessive wake lock");
12726                    Process.killProcessQuiet(app.pid);
12727                } else if (doCpuKills && uptimeSince > 0
12728                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12729                    synchronized (stats) {
12730                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12731                                uptimeSince, cputimeUsed);
12732                    }
12733                    Slog.w(TAG, "Excessive CPU in " + app.processName
12734                            + " (pid " + app.pid + "): used " + cputimeUsed
12735                            + " during " + uptimeSince);
12736                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12737                            app.processName, app.setAdj, "excessive cpu");
12738                    Process.killProcessQuiet(app.pid);
12739                } else {
12740                    app.lastWakeTime = wtime;
12741                    app.lastCpuTime = app.curCpuTime;
12742                }
12743            }
12744        }
12745    }
12746
12747    private final boolean updateOomAdjLocked(
12748            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
12749        app.hiddenAdj = hiddenAdj;
12750
12751        if (app.thread == null) {
12752            return false;
12753        }
12754
12755        final boolean wasKeeping = app.keeping;
12756
12757        boolean success = true;
12758
12759        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
12760
12761        if (app.curRawAdj != app.setRawAdj) {
12762            if (wasKeeping && !app.keeping) {
12763                // This app is no longer something we want to keep.  Note
12764                // its current wake lock time to later know to kill it if
12765                // it is not behaving well.
12766                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12767                synchronized (stats) {
12768                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12769                            app.pid, SystemClock.elapsedRealtime());
12770                }
12771                app.lastCpuTime = app.curCpuTime;
12772            }
12773
12774            app.setRawAdj = app.curRawAdj;
12775        }
12776
12777        if (app.curAdj != app.setAdj) {
12778            if (Process.setOomAdj(app.pid, app.curAdj)) {
12779                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12780                    TAG, "Set " + app.pid + " " + app.processName +
12781                    " adj " + app.curAdj + ": " + app.adjType);
12782                app.setAdj = app.curAdj;
12783            } else {
12784                success = false;
12785                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12786            }
12787        }
12788        if (app.setSchedGroup != app.curSchedGroup) {
12789            app.setSchedGroup = app.curSchedGroup;
12790            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12791                    "Setting process group of " + app.processName
12792                    + " to " + app.curSchedGroup);
12793            if (app.waitingToKill != null &&
12794                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12795                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12796                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12797                        app.processName, app.setAdj, app.waitingToKill);
12798                app.killedBackground = true;
12799                Process.killProcessQuiet(app.pid);
12800                success = false;
12801            } else {
12802                if (true) {
12803                    long oldId = Binder.clearCallingIdentity();
12804                    try {
12805                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12806                    } catch (Exception e) {
12807                        Slog.w(TAG, "Failed setting process group of " + app.pid
12808                                + " to " + app.curSchedGroup);
12809                        e.printStackTrace();
12810                    } finally {
12811                        Binder.restoreCallingIdentity(oldId);
12812                    }
12813                } else {
12814                    if (app.thread != null) {
12815                        try {
12816                            app.thread.setSchedulingGroup(app.curSchedGroup);
12817                        } catch (RemoteException e) {
12818                        }
12819                    }
12820                }
12821            }
12822        }
12823        return success;
12824    }
12825
12826    private final ActivityRecord resumedAppLocked() {
12827        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12828        if (resumedActivity == null || resumedActivity.app == null) {
12829            resumedActivity = mMainStack.mPausingActivity;
12830            if (resumedActivity == null || resumedActivity.app == null) {
12831                resumedActivity = mMainStack.topRunningActivityLocked(null);
12832            }
12833        }
12834        return resumedActivity;
12835    }
12836
12837    final boolean updateOomAdjLocked(ProcessRecord app) {
12838        final ActivityRecord TOP_ACT = resumedAppLocked();
12839        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12840        int curAdj = app.curAdj;
12841        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12842            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12843
12844        mAdjSeq++;
12845
12846        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
12847        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12848            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12849        if (nowHidden != wasHidden) {
12850            // Changed to/from hidden state, so apps after it in the LRU
12851            // list may also be changed.
12852            updateOomAdjLocked();
12853        }
12854        return success;
12855    }
12856
12857    final void updateOomAdjLocked() {
12858        final ActivityRecord TOP_ACT = resumedAppLocked();
12859        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12860
12861        if (false) {
12862            RuntimeException e = new RuntimeException();
12863            e.fillInStackTrace();
12864            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12865        }
12866
12867        mAdjSeq++;
12868        mNewNumServiceProcs = 0;
12869
12870        // Let's determine how many processes we have running vs.
12871        // how many slots we have for background processes; we may want
12872        // to put multiple processes in a slot of there are enough of
12873        // them.
12874        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
12875        int factor = (mLruProcesses.size()-4)/numSlots;
12876        if (factor < 1) factor = 1;
12877        int step = 0;
12878        int numHidden = 0;
12879        int numTrimming = 0;
12880
12881        // First update the OOM adjustment for each of the
12882        // application processes based on their current state.
12883        int i = mLruProcesses.size();
12884        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
12885        while (i > 0) {
12886            i--;
12887            ProcessRecord app = mLruProcesses.get(i);
12888            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
12889            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
12890            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
12891                && app.curAdj == curHiddenAdj) {
12892                step++;
12893                if (step >= factor) {
12894                    step = 0;
12895                    curHiddenAdj++;
12896                }
12897            }
12898            if (!app.killedBackground) {
12899                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12900                    numHidden++;
12901                    if (numHidden > mProcessLimit) {
12902                        Slog.i(TAG, "No longer want " + app.processName
12903                                + " (pid " + app.pid + "): hidden #" + numHidden);
12904                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12905                                app.processName, app.setAdj, "too many background");
12906                        app.killedBackground = true;
12907                        Process.killProcessQuiet(app.pid);
12908                    }
12909                }
12910                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
12911                    // If this is an isolated process, and there are no
12912                    // services running in it, then the process is no longer
12913                    // needed.  We agressively kill these because we can by
12914                    // definition not re-use the same process again, and it is
12915                    // good to avoid having whatever code was running in them
12916                    // left sitting around after no longer needed.
12917                    Slog.i(TAG, "Isolated process " + app.processName
12918                            + " (pid " + app.pid + ") no longer needed");
12919                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12920                            app.processName, app.setAdj, "isolated not needed");
12921                    app.killedBackground = true;
12922                    Process.killProcessQuiet(app.pid);
12923                }
12924                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
12925                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
12926                        && !app.killedBackground) {
12927                    numTrimming++;
12928                }
12929            }
12930        }
12931
12932        mNumServiceProcs = mNewNumServiceProcs;
12933
12934        // Now determine the memory trimming level of background processes.
12935        // Unfortunately we need to start at the back of the list to do this
12936        // properly.  We only do this if the number of background apps we
12937        // are managing to keep around is less than half the maximum we desire;
12938        // if we are keeping a good number around, we'll let them use whatever
12939        // memory they want.
12940        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
12941            final int N = mLruProcesses.size();
12942            factor = numTrimming/3;
12943            int minFactor = 2;
12944            if (mHomeProcess != null) minFactor++;
12945            if (mPreviousProcess != null) minFactor++;
12946            if (factor < minFactor) factor = minFactor;
12947            step = 0;
12948            int fgTrimLevel;
12949            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
12950                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
12951            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
12952                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
12953            } else {
12954                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
12955            }
12956            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
12957            for (i=0; i<N; i++) {
12958                ProcessRecord app = mLruProcesses.get(i);
12959                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
12960                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
12961                        && !app.killedBackground) {
12962                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
12963                        try {
12964                            app.thread.scheduleTrimMemory(curLevel);
12965                        } catch (RemoteException e) {
12966                        }
12967                        if (false) {
12968                            // For now we won't do this; our memory trimming seems
12969                            // to be good enough at this point that destroying
12970                            // activities causes more harm than good.
12971                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
12972                                    && app != mHomeProcess && app != mPreviousProcess) {
12973                                // Need to do this on its own message because the stack may not
12974                                // be in a consistent state at this point.
12975                                // For these apps we will also finish their activities
12976                                // to help them free memory.
12977                                mMainStack.scheduleDestroyActivities(app, false, "trim");
12978                            }
12979                        }
12980                    }
12981                    app.trimMemoryLevel = curLevel;
12982                    step++;
12983                    if (step >= factor) {
12984                        step = 0;
12985                        switch (curLevel) {
12986                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
12987                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
12988                                break;
12989                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
12990                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
12991                                break;
12992                        }
12993                    }
12994                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12995                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
12996                            && app.thread != null) {
12997                        try {
12998                            app.thread.scheduleTrimMemory(
12999                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13000                        } catch (RemoteException e) {
13001                        }
13002                    }
13003                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13004                } else {
13005                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13006                            && app.pendingUiClean) {
13007                        // If this application is now in the background and it
13008                        // had done UI, then give it the special trim level to
13009                        // have it free UI resources.
13010                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13011                        if (app.trimMemoryLevel < level && app.thread != null) {
13012                            try {
13013                                app.thread.scheduleTrimMemory(level);
13014                            } catch (RemoteException e) {
13015                            }
13016                        }
13017                        app.pendingUiClean = false;
13018                    }
13019                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13020                        try {
13021                            app.thread.scheduleTrimMemory(fgTrimLevel);
13022                        } catch (RemoteException e) {
13023                        }
13024                    }
13025                    app.trimMemoryLevel = fgTrimLevel;
13026                }
13027            }
13028        } else {
13029            final int N = mLruProcesses.size();
13030            for (i=0; i<N; i++) {
13031                ProcessRecord app = mLruProcesses.get(i);
13032                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13033                        && app.pendingUiClean) {
13034                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13035                            && app.thread != null) {
13036                        try {
13037                            app.thread.scheduleTrimMemory(
13038                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13039                        } catch (RemoteException e) {
13040                        }
13041                    }
13042                    app.pendingUiClean = false;
13043                }
13044                app.trimMemoryLevel = 0;
13045            }
13046        }
13047
13048        if (mAlwaysFinishActivities) {
13049            // Need to do this on its own message because the stack may not
13050            // be in a consistent state at this point.
13051            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13052        }
13053    }
13054
13055    final void trimApplications() {
13056        synchronized (this) {
13057            int i;
13058
13059            // First remove any unused application processes whose package
13060            // has been removed.
13061            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13062                final ProcessRecord app = mRemovedProcesses.get(i);
13063                if (app.activities.size() == 0
13064                        && app.curReceiver == null && app.services.size() == 0) {
13065                    Slog.i(
13066                        TAG, "Exiting empty application process "
13067                        + app.processName + " ("
13068                        + (app.thread != null ? app.thread.asBinder() : null)
13069                        + ")\n");
13070                    if (app.pid > 0 && app.pid != MY_PID) {
13071                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13072                                app.processName, app.setAdj, "empty");
13073                        Process.killProcessQuiet(app.pid);
13074                    } else {
13075                        try {
13076                            app.thread.scheduleExit();
13077                        } catch (Exception e) {
13078                            // Ignore exceptions.
13079                        }
13080                    }
13081                    cleanUpApplicationRecordLocked(app, false, true, -1);
13082                    mRemovedProcesses.remove(i);
13083
13084                    if (app.persistent) {
13085                        if (app.persistent) {
13086                            addAppLocked(app.info, false);
13087                        }
13088                    }
13089                }
13090            }
13091
13092            // Now update the oom adj for all processes.
13093            updateOomAdjLocked();
13094        }
13095    }
13096
13097    /** This method sends the specified signal to each of the persistent apps */
13098    public void signalPersistentProcesses(int sig) throws RemoteException {
13099        if (sig != Process.SIGNAL_USR1) {
13100            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13101        }
13102
13103        synchronized (this) {
13104            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13105                    != PackageManager.PERMISSION_GRANTED) {
13106                throw new SecurityException("Requires permission "
13107                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13108            }
13109
13110            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13111                ProcessRecord r = mLruProcesses.get(i);
13112                if (r.thread != null && r.persistent) {
13113                    Process.sendSignal(r.pid, sig);
13114                }
13115            }
13116        }
13117    }
13118
13119    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13120        if (proc == null || proc == mProfileProc) {
13121            proc = mProfileProc;
13122            path = mProfileFile;
13123            profileType = mProfileType;
13124            clearProfilerLocked();
13125        }
13126        if (proc == null) {
13127            return;
13128        }
13129        try {
13130            proc.thread.profilerControl(false, path, null, profileType);
13131        } catch (RemoteException e) {
13132            throw new IllegalStateException("Process disappeared");
13133        }
13134    }
13135
13136    private void clearProfilerLocked() {
13137        if (mProfileFd != null) {
13138            try {
13139                mProfileFd.close();
13140            } catch (IOException e) {
13141            }
13142        }
13143        mProfileApp = null;
13144        mProfileProc = null;
13145        mProfileFile = null;
13146        mProfileType = 0;
13147        mAutoStopProfiler = false;
13148    }
13149
13150    public boolean profileControl(String process, boolean start,
13151            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13152
13153        try {
13154            synchronized (this) {
13155                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13156                // its own permission.
13157                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13158                        != PackageManager.PERMISSION_GRANTED) {
13159                    throw new SecurityException("Requires permission "
13160                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13161                }
13162
13163                if (start && fd == null) {
13164                    throw new IllegalArgumentException("null fd");
13165                }
13166
13167                ProcessRecord proc = null;
13168                if (process != null) {
13169                    try {
13170                        int pid = Integer.parseInt(process);
13171                        synchronized (mPidsSelfLocked) {
13172                            proc = mPidsSelfLocked.get(pid);
13173                        }
13174                    } catch (NumberFormatException e) {
13175                    }
13176
13177                    if (proc == null) {
13178                        HashMap<String, SparseArray<ProcessRecord>> all
13179                                = mProcessNames.getMap();
13180                        SparseArray<ProcessRecord> procs = all.get(process);
13181                        if (procs != null && procs.size() > 0) {
13182                            proc = procs.valueAt(0);
13183                        }
13184                    }
13185                }
13186
13187                if (start && (proc == null || proc.thread == null)) {
13188                    throw new IllegalArgumentException("Unknown process: " + process);
13189                }
13190
13191                if (start) {
13192                    stopProfilerLocked(null, null, 0);
13193                    setProfileApp(proc.info, proc.processName, path, fd, false);
13194                    mProfileProc = proc;
13195                    mProfileType = profileType;
13196                    try {
13197                        fd = fd.dup();
13198                    } catch (IOException e) {
13199                        fd = null;
13200                    }
13201                    proc.thread.profilerControl(start, path, fd, profileType);
13202                    fd = null;
13203                    mProfileFd = null;
13204                } else {
13205                    stopProfilerLocked(proc, path, profileType);
13206                    if (fd != null) {
13207                        try {
13208                            fd.close();
13209                        } catch (IOException e) {
13210                        }
13211                    }
13212                }
13213
13214                return true;
13215            }
13216        } catch (RemoteException e) {
13217            throw new IllegalStateException("Process disappeared");
13218        } finally {
13219            if (fd != null) {
13220                try {
13221                    fd.close();
13222                } catch (IOException e) {
13223                }
13224            }
13225        }
13226    }
13227
13228    public boolean dumpHeap(String process, boolean managed,
13229            String path, ParcelFileDescriptor fd) throws RemoteException {
13230
13231        try {
13232            synchronized (this) {
13233                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13234                // its own permission (same as profileControl).
13235                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13236                        != PackageManager.PERMISSION_GRANTED) {
13237                    throw new SecurityException("Requires permission "
13238                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13239                }
13240
13241                if (fd == null) {
13242                    throw new IllegalArgumentException("null fd");
13243                }
13244
13245                ProcessRecord proc = null;
13246                try {
13247                    int pid = Integer.parseInt(process);
13248                    synchronized (mPidsSelfLocked) {
13249                        proc = mPidsSelfLocked.get(pid);
13250                    }
13251                } catch (NumberFormatException e) {
13252                }
13253
13254                if (proc == null) {
13255                    HashMap<String, SparseArray<ProcessRecord>> all
13256                            = mProcessNames.getMap();
13257                    SparseArray<ProcessRecord> procs = all.get(process);
13258                    if (procs != null && procs.size() > 0) {
13259                        proc = procs.valueAt(0);
13260                    }
13261                }
13262
13263                if (proc == null || proc.thread == null) {
13264                    throw new IllegalArgumentException("Unknown process: " + process);
13265                }
13266
13267                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13268                if (!isDebuggable) {
13269                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13270                        throw new SecurityException("Process not debuggable: " + proc);
13271                    }
13272                }
13273
13274                proc.thread.dumpHeap(managed, path, fd);
13275                fd = null;
13276                return true;
13277            }
13278        } catch (RemoteException e) {
13279            throw new IllegalStateException("Process disappeared");
13280        } finally {
13281            if (fd != null) {
13282                try {
13283                    fd.close();
13284                } catch (IOException e) {
13285                }
13286            }
13287        }
13288    }
13289
13290    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13291    public void monitor() {
13292        synchronized (this) { }
13293    }
13294
13295    void onCoreSettingsChange(Bundle settings) {
13296        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13297            ProcessRecord processRecord = mLruProcesses.get(i);
13298            try {
13299                if (processRecord.thread != null) {
13300                    processRecord.thread.setCoreSettings(settings);
13301                }
13302            } catch (RemoteException re) {
13303                /* ignore */
13304            }
13305        }
13306    }
13307
13308    // Multi-user methods
13309
13310    private int mCurrentUserId;
13311    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
13312
13313    public boolean switchUser(int userId) {
13314        final int callingUid = Binder.getCallingUid();
13315        if (callingUid != 0 && callingUid != Process.myUid()) {
13316            Slog.e(TAG, "Trying to switch user from unauthorized app");
13317            return false;
13318        }
13319        if (mCurrentUserId == userId)
13320            return true;
13321
13322        synchronized (this) {
13323            // Check if user is already logged in, otherwise check if user exists first before
13324            // adding to the list of logged in users.
13325            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13326                if (!userExists(userId)) {
13327                    return false;
13328                }
13329                mLoggedInUsers.append(userId, userId);
13330            }
13331
13332            mCurrentUserId = userId;
13333            boolean haveActivities = mMainStack.switchUser(userId);
13334            if (!haveActivities) {
13335                startHomeActivityLocked(userId);
13336            }
13337
13338        }
13339
13340        // Inform of user switch
13341        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13342        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
13343        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
13344
13345        return true;
13346    }
13347
13348    @Override
13349    public UserInfo getCurrentUser() throws RemoteException {
13350        final int callingUid = Binder.getCallingUid();
13351        if (callingUid != 0 && callingUid != Process.myUid()) {
13352            Slog.e(TAG, "Trying to get user from unauthorized app");
13353            return null;
13354        }
13355        return AppGlobals.getPackageManager().getUser(mCurrentUserId);
13356    }
13357
13358    private void onUserRemoved(Intent intent) {
13359        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
13360        if (extraUserId < 1) return;
13361
13362        // Kill all the processes for the user
13363        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13364        synchronized (this) {
13365            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13366            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13367                SparseArray<ProcessRecord> uids = uidMap.getValue();
13368                for (int i = 0; i < uids.size(); i++) {
13369                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
13370                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13371                    }
13372                }
13373            }
13374
13375            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13376                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13377                        false, false, true, true, extraUserId);
13378            }
13379        }
13380    }
13381
13382    private boolean userExists(int userId) {
13383        try {
13384            UserInfo user = AppGlobals.getPackageManager().getUser(userId);
13385            return user != null;
13386        } catch (RemoteException re) {
13387            // Won't happen, in same process
13388        }
13389
13390        return false;
13391    }
13392
13393    private void checkValidCaller(int uid, int userId) {
13394        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13395
13396        throw new SecurityException("Caller uid=" + uid
13397                + " is not privileged to communicate with user=" + userId);
13398    }
13399
13400    private int applyUserId(int uid, int userId) {
13401        return UserId.getUid(userId, uid);
13402    }
13403
13404    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13405        if (info == null) return null;
13406        ApplicationInfo newInfo = new ApplicationInfo(info);
13407        newInfo.uid = applyUserId(info.uid, userId);
13408        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13409                + info.packageName;
13410        return newInfo;
13411    }
13412
13413    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13414        if (aInfo == null
13415                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
13416            return aInfo;
13417        }
13418
13419        ActivityInfo info = new ActivityInfo(aInfo);
13420        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13421        return info;
13422    }
13423}
13424