ActivityManagerService.java revision 4ee364982e783b4a2eac6e05f81d167c6121e110
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 for a service to finish executing.
245    static final int SERVICE_TIMEOUT = 20*1000;
246
247    // How long a service needs to be running until restarting its process
248    // is no longer considered to be a relaunch of the service.
249    static final int SERVICE_RESTART_DURATION = 5*1000;
250
251    // How long a service needs to be running until it will start back at
252    // SERVICE_RESTART_DURATION after being killed.
253    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
254
255    // Multiplying factor to increase restart duration time by, for each time
256    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
257    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
258
259    // The minimum amount of time between restarting services that we allow.
260    // That is, when multiple services are restarting, we won't allow each
261    // to restart less than this amount of time from the last one.
262    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
263
264    // Maximum amount of time for there to be no activity on a service before
265    // we consider it non-essential and allow its process to go on the
266    // LRU background list.
267    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
268
269    // How long we wait until we timeout on key dispatching.
270    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
271
272    // How long we wait until we timeout on key dispatching during instrumentation.
273    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
274
275    static final int MY_PID = Process.myPid();
276
277    static final String[] EMPTY_STRING_ARRAY = new String[0];
278
279    public ActivityStack mMainStack;
280
281    private final boolean mHeadless;
282
283    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
284    // default actuion automatically.  Important for devices without direct input
285    // devices.
286    private boolean mShowDialogs = true;
287
288    /**
289     * Description of a request to start a new activity, which has been held
290     * due to app switches being disabled.
291     */
292    static class PendingActivityLaunch {
293        ActivityRecord r;
294        ActivityRecord sourceRecord;
295        int startFlags;
296    }
297
298    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
299            = new ArrayList<PendingActivityLaunch>();
300
301
302    BroadcastQueue mFgBroadcastQueue;
303    BroadcastQueue mBgBroadcastQueue;
304    // Convenient for easy iteration over the queues. Foreground is first
305    // so that dispatch of foreground broadcasts gets precedence.
306    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
307
308    BroadcastQueue broadcastQueueForIntent(Intent intent) {
309        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
310        if (DEBUG_BACKGROUND_BROADCAST) {
311            Slog.i(TAG, "Broadcast intent " + intent + " on "
312                    + (isFg ? "foreground" : "background")
313                    + " queue");
314        }
315        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
316    }
317
318    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
319        for (BroadcastQueue queue : mBroadcastQueues) {
320            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
321            if (r != null) {
322                return r;
323            }
324        }
325        return null;
326    }
327
328    /**
329     * Activity we have told the window manager to have key focus.
330     */
331    ActivityRecord mFocusedActivity = null;
332    /**
333     * List of intents that were used to start the most recent tasks.
334     */
335    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
336
337    /**
338     * Process management.
339     */
340    final ProcessList mProcessList = new ProcessList();
341
342    /**
343     * All of the applications we currently have running organized by name.
344     * The keys are strings of the application package name (as
345     * returned by the package manager), and the keys are ApplicationRecord
346     * objects.
347     */
348    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
349
350    /**
351     * The currently running isolated processes.
352     */
353    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
354
355    /**
356     * Counter for assigning isolated process uids, to avoid frequently reusing the
357     * same ones.
358     */
359    int mNextIsolatedProcessUid = 0;
360
361    /**
362     * The currently running heavy-weight process, if any.
363     */
364    ProcessRecord mHeavyWeightProcess = null;
365
366    /**
367     * The last time that various processes have crashed.
368     */
369    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
370
371    /**
372     * Set of applications that we consider to be bad, and will reject
373     * incoming broadcasts from (which the user has no control over).
374     * Processes are added to this set when they have crashed twice within
375     * a minimum amount of time; they are removed from it when they are
376     * later restarted (hopefully due to some user action).  The value is the
377     * time it was added to the list.
378     */
379    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
380
381    /**
382     * All of the processes we currently have running organized by pid.
383     * The keys are the pid running the application.
384     *
385     * <p>NOTE: This object is protected by its own lock, NOT the global
386     * activity manager lock!
387     */
388    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
389
390    /**
391     * All of the processes that have been forced to be foreground.  The key
392     * is the pid of the caller who requested it (we hold a death
393     * link on it).
394     */
395    abstract class ForegroundToken implements IBinder.DeathRecipient {
396        int pid;
397        IBinder token;
398    }
399    final SparseArray<ForegroundToken> mForegroundProcesses
400            = new SparseArray<ForegroundToken>();
401
402    /**
403     * List of records for processes that someone had tried to start before the
404     * system was ready.  We don't start them at that point, but ensure they
405     * are started by the time booting is complete.
406     */
407    final ArrayList<ProcessRecord> mProcessesOnHold
408            = new ArrayList<ProcessRecord>();
409
410    /**
411     * List of persistent applications that are in the process
412     * of being started.
413     */
414    final ArrayList<ProcessRecord> mPersistentStartingProcesses
415            = new ArrayList<ProcessRecord>();
416
417    /**
418     * Processes that are being forcibly torn down.
419     */
420    final ArrayList<ProcessRecord> mRemovedProcesses
421            = new ArrayList<ProcessRecord>();
422
423    /**
424     * List of running applications, sorted by recent usage.
425     * The first entry in the list is the least recently used.
426     * It contains ApplicationRecord objects.  This list does NOT include
427     * any persistent application records (since we never want to exit them).
428     */
429    final ArrayList<ProcessRecord> mLruProcesses
430            = new ArrayList<ProcessRecord>();
431
432    /**
433     * List of processes that should gc as soon as things are idle.
434     */
435    final ArrayList<ProcessRecord> mProcessesToGc
436            = new ArrayList<ProcessRecord>();
437
438    /**
439     * This is the process holding what we currently consider to be
440     * the "home" activity.
441     */
442    ProcessRecord mHomeProcess;
443
444    /**
445     * This is the process holding the activity the user last visited that
446     * is in a different process from the one they are currently in.
447     */
448    ProcessRecord mPreviousProcess;
449
450    /**
451     * The time at which the previous process was last visible.
452     */
453    long mPreviousProcessVisibleTime;
454
455    /**
456     * Packages that the user has asked to have run in screen size
457     * compatibility mode instead of filling the screen.
458     */
459    final CompatModePackages mCompatModePackages;
460
461    /**
462     * Set of PendingResultRecord objects that are currently active.
463     */
464    final HashSet mPendingResultRecords = new HashSet();
465
466    /**
467     * Set of IntentSenderRecord objects that are currently active.
468     */
469    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
470            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
471
472    /**
473     * Fingerprints (hashCode()) of stack traces that we've
474     * already logged DropBox entries for.  Guarded by itself.  If
475     * something (rogue user app) forces this over
476     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
477     */
478    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
479    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
480
481    /**
482     * Strict Mode background batched logging state.
483     *
484     * The string buffer is guarded by itself, and its lock is also
485     * used to determine if another batched write is already
486     * in-flight.
487     */
488    private final StringBuilder mStrictModeBuffer = new StringBuilder();
489
490    /**
491     * Keeps track of all IIntentReceivers that have been registered for
492     * broadcasts.  Hash keys are the receiver IBinder, hash value is
493     * a ReceiverList.
494     */
495    final HashMap mRegisteredReceivers = new HashMap();
496
497    /**
498     * Resolver for broadcast intents to registered receivers.
499     * Holds BroadcastFilter (subclass of IntentFilter).
500     */
501    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
502            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
503        @Override
504        protected boolean allowFilterResult(
505                BroadcastFilter filter, List<BroadcastFilter> dest) {
506            IBinder target = filter.receiverList.receiver.asBinder();
507            for (int i=dest.size()-1; i>=0; i--) {
508                if (dest.get(i).receiverList.receiver.asBinder() == target) {
509                    return false;
510                }
511            }
512            return true;
513        }
514
515        @Override
516        protected String packageForFilter(BroadcastFilter filter) {
517            return filter.packageName;
518        }
519    };
520
521    /**
522     * State of all active sticky broadcasts.  Keys are the action of the
523     * sticky Intent, values are an ArrayList of all broadcasted intents with
524     * that action (which should usually be one).
525     */
526    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
527            new HashMap<String, ArrayList<Intent>>();
528
529    final ServiceMap mServiceMap = new ServiceMap();
530
531    /**
532     * All currently bound service connections.  Keys are the IBinder of
533     * the client's IServiceConnection.
534     */
535    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
536            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
537
538    /**
539     * List of services that we have been asked to start,
540     * but haven't yet been able to.  It is used to hold start requests
541     * while waiting for their corresponding application thread to get
542     * going.
543     */
544    final ArrayList<ServiceRecord> mPendingServices
545            = new ArrayList<ServiceRecord>();
546
547    /**
548     * List of services that are scheduled to restart following a crash.
549     */
550    final ArrayList<ServiceRecord> mRestartingServices
551            = new ArrayList<ServiceRecord>();
552
553    /**
554     * List of services that are in the process of being stopped.
555     */
556    final ArrayList<ServiceRecord> mStoppingServices
557            = new ArrayList<ServiceRecord>();
558
559    /**
560     * Backup/restore process management
561     */
562    String mBackupAppName = null;
563    BackupRecord mBackupTarget = null;
564
565    /**
566     * List of PendingThumbnailsRecord objects of clients who are still
567     * waiting to receive all of the thumbnails for a task.
568     */
569    final ArrayList mPendingThumbnails = new ArrayList();
570
571    /**
572     * List of HistoryRecord objects that have been finished and must
573     * still report back to a pending thumbnail receiver.
574     */
575    final ArrayList mCancelledThumbnails = new ArrayList();
576
577    final ProviderMap mProviderMap = new ProviderMap();
578
579    /**
580     * List of content providers who have clients waiting for them.  The
581     * application is currently being launched and the provider will be
582     * removed from this list once it is published.
583     */
584    final ArrayList<ContentProviderRecord> mLaunchingProviders
585            = new ArrayList<ContentProviderRecord>();
586
587    /**
588     * Global set of specific Uri permissions that have been granted.
589     */
590    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591            = new SparseArray<HashMap<Uri, UriPermission>>();
592
593    CoreSettingsObserver mCoreSettingsObserver;
594
595    /**
596     * Thread-local storage used to carry caller permissions over through
597     * indirect content-provider access.
598     * @see #ActivityManagerService.openContentUri()
599     */
600    private class Identity {
601        public int pid;
602        public int uid;
603
604        Identity(int _pid, int _uid) {
605            pid = _pid;
606            uid = _uid;
607        }
608    }
609
610    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
611
612    /**
613     * All information we have collected about the runtime performance of
614     * any user id that can impact battery performance.
615     */
616    final BatteryStatsService mBatteryStatsService;
617
618    /**
619     * information about component usage
620     */
621    final UsageStatsService mUsageStatsService;
622
623    /**
624     * Current configuration information.  HistoryRecord objects are given
625     * a reference to this object to indicate which configuration they are
626     * currently running in, so this object must be kept immutable.
627     */
628    Configuration mConfiguration = new Configuration();
629
630    /**
631     * Current sequencing integer of the configuration, for skipping old
632     * configurations.
633     */
634    int mConfigurationSeq = 0;
635
636    /**
637     * Hardware-reported OpenGLES version.
638     */
639    final int GL_ES_VERSION;
640
641    /**
642     * List of initialization arguments to pass to all processes when binding applications to them.
643     * For example, references to the commonly used services.
644     */
645    HashMap<String, IBinder> mAppBindArgs;
646
647    /**
648     * Temporary to avoid allocations.  Protected by main lock.
649     */
650    final StringBuilder mStringBuilder = new StringBuilder(256);
651
652    /**
653     * Used to control how we initialize the service.
654     */
655    boolean mStartRunning = false;
656    ComponentName mTopComponent;
657    String mTopAction;
658    String mTopData;
659    boolean mProcessesReady = false;
660    boolean mSystemReady = false;
661    boolean mBooting = false;
662    boolean mWaitingUpdate = false;
663    boolean mDidUpdate = false;
664    boolean mOnBattery = false;
665    boolean mLaunchWarningShown = false;
666
667    Context mContext;
668
669    int mFactoryTest;
670
671    boolean mCheckedForSetup;
672
673    /**
674     * The time at which we will allow normal application switches again,
675     * after a call to {@link #stopAppSwitches()}.
676     */
677    long mAppSwitchesAllowedTime;
678
679    /**
680     * This is set to true after the first switch after mAppSwitchesAllowedTime
681     * is set; any switches after that will clear the time.
682     */
683    boolean mDidAppSwitch;
684
685    /**
686     * Last time (in realtime) at which we checked for power usage.
687     */
688    long mLastPowerCheckRealtime;
689
690    /**
691     * Last time (in uptime) at which we checked for power usage.
692     */
693    long mLastPowerCheckUptime;
694
695    /**
696     * Set while we are wanting to sleep, to prevent any
697     * activities from being started/resumed.
698     */
699    boolean mSleeping = false;
700
701    /**
702     * State of external calls telling us if the device is asleep.
703     */
704    boolean mWentToSleep = false;
705
706    /**
707     * State of external call telling us if the lock screen is shown.
708     */
709    boolean mLockScreenShown = false;
710
711    /**
712     * Set if we are shutting down the system, similar to sleeping.
713     */
714    boolean mShuttingDown = false;
715
716    /**
717     * Task identifier that activities are currently being started
718     * in.  Incremented each time a new task is created.
719     * todo: Replace this with a TokenSpace class that generates non-repeating
720     * integers that won't wrap.
721     */
722    int mCurTask = 1;
723
724    /**
725     * Current sequence id for oom_adj computation traversal.
726     */
727    int mAdjSeq = 0;
728
729    /**
730     * Current sequence id for process LRU updating.
731     */
732    int mLruSeq = 0;
733
734    /**
735     * Keep track of the number of service processes we last found, to
736     * determine on the next iteration which should be B services.
737     */
738    int mNumServiceProcs = 0;
739    int mNewNumServiceProcs = 0;
740
741    /**
742     * System monitoring: number of processes that died since the last
743     * N procs were started.
744     */
745    int[] mProcDeaths = new int[20];
746
747    /**
748     * This is set if we had to do a delayed dexopt of an app before launching
749     * it, to increasing the ANR timeouts in that case.
750     */
751    boolean mDidDexOpt;
752
753    String mDebugApp = null;
754    boolean mWaitForDebugger = false;
755    boolean mDebugTransient = false;
756    String mOrigDebugApp = null;
757    boolean mOrigWaitForDebugger = false;
758    boolean mAlwaysFinishActivities = false;
759    IActivityController mController = null;
760    String mProfileApp = null;
761    ProcessRecord mProfileProc = null;
762    String mProfileFile;
763    ParcelFileDescriptor mProfileFd;
764    int mProfileType = 0;
765    boolean mAutoStopProfiler = false;
766    String mOpenGlTraceApp = null;
767
768    static class ProcessChangeItem {
769        static final int CHANGE_ACTIVITIES = 1<<0;
770        static final int CHANGE_IMPORTANCE= 1<<1;
771        int changes;
772        int uid;
773        int pid;
774        int importance;
775        boolean foregroundActivities;
776    }
777
778    final RemoteCallbackList<IProcessObserver> mProcessObservers
779            = new RemoteCallbackList<IProcessObserver>();
780    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
781
782    final ArrayList<ProcessChangeItem> mPendingProcessChanges
783            = new ArrayList<ProcessChangeItem>();
784    final ArrayList<ProcessChangeItem> mAvailProcessChanges
785            = new ArrayList<ProcessChangeItem>();
786
787    /**
788     * Callback of last caller to {@link #requestPss}.
789     */
790    Runnable mRequestPssCallback;
791
792    /**
793     * Remaining processes for which we are waiting results from the last
794     * call to {@link #requestPss}.
795     */
796    final ArrayList<ProcessRecord> mRequestPssList
797            = new ArrayList<ProcessRecord>();
798
799    /**
800     * Runtime statistics collection thread.  This object's lock is used to
801     * protect all related state.
802     */
803    final Thread mProcessStatsThread;
804
805    /**
806     * Used to collect process stats when showing not responding dialog.
807     * Protected by mProcessStatsThread.
808     */
809    final ProcessStats mProcessStats = new ProcessStats(
810            MONITOR_THREAD_CPU_USAGE);
811    final AtomicLong mLastCpuTime = new AtomicLong(0);
812    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
813
814    long mLastWriteTime = 0;
815
816    /**
817     * Set to true after the system has finished booting.
818     */
819    boolean mBooted = false;
820
821    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
822    int mProcessLimitOverride = -1;
823
824    WindowManagerService mWindowManager;
825
826    static ActivityManagerService mSelf;
827    static ActivityThread mSystemThread;
828
829    private final class AppDeathRecipient implements IBinder.DeathRecipient {
830        final ProcessRecord mApp;
831        final int mPid;
832        final IApplicationThread mAppThread;
833
834        AppDeathRecipient(ProcessRecord app, int pid,
835                IApplicationThread thread) {
836            if (localLOGV) Slog.v(
837                TAG, "New death recipient " + this
838                + " for thread " + thread.asBinder());
839            mApp = app;
840            mPid = pid;
841            mAppThread = thread;
842        }
843
844        public void binderDied() {
845            if (localLOGV) Slog.v(
846                TAG, "Death received in " + this
847                + " for thread " + mAppThread.asBinder());
848            synchronized(ActivityManagerService.this) {
849                appDiedLocked(mApp, mPid, mAppThread);
850            }
851        }
852    }
853
854    static final int SHOW_ERROR_MSG = 1;
855    static final int SHOW_NOT_RESPONDING_MSG = 2;
856    static final int SHOW_FACTORY_ERROR_MSG = 3;
857    static final int UPDATE_CONFIGURATION_MSG = 4;
858    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
859    static final int WAIT_FOR_DEBUGGER_MSG = 6;
860    static final int SERVICE_TIMEOUT_MSG = 12;
861    static final int UPDATE_TIME_ZONE = 13;
862    static final int SHOW_UID_ERROR_MSG = 14;
863    static final int IM_FEELING_LUCKY_MSG = 15;
864    static final int PROC_START_TIMEOUT_MSG = 20;
865    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
866    static final int KILL_APPLICATION_MSG = 22;
867    static final int FINALIZE_PENDING_INTENT_MSG = 23;
868    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
869    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
870    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
871    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
872    static final int CLEAR_DNS_CACHE = 28;
873    static final int UPDATE_HTTP_PROXY = 29;
874    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
875    static final int DISPATCH_PROCESSES_CHANGED = 31;
876    static final int DISPATCH_PROCESS_DIED = 32;
877    static final int REPORT_MEM_USAGE = 33;
878
879    static final int FIRST_ACTIVITY_STACK_MSG = 100;
880    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
881    static final int FIRST_COMPAT_MODE_MSG = 300;
882
883    AlertDialog mUidAlert;
884    CompatModeDialog mCompatModeDialog;
885    long mLastMemUsageReportTime = 0;
886
887    final Handler mHandler = new Handler() {
888        //public Handler() {
889        //    if (localLOGV) Slog.v(TAG, "Handler started!");
890        //}
891
892        public void handleMessage(Message msg) {
893            switch (msg.what) {
894            case SHOW_ERROR_MSG: {
895                HashMap data = (HashMap) msg.obj;
896                synchronized (ActivityManagerService.this) {
897                    ProcessRecord proc = (ProcessRecord)data.get("app");
898                    if (proc != null && proc.crashDialog != null) {
899                        Slog.e(TAG, "App already has crash dialog: " + proc);
900                        return;
901                    }
902                    AppErrorResult res = (AppErrorResult) data.get("result");
903                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
904                        Dialog d = new AppErrorDialog(mContext, res, proc);
905                        d.show();
906                        proc.crashDialog = d;
907                    } else {
908                        // The device is asleep, so just pretend that the user
909                        // saw a crash dialog and hit "force quit".
910                        res.set(0);
911                    }
912                }
913
914                ensureBootCompleted();
915            } break;
916            case SHOW_NOT_RESPONDING_MSG: {
917                synchronized (ActivityManagerService.this) {
918                    HashMap data = (HashMap) msg.obj;
919                    ProcessRecord proc = (ProcessRecord)data.get("app");
920                    if (proc != null && proc.anrDialog != null) {
921                        Slog.e(TAG, "App already has anr dialog: " + proc);
922                        return;
923                    }
924
925                    Intent intent = new Intent("android.intent.action.ANR");
926                    if (!mProcessesReady) {
927                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
928                                | Intent.FLAG_RECEIVER_FOREGROUND);
929                    }
930                    broadcastIntentLocked(null, null, intent,
931                            null, null, 0, null, null, null,
932                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
933
934                    if (mShowDialogs) {
935                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
936                                mContext, proc, (ActivityRecord)data.get("activity"));
937                        d.show();
938                        proc.anrDialog = d;
939                    } else {
940                        // Just kill the app if there is no dialog to be shown.
941                        killAppAtUsersRequest(proc, null);
942                    }
943                }
944
945                ensureBootCompleted();
946            } break;
947            case SHOW_STRICT_MODE_VIOLATION_MSG: {
948                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
949                synchronized (ActivityManagerService.this) {
950                    ProcessRecord proc = (ProcessRecord) data.get("app");
951                    if (proc == null) {
952                        Slog.e(TAG, "App not found when showing strict mode dialog.");
953                        break;
954                    }
955                    if (proc.crashDialog != null) {
956                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
957                        return;
958                    }
959                    AppErrorResult res = (AppErrorResult) data.get("result");
960                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
961                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
962                        d.show();
963                        proc.crashDialog = d;
964                    } else {
965                        // The device is asleep, so just pretend that the user
966                        // saw a crash dialog and hit "force quit".
967                        res.set(0);
968                    }
969                }
970                ensureBootCompleted();
971            } break;
972            case SHOW_FACTORY_ERROR_MSG: {
973                Dialog d = new FactoryErrorDialog(
974                    mContext, msg.getData().getCharSequence("msg"));
975                d.show();
976                ensureBootCompleted();
977            } break;
978            case UPDATE_CONFIGURATION_MSG: {
979                final ContentResolver resolver = mContext.getContentResolver();
980                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
981            } break;
982            case GC_BACKGROUND_PROCESSES_MSG: {
983                synchronized (ActivityManagerService.this) {
984                    performAppGcsIfAppropriateLocked();
985                }
986            } break;
987            case WAIT_FOR_DEBUGGER_MSG: {
988                synchronized (ActivityManagerService.this) {
989                    ProcessRecord app = (ProcessRecord)msg.obj;
990                    if (msg.arg1 != 0) {
991                        if (!app.waitedForDebugger) {
992                            Dialog d = new AppWaitingForDebuggerDialog(
993                                    ActivityManagerService.this,
994                                    mContext, app);
995                            app.waitDialog = d;
996                            app.waitedForDebugger = true;
997                            d.show();
998                        }
999                    } else {
1000                        if (app.waitDialog != null) {
1001                            app.waitDialog.dismiss();
1002                            app.waitDialog = null;
1003                        }
1004                    }
1005                }
1006            } break;
1007            case SERVICE_TIMEOUT_MSG: {
1008                if (mDidDexOpt) {
1009                    mDidDexOpt = false;
1010                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1011                    nmsg.obj = msg.obj;
1012                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1013                    return;
1014                }
1015                serviceTimeout((ProcessRecord)msg.obj);
1016            } break;
1017            case UPDATE_TIME_ZONE: {
1018                synchronized (ActivityManagerService.this) {
1019                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1020                        ProcessRecord r = mLruProcesses.get(i);
1021                        if (r.thread != null) {
1022                            try {
1023                                r.thread.updateTimeZone();
1024                            } catch (RemoteException ex) {
1025                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1026                            }
1027                        }
1028                    }
1029                }
1030            } break;
1031            case CLEAR_DNS_CACHE: {
1032                synchronized (ActivityManagerService.this) {
1033                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1034                        ProcessRecord r = mLruProcesses.get(i);
1035                        if (r.thread != null) {
1036                            try {
1037                                r.thread.clearDnsCache();
1038                            } catch (RemoteException ex) {
1039                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1040                            }
1041                        }
1042                    }
1043                }
1044            } break;
1045            case UPDATE_HTTP_PROXY: {
1046                ProxyProperties proxy = (ProxyProperties)msg.obj;
1047                String host = "";
1048                String port = "";
1049                String exclList = "";
1050                if (proxy != null) {
1051                    host = proxy.getHost();
1052                    port = Integer.toString(proxy.getPort());
1053                    exclList = proxy.getExclusionList();
1054                }
1055                synchronized (ActivityManagerService.this) {
1056                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1057                        ProcessRecord r = mLruProcesses.get(i);
1058                        if (r.thread != null) {
1059                            try {
1060                                r.thread.setHttpProxy(host, port, exclList);
1061                            } catch (RemoteException ex) {
1062                                Slog.w(TAG, "Failed to update http proxy for: " +
1063                                        r.info.processName);
1064                            }
1065                        }
1066                    }
1067                }
1068            } break;
1069            case SHOW_UID_ERROR_MSG: {
1070                String title = "System UIDs Inconsistent";
1071                String text = "UIDs on the system are inconsistent, you need to wipe your"
1072                        + " data partition or your device will be unstable.";
1073                Log.e(TAG, title + ": " + text);
1074                if (mShowDialogs) {
1075                    // XXX This is a temporary dialog, no need to localize.
1076                    AlertDialog d = new BaseErrorDialog(mContext);
1077                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1078                    d.setCancelable(false);
1079                    d.setTitle(title);
1080                    d.setMessage(text);
1081                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1082                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1083                    mUidAlert = d;
1084                    d.show();
1085                }
1086            } break;
1087            case IM_FEELING_LUCKY_MSG: {
1088                if (mUidAlert != null) {
1089                    mUidAlert.dismiss();
1090                    mUidAlert = null;
1091                }
1092            } break;
1093            case PROC_START_TIMEOUT_MSG: {
1094                if (mDidDexOpt) {
1095                    mDidDexOpt = false;
1096                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1097                    nmsg.obj = msg.obj;
1098                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1099                    return;
1100                }
1101                ProcessRecord app = (ProcessRecord)msg.obj;
1102                synchronized (ActivityManagerService.this) {
1103                    processStartTimedOutLocked(app);
1104                }
1105            } break;
1106            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1107                synchronized (ActivityManagerService.this) {
1108                    doPendingActivityLaunchesLocked(true);
1109                }
1110            } break;
1111            case KILL_APPLICATION_MSG: {
1112                synchronized (ActivityManagerService.this) {
1113                    int uid = msg.arg1;
1114                    boolean restart = (msg.arg2 == 1);
1115                    String pkg = (String) msg.obj;
1116                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1117                            UserId.getUserId(uid));
1118                }
1119            } break;
1120            case FINALIZE_PENDING_INTENT_MSG: {
1121                ((PendingIntentRecord)msg.obj).completeFinalize();
1122            } break;
1123            case POST_HEAVY_NOTIFICATION_MSG: {
1124                INotificationManager inm = NotificationManager.getService();
1125                if (inm == null) {
1126                    return;
1127                }
1128
1129                ActivityRecord root = (ActivityRecord)msg.obj;
1130                ProcessRecord process = root.app;
1131                if (process == null) {
1132                    return;
1133                }
1134
1135                try {
1136                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1137                    String text = mContext.getString(R.string.heavy_weight_notification,
1138                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1139                    Notification notification = new Notification();
1140                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1141                    notification.when = 0;
1142                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1143                    notification.tickerText = text;
1144                    notification.defaults = 0; // please be quiet
1145                    notification.sound = null;
1146                    notification.vibrate = null;
1147                    notification.setLatestEventInfo(context, text,
1148                            mContext.getText(R.string.heavy_weight_notification_detail),
1149                            PendingIntent.getActivity(mContext, 0, root.intent,
1150                                    PendingIntent.FLAG_CANCEL_CURRENT));
1151
1152                    try {
1153                        int[] outId = new int[1];
1154                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1155                                notification, outId);
1156                    } catch (RuntimeException e) {
1157                        Slog.w(ActivityManagerService.TAG,
1158                                "Error showing notification for heavy-weight app", e);
1159                    } catch (RemoteException e) {
1160                    }
1161                } catch (NameNotFoundException e) {
1162                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1163                }
1164            } break;
1165            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1166                INotificationManager inm = NotificationManager.getService();
1167                if (inm == null) {
1168                    return;
1169                }
1170                try {
1171                    inm.cancelNotification("android",
1172                            R.string.heavy_weight_notification);
1173                } catch (RuntimeException e) {
1174                    Slog.w(ActivityManagerService.TAG,
1175                            "Error canceling notification for service", e);
1176                } catch (RemoteException e) {
1177                }
1178            } break;
1179            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1180                synchronized (ActivityManagerService.this) {
1181                    checkExcessivePowerUsageLocked(true);
1182                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1183                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1184                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1185                }
1186            } break;
1187            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1188                synchronized (ActivityManagerService.this) {
1189                    ActivityRecord ar = (ActivityRecord)msg.obj;
1190                    if (mCompatModeDialog != null) {
1191                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1192                                ar.info.applicationInfo.packageName)) {
1193                            return;
1194                        }
1195                        mCompatModeDialog.dismiss();
1196                        mCompatModeDialog = null;
1197                    }
1198                    if (ar != null && false) {
1199                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1200                                ar.packageName)) {
1201                            int mode = mCompatModePackages.computeCompatModeLocked(
1202                                    ar.info.applicationInfo);
1203                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1204                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1205                                mCompatModeDialog = new CompatModeDialog(
1206                                        ActivityManagerService.this, mContext,
1207                                        ar.info.applicationInfo);
1208                                mCompatModeDialog.show();
1209                            }
1210                        }
1211                    }
1212                }
1213                break;
1214            }
1215            case DISPATCH_PROCESSES_CHANGED: {
1216                dispatchProcessesChanged();
1217                break;
1218            }
1219            case DISPATCH_PROCESS_DIED: {
1220                final int pid = msg.arg1;
1221                final int uid = msg.arg2;
1222                dispatchProcessDied(pid, uid);
1223                break;
1224            }
1225            case REPORT_MEM_USAGE: {
1226                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1227                if (!isDebuggable) {
1228                    return;
1229                }
1230                synchronized (ActivityManagerService.this) {
1231                    long now = SystemClock.uptimeMillis();
1232                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1233                        // Don't report more than every 5 minutes to somewhat
1234                        // avoid spamming.
1235                        return;
1236                    }
1237                    mLastMemUsageReportTime = now;
1238                }
1239                Thread thread = new Thread() {
1240                    @Override public void run() {
1241                        StringBuilder dropBuilder = new StringBuilder(1024);
1242                        StringBuilder logBuilder = new StringBuilder(1024);
1243                        StringWriter oomSw = new StringWriter();
1244                        PrintWriter oomPw = new PrintWriter(oomSw);
1245                        StringWriter catSw = new StringWriter();
1246                        PrintWriter catPw = new PrintWriter(catSw);
1247                        String[] emptyArgs = new String[] { };
1248                        StringBuilder tag = new StringBuilder(128);
1249                        StringBuilder stack = new StringBuilder(128);
1250                        tag.append("Low on memory -- ");
1251                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1252                                tag, stack);
1253                        dropBuilder.append(stack);
1254                        dropBuilder.append('\n');
1255                        dropBuilder.append('\n');
1256                        String oomString = oomSw.toString();
1257                        dropBuilder.append(oomString);
1258                        dropBuilder.append('\n');
1259                        logBuilder.append(oomString);
1260                        try {
1261                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1262                                    "procrank", });
1263                            final InputStreamReader converter = new InputStreamReader(
1264                                    proc.getInputStream());
1265                            BufferedReader in = new BufferedReader(converter);
1266                            String line;
1267                            while (true) {
1268                                line = in.readLine();
1269                                if (line == null) {
1270                                    break;
1271                                }
1272                                if (line.length() > 0) {
1273                                    logBuilder.append(line);
1274                                    logBuilder.append('\n');
1275                                }
1276                                dropBuilder.append(line);
1277                                dropBuilder.append('\n');
1278                            }
1279                            converter.close();
1280                        } catch (IOException e) {
1281                        }
1282                        synchronized (ActivityManagerService.this) {
1283                            catPw.println();
1284                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1285                            catPw.println();
1286                            dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
1287                            catPw.println();
1288                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1289                        }
1290                        dropBuilder.append(catSw.toString());
1291                        addErrorToDropBox("lowmem", null, "system_server", null,
1292                                null, tag.toString(), dropBuilder.toString(), null, null);
1293                        Slog.i(TAG, logBuilder.toString());
1294                        synchronized (ActivityManagerService.this) {
1295                            long now = SystemClock.uptimeMillis();
1296                            if (mLastMemUsageReportTime < now) {
1297                                mLastMemUsageReportTime = now;
1298                            }
1299                        }
1300                    }
1301                };
1302                thread.start();
1303                break;
1304            }
1305            }
1306        }
1307    };
1308
1309    public static void setSystemProcess() {
1310        try {
1311            ActivityManagerService m = mSelf;
1312
1313            ServiceManager.addService("activity", m, true);
1314            ServiceManager.addService("meminfo", new MemBinder(m));
1315            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1316            ServiceManager.addService("dbinfo", new DbBinder(m));
1317            if (MONITOR_CPU_USAGE) {
1318                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1319            }
1320            ServiceManager.addService("permission", new PermissionController(m));
1321
1322            ApplicationInfo info =
1323                mSelf.mContext.getPackageManager().getApplicationInfo(
1324                            "android", STOCK_PM_FLAGS);
1325            mSystemThread.installSystemApplicationInfo(info);
1326
1327            synchronized (mSelf) {
1328                ProcessRecord app = mSelf.newProcessRecordLocked(
1329                        mSystemThread.getApplicationThread(), info,
1330                        info.processName, false);
1331                app.persistent = true;
1332                app.pid = MY_PID;
1333                app.maxAdj = ProcessList.SYSTEM_ADJ;
1334                mSelf.mProcessNames.put(app.processName, app.uid, app);
1335                synchronized (mSelf.mPidsSelfLocked) {
1336                    mSelf.mPidsSelfLocked.put(app.pid, app);
1337                }
1338                mSelf.updateLruProcessLocked(app, true, true);
1339            }
1340        } catch (PackageManager.NameNotFoundException e) {
1341            throw new RuntimeException(
1342                    "Unable to find android system package", e);
1343        }
1344    }
1345
1346    public void setWindowManager(WindowManagerService wm) {
1347        mWindowManager = wm;
1348    }
1349
1350    public static final Context main(int factoryTest) {
1351        AThread thr = new AThread();
1352        thr.start();
1353
1354        synchronized (thr) {
1355            while (thr.mService == null) {
1356                try {
1357                    thr.wait();
1358                } catch (InterruptedException e) {
1359                }
1360            }
1361        }
1362
1363        ActivityManagerService m = thr.mService;
1364        mSelf = m;
1365        ActivityThread at = ActivityThread.systemMain();
1366        mSystemThread = at;
1367        Context context = at.getSystemContext();
1368        context.setTheme(android.R.style.Theme_Holo);
1369        m.mContext = context;
1370        m.mFactoryTest = factoryTest;
1371        m.mMainStack = new ActivityStack(m, context, true);
1372
1373        m.mBatteryStatsService.publish(context);
1374        m.mUsageStatsService.publish(context);
1375
1376        synchronized (thr) {
1377            thr.mReady = true;
1378            thr.notifyAll();
1379        }
1380
1381        m.startRunning(null, null, null, null);
1382
1383        return context;
1384    }
1385
1386    public static ActivityManagerService self() {
1387        return mSelf;
1388    }
1389
1390    static class AThread extends Thread {
1391        ActivityManagerService mService;
1392        boolean mReady = false;
1393
1394        public AThread() {
1395            super("ActivityManager");
1396        }
1397
1398        public void run() {
1399            Looper.prepare();
1400
1401            android.os.Process.setThreadPriority(
1402                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1403            android.os.Process.setCanSelfBackground(false);
1404
1405            ActivityManagerService m = new ActivityManagerService();
1406
1407            synchronized (this) {
1408                mService = m;
1409                notifyAll();
1410            }
1411
1412            synchronized (this) {
1413                while (!mReady) {
1414                    try {
1415                        wait();
1416                    } catch (InterruptedException e) {
1417                    }
1418                }
1419            }
1420
1421            // For debug builds, log event loop stalls to dropbox for analysis.
1422            if (StrictMode.conditionallyEnableDebugLogging()) {
1423                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1424            }
1425
1426            Looper.loop();
1427        }
1428    }
1429
1430    static class MemBinder extends Binder {
1431        ActivityManagerService mActivityManagerService;
1432        MemBinder(ActivityManagerService activityManagerService) {
1433            mActivityManagerService = activityManagerService;
1434        }
1435
1436        @Override
1437        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1438            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1439                    != PackageManager.PERMISSION_GRANTED) {
1440                pw.println("Permission Denial: can't dump meminfo from from pid="
1441                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1442                        + " without permission " + android.Manifest.permission.DUMP);
1443                return;
1444            }
1445
1446            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1447                    false, null, null, null);
1448        }
1449    }
1450
1451    static class GraphicsBinder extends Binder {
1452        ActivityManagerService mActivityManagerService;
1453        GraphicsBinder(ActivityManagerService activityManagerService) {
1454            mActivityManagerService = activityManagerService;
1455        }
1456
1457        @Override
1458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1459            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1460                    != PackageManager.PERMISSION_GRANTED) {
1461                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1462                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1463                        + " without permission " + android.Manifest.permission.DUMP);
1464                return;
1465            }
1466
1467            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1468        }
1469    }
1470
1471    static class DbBinder extends Binder {
1472        ActivityManagerService mActivityManagerService;
1473        DbBinder(ActivityManagerService activityManagerService) {
1474            mActivityManagerService = activityManagerService;
1475        }
1476
1477        @Override
1478        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1479            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1480                    != PackageManager.PERMISSION_GRANTED) {
1481                pw.println("Permission Denial: can't dump dbinfo from from pid="
1482                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1483                        + " without permission " + android.Manifest.permission.DUMP);
1484                return;
1485            }
1486
1487            mActivityManagerService.dumpDbInfo(fd, pw, args);
1488        }
1489    }
1490
1491    static class CpuBinder extends Binder {
1492        ActivityManagerService mActivityManagerService;
1493        CpuBinder(ActivityManagerService activityManagerService) {
1494            mActivityManagerService = activityManagerService;
1495        }
1496
1497        @Override
1498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1500                    != PackageManager.PERMISSION_GRANTED) {
1501                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1503                        + " without permission " + android.Manifest.permission.DUMP);
1504                return;
1505            }
1506
1507            synchronized (mActivityManagerService.mProcessStatsThread) {
1508                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1509                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1510                        SystemClock.uptimeMillis()));
1511            }
1512        }
1513    }
1514
1515    private ActivityManagerService() {
1516        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1517
1518        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1519        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1520        mBroadcastQueues[0] = mFgBroadcastQueue;
1521        mBroadcastQueues[1] = mBgBroadcastQueue;
1522
1523        File dataDir = Environment.getDataDirectory();
1524        File systemDir = new File(dataDir, "system");
1525        systemDir.mkdirs();
1526        mBatteryStatsService = new BatteryStatsService(new File(
1527                systemDir, "batterystats.bin").toString());
1528        mBatteryStatsService.getActiveStatistics().readLocked();
1529        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1530        mOnBattery = DEBUG_POWER ? true
1531                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1532        mBatteryStatsService.getActiveStatistics().setCallback(this);
1533
1534        mUsageStatsService = new UsageStatsService(new File(
1535                systemDir, "usagestats").toString());
1536        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1537
1538        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1539            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1540
1541        mConfiguration.setToDefaults();
1542        mConfiguration.locale = Locale.getDefault();
1543        mConfigurationSeq = mConfiguration.seq = 1;
1544        mProcessStats.init();
1545
1546        mCompatModePackages = new CompatModePackages(this, systemDir);
1547
1548        // Add ourself to the Watchdog monitors.
1549        Watchdog.getInstance().addMonitor(this);
1550
1551        mProcessStatsThread = new Thread("ProcessStats") {
1552            public void run() {
1553                while (true) {
1554                    try {
1555                        try {
1556                            synchronized(this) {
1557                                final long now = SystemClock.uptimeMillis();
1558                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1559                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1560                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1561                                //        + ", write delay=" + nextWriteDelay);
1562                                if (nextWriteDelay < nextCpuDelay) {
1563                                    nextCpuDelay = nextWriteDelay;
1564                                }
1565                                if (nextCpuDelay > 0) {
1566                                    mProcessStatsMutexFree.set(true);
1567                                    this.wait(nextCpuDelay);
1568                                }
1569                            }
1570                        } catch (InterruptedException e) {
1571                        }
1572                        updateCpuStatsNow();
1573                    } catch (Exception e) {
1574                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1575                    }
1576                }
1577            }
1578        };
1579        mProcessStatsThread.start();
1580    }
1581
1582    @Override
1583    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1584            throws RemoteException {
1585        if (code == SYSPROPS_TRANSACTION) {
1586            // We need to tell all apps about the system property change.
1587            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1588            synchronized(this) {
1589                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1590                    final int NA = apps.size();
1591                    for (int ia=0; ia<NA; ia++) {
1592                        ProcessRecord app = apps.valueAt(ia);
1593                        if (app.thread != null) {
1594                            procs.add(app.thread.asBinder());
1595                        }
1596                    }
1597                }
1598            }
1599
1600            int N = procs.size();
1601            for (int i=0; i<N; i++) {
1602                Parcel data2 = Parcel.obtain();
1603                try {
1604                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1605                } catch (RemoteException e) {
1606                }
1607                data2.recycle();
1608            }
1609        }
1610        try {
1611            return super.onTransact(code, data, reply, flags);
1612        } catch (RuntimeException e) {
1613            // The activity manager only throws security exceptions, so let's
1614            // log all others.
1615            if (!(e instanceof SecurityException)) {
1616                Slog.e(TAG, "Activity Manager Crash", e);
1617            }
1618            throw e;
1619        }
1620    }
1621
1622    void updateCpuStats() {
1623        final long now = SystemClock.uptimeMillis();
1624        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1625            return;
1626        }
1627        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1628            synchronized (mProcessStatsThread) {
1629                mProcessStatsThread.notify();
1630            }
1631        }
1632    }
1633
1634    void updateCpuStatsNow() {
1635        synchronized (mProcessStatsThread) {
1636            mProcessStatsMutexFree.set(false);
1637            final long now = SystemClock.uptimeMillis();
1638            boolean haveNewCpuStats = false;
1639
1640            if (MONITOR_CPU_USAGE &&
1641                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1642                mLastCpuTime.set(now);
1643                haveNewCpuStats = true;
1644                mProcessStats.update();
1645                //Slog.i(TAG, mProcessStats.printCurrentState());
1646                //Slog.i(TAG, "Total CPU usage: "
1647                //        + mProcessStats.getTotalCpuPercent() + "%");
1648
1649                // Slog the cpu usage if the property is set.
1650                if ("true".equals(SystemProperties.get("events.cpu"))) {
1651                    int user = mProcessStats.getLastUserTime();
1652                    int system = mProcessStats.getLastSystemTime();
1653                    int iowait = mProcessStats.getLastIoWaitTime();
1654                    int irq = mProcessStats.getLastIrqTime();
1655                    int softIrq = mProcessStats.getLastSoftIrqTime();
1656                    int idle = mProcessStats.getLastIdleTime();
1657
1658                    int total = user + system + iowait + irq + softIrq + idle;
1659                    if (total == 0) total = 1;
1660
1661                    EventLog.writeEvent(EventLogTags.CPU,
1662                            ((user+system+iowait+irq+softIrq) * 100) / total,
1663                            (user * 100) / total,
1664                            (system * 100) / total,
1665                            (iowait * 100) / total,
1666                            (irq * 100) / total,
1667                            (softIrq * 100) / total);
1668                }
1669            }
1670
1671            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1672            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1673            synchronized(bstats) {
1674                synchronized(mPidsSelfLocked) {
1675                    if (haveNewCpuStats) {
1676                        if (mOnBattery) {
1677                            int perc = bstats.startAddingCpuLocked();
1678                            int totalUTime = 0;
1679                            int totalSTime = 0;
1680                            final int N = mProcessStats.countStats();
1681                            for (int i=0; i<N; i++) {
1682                                ProcessStats.Stats st = mProcessStats.getStats(i);
1683                                if (!st.working) {
1684                                    continue;
1685                                }
1686                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1687                                int otherUTime = (st.rel_utime*perc)/100;
1688                                int otherSTime = (st.rel_stime*perc)/100;
1689                                totalUTime += otherUTime;
1690                                totalSTime += otherSTime;
1691                                if (pr != null) {
1692                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1693                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1694                                            st.rel_stime-otherSTime);
1695                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1696                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1697                                } else {
1698                                    BatteryStatsImpl.Uid.Proc ps =
1699                                            bstats.getProcessStatsLocked(st.name, st.pid);
1700                                    if (ps != null) {
1701                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1702                                                st.rel_stime-otherSTime);
1703                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1704                                    }
1705                                }
1706                            }
1707                            bstats.finishAddingCpuLocked(perc, totalUTime,
1708                                    totalSTime, cpuSpeedTimes);
1709                        }
1710                    }
1711                }
1712
1713                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1714                    mLastWriteTime = now;
1715                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1716                }
1717            }
1718        }
1719    }
1720
1721    @Override
1722    public void batteryNeedsCpuUpdate() {
1723        updateCpuStatsNow();
1724    }
1725
1726    @Override
1727    public void batteryPowerChanged(boolean onBattery) {
1728        // When plugging in, update the CPU stats first before changing
1729        // the plug state.
1730        updateCpuStatsNow();
1731        synchronized (this) {
1732            synchronized(mPidsSelfLocked) {
1733                mOnBattery = DEBUG_POWER ? true : onBattery;
1734            }
1735        }
1736    }
1737
1738    /**
1739     * Initialize the application bind args. These are passed to each
1740     * process when the bindApplication() IPC is sent to the process. They're
1741     * lazily setup to make sure the services are running when they're asked for.
1742     */
1743    private HashMap<String, IBinder> getCommonServicesLocked() {
1744        if (mAppBindArgs == null) {
1745            mAppBindArgs = new HashMap<String, IBinder>();
1746
1747            // Setup the application init args
1748            mAppBindArgs.put("package", ServiceManager.getService("package"));
1749            mAppBindArgs.put("window", ServiceManager.getService("window"));
1750            mAppBindArgs.put(Context.ALARM_SERVICE,
1751                    ServiceManager.getService(Context.ALARM_SERVICE));
1752        }
1753        return mAppBindArgs;
1754    }
1755
1756    final void setFocusedActivityLocked(ActivityRecord r) {
1757        if (mFocusedActivity != r) {
1758            mFocusedActivity = r;
1759            if (r != null) {
1760                mWindowManager.setFocusedApp(r.appToken, true);
1761            }
1762        }
1763    }
1764
1765    private final void updateLruProcessInternalLocked(ProcessRecord app,
1766            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1767        // put it on the LRU to keep track of when it should be exited.
1768        int lrui = mLruProcesses.indexOf(app);
1769        if (lrui >= 0) mLruProcesses.remove(lrui);
1770
1771        int i = mLruProcesses.size()-1;
1772        int skipTop = 0;
1773
1774        app.lruSeq = mLruSeq;
1775
1776        // compute the new weight for this process.
1777        if (updateActivityTime) {
1778            app.lastActivityTime = SystemClock.uptimeMillis();
1779        }
1780        if (app.activities.size() > 0) {
1781            // If this process has activities, we more strongly want to keep
1782            // it around.
1783            app.lruWeight = app.lastActivityTime;
1784        } else if (app.pubProviders.size() > 0) {
1785            // If this process contains content providers, we want to keep
1786            // it a little more strongly.
1787            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1788            // Also don't let it kick out the first few "real" hidden processes.
1789            skipTop = ProcessList.MIN_HIDDEN_APPS;
1790        } else {
1791            // If this process doesn't have activities, we less strongly
1792            // want to keep it around, and generally want to avoid getting
1793            // in front of any very recently used activities.
1794            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1795            // Also don't let it kick out the first few "real" hidden processes.
1796            skipTop = ProcessList.MIN_HIDDEN_APPS;
1797        }
1798
1799        while (i >= 0) {
1800            ProcessRecord p = mLruProcesses.get(i);
1801            // If this app shouldn't be in front of the first N background
1802            // apps, then skip over that many that are currently hidden.
1803            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1804                skipTop--;
1805            }
1806            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1807                mLruProcesses.add(i+1, app);
1808                break;
1809            }
1810            i--;
1811        }
1812        if (i < 0) {
1813            mLruProcesses.add(0, app);
1814        }
1815
1816        // If the app is currently using a content provider or service,
1817        // bump those processes as well.
1818        if (app.connections.size() > 0) {
1819            for (ConnectionRecord cr : app.connections) {
1820                if (cr.binding != null && cr.binding.service != null
1821                        && cr.binding.service.app != null
1822                        && cr.binding.service.app.lruSeq != mLruSeq) {
1823                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1824                            updateActivityTime, i+1);
1825                }
1826            }
1827        }
1828        for (int j=app.conProviders.size()-1; j>=0; j--) {
1829            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1830            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1831                updateLruProcessInternalLocked(cpr.proc, false,
1832                        updateActivityTime, i+1);
1833            }
1834        }
1835
1836        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1837        if (oomAdj) {
1838            updateOomAdjLocked();
1839        }
1840    }
1841
1842    final void updateLruProcessLocked(ProcessRecord app,
1843            boolean oomAdj, boolean updateActivityTime) {
1844        mLruSeq++;
1845        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1846    }
1847
1848    final ProcessRecord getProcessRecordLocked(
1849            String processName, int uid) {
1850        if (uid == Process.SYSTEM_UID) {
1851            // The system gets to run in any process.  If there are multiple
1852            // processes with the same uid, just pick the first (this
1853            // should never happen).
1854            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1855                    processName);
1856            if (procs == null) return null;
1857            final int N = procs.size();
1858            for (int i = 0; i < N; i++) {
1859                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1860            }
1861        }
1862        ProcessRecord proc = mProcessNames.get(processName, uid);
1863        return proc;
1864    }
1865
1866    void ensurePackageDexOpt(String packageName) {
1867        IPackageManager pm = AppGlobals.getPackageManager();
1868        try {
1869            if (pm.performDexOpt(packageName)) {
1870                mDidDexOpt = true;
1871            }
1872        } catch (RemoteException e) {
1873        }
1874    }
1875
1876    boolean isNextTransitionForward() {
1877        int transit = mWindowManager.getPendingAppTransition();
1878        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1879                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1880                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1881    }
1882
1883    final ProcessRecord startProcessLocked(String processName,
1884            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1885            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1886            boolean isolated) {
1887        ProcessRecord app;
1888        if (!isolated) {
1889            app = getProcessRecordLocked(processName, info.uid);
1890        } else {
1891            // If this is an isolated process, it can't re-use an existing process.
1892            app = null;
1893        }
1894        // We don't have to do anything more if:
1895        // (1) There is an existing application record; and
1896        // (2) The caller doesn't think it is dead, OR there is no thread
1897        //     object attached to it so we know it couldn't have crashed; and
1898        // (3) There is a pid assigned to it, so it is either starting or
1899        //     already running.
1900        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1901                + " app=" + app + " knownToBeDead=" + knownToBeDead
1902                + " thread=" + (app != null ? app.thread : null)
1903                + " pid=" + (app != null ? app.pid : -1));
1904        if (app != null && app.pid > 0) {
1905            if (!knownToBeDead || app.thread == null) {
1906                // We already have the app running, or are waiting for it to
1907                // come up (we have a pid but not yet its thread), so keep it.
1908                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1909                // If this is a new package in the process, add the package to the list
1910                app.addPackage(info.packageName);
1911                return app;
1912            } else {
1913                // An application record is attached to a previous process,
1914                // clean it up now.
1915                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1916                handleAppDiedLocked(app, true, true);
1917            }
1918        }
1919
1920        String hostingNameStr = hostingName != null
1921                ? hostingName.flattenToShortString() : null;
1922
1923        if (!isolated) {
1924            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1925                // If we are in the background, then check to see if this process
1926                // is bad.  If so, we will just silently fail.
1927                if (mBadProcesses.get(info.processName, info.uid) != null) {
1928                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1929                            + "/" + info.processName);
1930                    return null;
1931                }
1932            } else {
1933                // When the user is explicitly starting a process, then clear its
1934                // crash count so that we won't make it bad until they see at
1935                // least one crash dialog again, and make the process good again
1936                // if it had been bad.
1937                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1938                        + "/" + info.processName);
1939                mProcessCrashTimes.remove(info.processName, info.uid);
1940                if (mBadProcesses.get(info.processName, info.uid) != null) {
1941                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1942                            info.processName);
1943                    mBadProcesses.remove(info.processName, info.uid);
1944                    if (app != null) {
1945                        app.bad = false;
1946                    }
1947                }
1948            }
1949        }
1950
1951        if (app == null) {
1952            app = newProcessRecordLocked(null, info, processName, isolated);
1953            if (app == null) {
1954                Slog.w(TAG, "Failed making new process record for "
1955                        + processName + "/" + info.uid + " isolated=" + isolated);
1956                return null;
1957            }
1958            mProcessNames.put(processName, app.uid, app);
1959            if (isolated) {
1960                mIsolatedProcesses.put(app.uid, app);
1961            }
1962        } else {
1963            // If this is a new package in the process, add the package to the list
1964            app.addPackage(info.packageName);
1965        }
1966
1967        // If the system is not ready yet, then hold off on starting this
1968        // process until it is.
1969        if (!mProcessesReady
1970                && !isAllowedWhileBooting(info)
1971                && !allowWhileBooting) {
1972            if (!mProcessesOnHold.contains(app)) {
1973                mProcessesOnHold.add(app);
1974            }
1975            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1976            return app;
1977        }
1978
1979        startProcessLocked(app, hostingType, hostingNameStr);
1980        return (app.pid != 0) ? app : null;
1981    }
1982
1983    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1984        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1985    }
1986
1987    private final void startProcessLocked(ProcessRecord app,
1988            String hostingType, String hostingNameStr) {
1989        if (app.pid > 0 && app.pid != MY_PID) {
1990            synchronized (mPidsSelfLocked) {
1991                mPidsSelfLocked.remove(app.pid);
1992                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1993            }
1994            app.pid = 0;
1995        }
1996
1997        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1998                "startProcessLocked removing on hold: " + app);
1999        mProcessesOnHold.remove(app);
2000
2001        updateCpuStats();
2002
2003        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2004        mProcDeaths[0] = 0;
2005
2006        try {
2007            int uid = app.uid;
2008
2009            int[] gids = null;
2010            if (!app.isolated) {
2011                try {
2012                    gids = mContext.getPackageManager().getPackageGids(
2013                            app.info.packageName);
2014                } catch (PackageManager.NameNotFoundException e) {
2015                    Slog.w(TAG, "Unable to retrieve gids", e);
2016                }
2017            }
2018            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2019                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2020                        && mTopComponent != null
2021                        && app.processName.equals(mTopComponent.getPackageName())) {
2022                    uid = 0;
2023                }
2024                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2025                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2026                    uid = 0;
2027                }
2028            }
2029            int debugFlags = 0;
2030            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2031                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2032                // Also turn on CheckJNI for debuggable apps. It's quite
2033                // awkward to turn on otherwise.
2034                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2035            }
2036            // Run the app in safe mode if its manifest requests so or the
2037            // system is booted in safe mode.
2038            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2039                Zygote.systemInSafeMode == true) {
2040                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2041            }
2042            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2043                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2044            }
2045            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2046                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2047            }
2048            if ("1".equals(SystemProperties.get("debug.assert"))) {
2049                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2050            }
2051
2052            // Start the process.  It will either succeed and return a result containing
2053            // the PID of the new process, or else throw a RuntimeException.
2054            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2055                    app.processName, uid, uid, gids, debugFlags,
2056                    app.info.targetSdkVersion, null, null);
2057
2058            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2059            synchronized (bs) {
2060                if (bs.isOnBattery()) {
2061                    app.batteryStats.incStartsLocked();
2062                }
2063            }
2064
2065            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2066                    app.processName, hostingType,
2067                    hostingNameStr != null ? hostingNameStr : "");
2068
2069            if (app.persistent) {
2070                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2071            }
2072
2073            StringBuilder buf = mStringBuilder;
2074            buf.setLength(0);
2075            buf.append("Start proc ");
2076            buf.append(app.processName);
2077            buf.append(" for ");
2078            buf.append(hostingType);
2079            if (hostingNameStr != null) {
2080                buf.append(" ");
2081                buf.append(hostingNameStr);
2082            }
2083            buf.append(": pid=");
2084            buf.append(startResult.pid);
2085            buf.append(" uid=");
2086            buf.append(uid);
2087            buf.append(" gids={");
2088            if (gids != null) {
2089                for (int gi=0; gi<gids.length; gi++) {
2090                    if (gi != 0) buf.append(", ");
2091                    buf.append(gids[gi]);
2092
2093                }
2094            }
2095            buf.append("}");
2096            Slog.i(TAG, buf.toString());
2097            app.pid = startResult.pid;
2098            app.usingWrapper = startResult.usingWrapper;
2099            app.removed = false;
2100            synchronized (mPidsSelfLocked) {
2101                this.mPidsSelfLocked.put(startResult.pid, app);
2102                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2103                msg.obj = app;
2104                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2105                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2106            }
2107        } catch (RuntimeException e) {
2108            // XXX do better error recovery.
2109            app.pid = 0;
2110            Slog.e(TAG, "Failure starting process " + app.processName, e);
2111        }
2112    }
2113
2114    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2115        if (resumed) {
2116            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2117        } else {
2118            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2119        }
2120    }
2121
2122    boolean startHomeActivityLocked(int userId) {
2123        if (mHeadless) {
2124            // Added because none of the other calls to ensureBootCompleted seem to fire
2125            // when running headless.
2126            ensureBootCompleted();
2127            return false;
2128        }
2129
2130        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2131                && mTopAction == null) {
2132            // We are running in factory test mode, but unable to find
2133            // the factory test app, so just sit around displaying the
2134            // error message and don't try to start anything.
2135            return false;
2136        }
2137        Intent intent = new Intent(
2138            mTopAction,
2139            mTopData != null ? Uri.parse(mTopData) : null);
2140        intent.setComponent(mTopComponent);
2141        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2142            intent.addCategory(Intent.CATEGORY_HOME);
2143        }
2144        ActivityInfo aInfo =
2145            intent.resolveActivityInfo(mContext.getPackageManager(),
2146                    STOCK_PM_FLAGS);
2147        if (aInfo != null) {
2148            intent.setComponent(new ComponentName(
2149                    aInfo.applicationInfo.packageName, aInfo.name));
2150            // Don't do this if the home app is currently being
2151            // instrumented.
2152            aInfo = new ActivityInfo(aInfo);
2153            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2154            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2155                    aInfo.applicationInfo.uid);
2156            if (app == null || app.instrumentationClass == null) {
2157                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2158                mMainStack.startActivityLocked(null, intent, null, aInfo,
2159                        null, null, 0, 0, 0, 0, null, false, null);
2160            }
2161        }
2162
2163        return true;
2164    }
2165
2166    /**
2167     * Starts the "new version setup screen" if appropriate.
2168     */
2169    void startSetupActivityLocked() {
2170        // Only do this once per boot.
2171        if (mCheckedForSetup) {
2172            return;
2173        }
2174
2175        // We will show this screen if the current one is a different
2176        // version than the last one shown, and we are not running in
2177        // low-level factory test mode.
2178        final ContentResolver resolver = mContext.getContentResolver();
2179        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2180                Settings.Secure.getInt(resolver,
2181                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2182            mCheckedForSetup = true;
2183
2184            // See if we should be showing the platform update setup UI.
2185            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2186            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2187                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2188
2189            // We don't allow third party apps to replace this.
2190            ResolveInfo ri = null;
2191            for (int i=0; ris != null && i<ris.size(); i++) {
2192                if ((ris.get(i).activityInfo.applicationInfo.flags
2193                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2194                    ri = ris.get(i);
2195                    break;
2196                }
2197            }
2198
2199            if (ri != null) {
2200                String vers = ri.activityInfo.metaData != null
2201                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2202                        : null;
2203                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2204                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2205                            Intent.METADATA_SETUP_VERSION);
2206                }
2207                String lastVers = Settings.Secure.getString(
2208                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2209                if (vers != null && !vers.equals(lastVers)) {
2210                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2211                    intent.setComponent(new ComponentName(
2212                            ri.activityInfo.packageName, ri.activityInfo.name));
2213                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2214                            null, null, 0, 0, 0, 0, null, false, null);
2215                }
2216            }
2217        }
2218    }
2219
2220    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2221        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2222    }
2223
2224    void enforceNotIsolatedCaller(String caller) {
2225        if (UserId.isIsolated(Binder.getCallingUid())) {
2226            throw new SecurityException("Isolated process not allowed to call " + caller);
2227        }
2228    }
2229
2230    public int getFrontActivityScreenCompatMode() {
2231        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2232        synchronized (this) {
2233            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2234        }
2235    }
2236
2237    public void setFrontActivityScreenCompatMode(int mode) {
2238        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2239                "setFrontActivityScreenCompatMode");
2240        synchronized (this) {
2241            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2242        }
2243    }
2244
2245    public int getPackageScreenCompatMode(String packageName) {
2246        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2247        synchronized (this) {
2248            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2249        }
2250    }
2251
2252    public void setPackageScreenCompatMode(String packageName, int mode) {
2253        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2254                "setPackageScreenCompatMode");
2255        synchronized (this) {
2256            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2257        }
2258    }
2259
2260    public boolean getPackageAskScreenCompat(String packageName) {
2261        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2262        synchronized (this) {
2263            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2264        }
2265    }
2266
2267    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2268        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2269                "setPackageAskScreenCompat");
2270        synchronized (this) {
2271            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2272        }
2273    }
2274
2275    void reportResumedActivityLocked(ActivityRecord r) {
2276        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2277        updateUsageStats(r, true);
2278    }
2279
2280    private void dispatchProcessesChanged() {
2281        int N;
2282        synchronized (this) {
2283            N = mPendingProcessChanges.size();
2284            if (mActiveProcessChanges.length < N) {
2285                mActiveProcessChanges = new ProcessChangeItem[N];
2286            }
2287            mPendingProcessChanges.toArray(mActiveProcessChanges);
2288            mAvailProcessChanges.addAll(mPendingProcessChanges);
2289            mPendingProcessChanges.clear();
2290            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2291        }
2292        int i = mProcessObservers.beginBroadcast();
2293        while (i > 0) {
2294            i--;
2295            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2296            if (observer != null) {
2297                try {
2298                    for (int j=0; j<N; j++) {
2299                        ProcessChangeItem item = mActiveProcessChanges[j];
2300                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2301                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2302                                    + item.pid + " uid=" + item.uid + ": "
2303                                    + item.foregroundActivities);
2304                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2305                                    item.foregroundActivities);
2306                        }
2307                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2308                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2309                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2310                            observer.onImportanceChanged(item.pid, item.uid,
2311                                    item.importance);
2312                        }
2313                    }
2314                } catch (RemoteException e) {
2315                }
2316            }
2317        }
2318        mProcessObservers.finishBroadcast();
2319    }
2320
2321    private void dispatchProcessDied(int pid, int uid) {
2322        int i = mProcessObservers.beginBroadcast();
2323        while (i > 0) {
2324            i--;
2325            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2326            if (observer != null) {
2327                try {
2328                    observer.onProcessDied(pid, uid);
2329                } catch (RemoteException e) {
2330                }
2331            }
2332        }
2333        mProcessObservers.finishBroadcast();
2334    }
2335
2336    final void doPendingActivityLaunchesLocked(boolean doResume) {
2337        final int N = mPendingActivityLaunches.size();
2338        if (N <= 0) {
2339            return;
2340        }
2341        for (int i=0; i<N; i++) {
2342            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2343            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2344                    pal.startFlags, doResume && i == (N-1), null);
2345        }
2346        mPendingActivityLaunches.clear();
2347    }
2348
2349    public final int startActivity(IApplicationThread caller,
2350            Intent intent, String resolvedType, IBinder resultTo,
2351            String resultWho, int requestCode, int startFlags,
2352            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2353        enforceNotIsolatedCaller("startActivity");
2354        int userId = 0;
2355        if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2356            // Requesting home, set the identity to the current user
2357            // HACK!
2358            userId = mCurrentUserId;
2359        } else {
2360            // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2361            // the current user's userId
2362            if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2363                userId = 0;
2364            } else {
2365                userId = Binder.getOrigCallingUser();
2366            }
2367        }
2368        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2369                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2370                null, null, options, userId);
2371    }
2372
2373    public final WaitResult startActivityAndWait(IApplicationThread caller,
2374            Intent intent, String resolvedType, IBinder resultTo,
2375            String resultWho, int requestCode, int startFlags, String profileFile,
2376            ParcelFileDescriptor profileFd, Bundle options) {
2377        enforceNotIsolatedCaller("startActivityAndWait");
2378        WaitResult res = new WaitResult();
2379        int userId = Binder.getOrigCallingUser();
2380        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2381                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2382                res, null, options, userId);
2383        return res;
2384    }
2385
2386    public final int startActivityWithConfig(IApplicationThread caller,
2387            Intent intent, String resolvedType, IBinder resultTo,
2388            String resultWho, int requestCode, int startFlags, Configuration config,
2389            Bundle options) {
2390        enforceNotIsolatedCaller("startActivityWithConfig");
2391        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2392                resultTo, resultWho, requestCode, startFlags,
2393                null, null, null, config, options, Binder.getOrigCallingUser());
2394        return ret;
2395    }
2396
2397    public int startActivityIntentSender(IApplicationThread caller,
2398            IntentSender intent, Intent fillInIntent, String resolvedType,
2399            IBinder resultTo, String resultWho, int requestCode,
2400            int flagsMask, int flagsValues, Bundle options) {
2401        enforceNotIsolatedCaller("startActivityIntentSender");
2402        // Refuse possible leaked file descriptors
2403        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2404            throw new IllegalArgumentException("File descriptors passed in Intent");
2405        }
2406
2407        IIntentSender sender = intent.getTarget();
2408        if (!(sender instanceof PendingIntentRecord)) {
2409            throw new IllegalArgumentException("Bad PendingIntent object");
2410        }
2411
2412        PendingIntentRecord pir = (PendingIntentRecord)sender;
2413
2414        synchronized (this) {
2415            // If this is coming from the currently resumed activity, it is
2416            // effectively saying that app switches are allowed at this point.
2417            if (mMainStack.mResumedActivity != null
2418                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2419                            Binder.getCallingUid()) {
2420                mAppSwitchesAllowedTime = 0;
2421            }
2422        }
2423        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2424                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2425        return ret;
2426    }
2427
2428    public boolean startNextMatchingActivity(IBinder callingActivity,
2429            Intent intent, Bundle options) {
2430        // Refuse possible leaked file descriptors
2431        if (intent != null && intent.hasFileDescriptors() == true) {
2432            throw new IllegalArgumentException("File descriptors passed in Intent");
2433        }
2434
2435        synchronized (this) {
2436            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2437            if (r == null) {
2438                ActivityOptions.abort(options);
2439                return false;
2440            }
2441            if (r.app == null || r.app.thread == null) {
2442                // The caller is not running...  d'oh!
2443                ActivityOptions.abort(options);
2444                return false;
2445            }
2446            intent = new Intent(intent);
2447            // The caller is not allowed to change the data.
2448            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2449            // And we are resetting to find the next component...
2450            intent.setComponent(null);
2451
2452            ActivityInfo aInfo = null;
2453            try {
2454                List<ResolveInfo> resolves =
2455                    AppGlobals.getPackageManager().queryIntentActivities(
2456                            intent, r.resolvedType,
2457                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2458                            UserId.getCallingUserId());
2459
2460                // Look for the original activity in the list...
2461                final int N = resolves != null ? resolves.size() : 0;
2462                for (int i=0; i<N; i++) {
2463                    ResolveInfo rInfo = resolves.get(i);
2464                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2465                            && rInfo.activityInfo.name.equals(r.info.name)) {
2466                        // We found the current one...  the next matching is
2467                        // after it.
2468                        i++;
2469                        if (i<N) {
2470                            aInfo = resolves.get(i).activityInfo;
2471                        }
2472                        break;
2473                    }
2474                }
2475            } catch (RemoteException e) {
2476            }
2477
2478            if (aInfo == null) {
2479                // Nobody who is next!
2480                ActivityOptions.abort(options);
2481                return false;
2482            }
2483
2484            intent.setComponent(new ComponentName(
2485                    aInfo.applicationInfo.packageName, aInfo.name));
2486            intent.setFlags(intent.getFlags()&~(
2487                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2488                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2489                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2490                    Intent.FLAG_ACTIVITY_NEW_TASK));
2491
2492            // Okay now we need to start the new activity, replacing the
2493            // currently running activity.  This is a little tricky because
2494            // we want to start the new one as if the current one is finished,
2495            // but not finish the current one first so that there is no flicker.
2496            // And thus...
2497            final boolean wasFinishing = r.finishing;
2498            r.finishing = true;
2499
2500            // Propagate reply information over to the new activity.
2501            final ActivityRecord resultTo = r.resultTo;
2502            final String resultWho = r.resultWho;
2503            final int requestCode = r.requestCode;
2504            r.resultTo = null;
2505            if (resultTo != null) {
2506                resultTo.removeResultsLocked(r, resultWho, requestCode);
2507            }
2508
2509            final long origId = Binder.clearCallingIdentity();
2510            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2511                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2512                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2513                    options, false, null);
2514            Binder.restoreCallingIdentity(origId);
2515
2516            r.finishing = wasFinishing;
2517            if (res != ActivityManager.START_SUCCESS) {
2518                return false;
2519            }
2520            return true;
2521        }
2522    }
2523
2524    public final int startActivityInPackage(int uid,
2525            Intent intent, String resolvedType, IBinder resultTo,
2526            String resultWho, int requestCode, int startFlags, Bundle options) {
2527
2528        // This is so super not safe, that only the system (or okay root)
2529        // can do it.
2530        int userId = Binder.getOrigCallingUser();
2531        final int callingUid = Binder.getCallingUid();
2532        if (callingUid != 0 && callingUid != Process.myUid()) {
2533            throw new SecurityException(
2534                    "startActivityInPackage only available to the system");
2535        }
2536
2537        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2538                resultTo, resultWho, requestCode, startFlags,
2539                null, null, null, null, options, userId);
2540        return ret;
2541    }
2542
2543    public final int startActivities(IApplicationThread caller,
2544            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2545        enforceNotIsolatedCaller("startActivities");
2546        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2547                options, Binder.getOrigCallingUser());
2548        return ret;
2549    }
2550
2551    public final int startActivitiesInPackage(int uid,
2552            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2553            Bundle options) {
2554
2555        // This is so super not safe, that only the system (or okay root)
2556        // can do it.
2557        final int callingUid = Binder.getCallingUid();
2558        if (callingUid != 0 && callingUid != Process.myUid()) {
2559            throw new SecurityException(
2560                    "startActivityInPackage only available to the system");
2561        }
2562        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2563                options, UserId.getUserId(uid));
2564        return ret;
2565    }
2566
2567    final void addRecentTaskLocked(TaskRecord task) {
2568        int N = mRecentTasks.size();
2569        // Quick case: check if the top-most recent task is the same.
2570        if (N > 0 && mRecentTasks.get(0) == task) {
2571            return;
2572        }
2573        // Remove any existing entries that are the same kind of task.
2574        for (int i=0; i<N; i++) {
2575            TaskRecord tr = mRecentTasks.get(i);
2576            if (task.userId == tr.userId
2577                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2578                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2579                mRecentTasks.remove(i);
2580                i--;
2581                N--;
2582                if (task.intent == null) {
2583                    // If the new recent task we are adding is not fully
2584                    // specified, then replace it with the existing recent task.
2585                    task = tr;
2586                }
2587            }
2588        }
2589        if (N >= MAX_RECENT_TASKS) {
2590            mRecentTasks.remove(N-1);
2591        }
2592        mRecentTasks.add(0, task);
2593    }
2594
2595    public void setRequestedOrientation(IBinder token,
2596            int requestedOrientation) {
2597        synchronized (this) {
2598            ActivityRecord r = mMainStack.isInStackLocked(token);
2599            if (r == null) {
2600                return;
2601            }
2602            final long origId = Binder.clearCallingIdentity();
2603            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2604            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2605                    mConfiguration,
2606                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2607            if (config != null) {
2608                r.frozenBeforeDestroy = true;
2609                if (!updateConfigurationLocked(config, r, false, false)) {
2610                    mMainStack.resumeTopActivityLocked(null);
2611                }
2612            }
2613            Binder.restoreCallingIdentity(origId);
2614        }
2615    }
2616
2617    public int getRequestedOrientation(IBinder token) {
2618        synchronized (this) {
2619            ActivityRecord r = mMainStack.isInStackLocked(token);
2620            if (r == null) {
2621                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2622            }
2623            return mWindowManager.getAppOrientation(r.appToken);
2624        }
2625    }
2626
2627    /**
2628     * This is the internal entry point for handling Activity.finish().
2629     *
2630     * @param token The Binder token referencing the Activity we want to finish.
2631     * @param resultCode Result code, if any, from this Activity.
2632     * @param resultData Result data (Intent), if any, from this Activity.
2633     *
2634     * @return Returns true if the activity successfully finished, or false if it is still running.
2635     */
2636    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2637        // Refuse possible leaked file descriptors
2638        if (resultData != null && resultData.hasFileDescriptors() == true) {
2639            throw new IllegalArgumentException("File descriptors passed in Intent");
2640        }
2641
2642        synchronized(this) {
2643            if (mController != null) {
2644                // Find the first activity that is not finishing.
2645                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2646                if (next != null) {
2647                    // ask watcher if this is allowed
2648                    boolean resumeOK = true;
2649                    try {
2650                        resumeOK = mController.activityResuming(next.packageName);
2651                    } catch (RemoteException e) {
2652                        mController = null;
2653                    }
2654
2655                    if (!resumeOK) {
2656                        return false;
2657                    }
2658                }
2659            }
2660            final long origId = Binder.clearCallingIdentity();
2661            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2662                    resultData, "app-request");
2663            Binder.restoreCallingIdentity(origId);
2664            return res;
2665        }
2666    }
2667
2668    public final void finishHeavyWeightApp() {
2669        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2670                != PackageManager.PERMISSION_GRANTED) {
2671            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2672                    + Binder.getCallingPid()
2673                    + ", uid=" + Binder.getCallingUid()
2674                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2675            Slog.w(TAG, msg);
2676            throw new SecurityException(msg);
2677        }
2678
2679        synchronized(this) {
2680            if (mHeavyWeightProcess == null) {
2681                return;
2682            }
2683
2684            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2685                    mHeavyWeightProcess.activities);
2686            for (int i=0; i<activities.size(); i++) {
2687                ActivityRecord r = activities.get(i);
2688                if (!r.finishing) {
2689                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2690                    if (index >= 0) {
2691                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2692                                null, "finish-heavy");
2693                    }
2694                }
2695            }
2696
2697            mHeavyWeightProcess = null;
2698            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2699        }
2700    }
2701
2702    public void crashApplication(int uid, int initialPid, String packageName,
2703            String message) {
2704        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2705                != PackageManager.PERMISSION_GRANTED) {
2706            String msg = "Permission Denial: crashApplication() from pid="
2707                    + Binder.getCallingPid()
2708                    + ", uid=" + Binder.getCallingUid()
2709                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2710            Slog.w(TAG, msg);
2711            throw new SecurityException(msg);
2712        }
2713
2714        synchronized(this) {
2715            ProcessRecord proc = null;
2716
2717            // Figure out which process to kill.  We don't trust that initialPid
2718            // still has any relation to current pids, so must scan through the
2719            // list.
2720            synchronized (mPidsSelfLocked) {
2721                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2722                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2723                    if (p.uid != uid) {
2724                        continue;
2725                    }
2726                    if (p.pid == initialPid) {
2727                        proc = p;
2728                        break;
2729                    }
2730                    for (String str : p.pkgList) {
2731                        if (str.equals(packageName)) {
2732                            proc = p;
2733                        }
2734                    }
2735                }
2736            }
2737
2738            if (proc == null) {
2739                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2740                        + " initialPid=" + initialPid
2741                        + " packageName=" + packageName);
2742                return;
2743            }
2744
2745            if (proc.thread != null) {
2746                if (proc.pid == Process.myPid()) {
2747                    Log.w(TAG, "crashApplication: trying to crash self!");
2748                    return;
2749                }
2750                long ident = Binder.clearCallingIdentity();
2751                try {
2752                    proc.thread.scheduleCrash(message);
2753                } catch (RemoteException e) {
2754                }
2755                Binder.restoreCallingIdentity(ident);
2756            }
2757        }
2758    }
2759
2760    public final void finishSubActivity(IBinder token, String resultWho,
2761            int requestCode) {
2762        synchronized(this) {
2763            final long origId = Binder.clearCallingIdentity();
2764            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2765            Binder.restoreCallingIdentity(origId);
2766        }
2767    }
2768
2769    public boolean finishActivityAffinity(IBinder token) {
2770        synchronized(this) {
2771            final long origId = Binder.clearCallingIdentity();
2772            boolean res = mMainStack.finishActivityAffinityLocked(token);
2773            Binder.restoreCallingIdentity(origId);
2774            return res;
2775        }
2776    }
2777
2778    public boolean willActivityBeVisible(IBinder token) {
2779        synchronized(this) {
2780            int i;
2781            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2782                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2783                if (r.appToken == token) {
2784                    return true;
2785                }
2786                if (r.fullscreen && !r.finishing) {
2787                    return false;
2788                }
2789            }
2790            return true;
2791        }
2792    }
2793
2794    public void overridePendingTransition(IBinder token, String packageName,
2795            int enterAnim, int exitAnim) {
2796        synchronized(this) {
2797            ActivityRecord self = mMainStack.isInStackLocked(token);
2798            if (self == null) {
2799                return;
2800            }
2801
2802            final long origId = Binder.clearCallingIdentity();
2803
2804            if (self.state == ActivityState.RESUMED
2805                    || self.state == ActivityState.PAUSING) {
2806                mWindowManager.overridePendingAppTransition(packageName,
2807                        enterAnim, exitAnim, null);
2808            }
2809
2810            Binder.restoreCallingIdentity(origId);
2811        }
2812    }
2813
2814    /**
2815     * Main function for removing an existing process from the activity manager
2816     * as a result of that process going away.  Clears out all connections
2817     * to the process.
2818     */
2819    private final void handleAppDiedLocked(ProcessRecord app,
2820            boolean restarting, boolean allowRestart) {
2821        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2822        if (!restarting) {
2823            mLruProcesses.remove(app);
2824        }
2825
2826        if (mProfileProc == app) {
2827            clearProfilerLocked();
2828        }
2829
2830        // Just in case...
2831        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2832            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2833            mMainStack.mPausingActivity = null;
2834        }
2835        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2836            mMainStack.mLastPausedActivity = null;
2837        }
2838
2839        // Remove this application's activities from active lists.
2840        mMainStack.removeHistoryRecordsForAppLocked(app);
2841
2842        boolean atTop = true;
2843        boolean hasVisibleActivities = false;
2844
2845        // Clean out the history list.
2846        int i = mMainStack.mHistory.size();
2847        if (localLOGV) Slog.v(
2848            TAG, "Removing app " + app + " from history with " + i + " entries");
2849        while (i > 0) {
2850            i--;
2851            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2852            if (localLOGV) Slog.v(
2853                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2854            if (r.app == app) {
2855                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2856                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2857                        RuntimeException here = new RuntimeException("here");
2858                        here.fillInStackTrace();
2859                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2860                                + ": haveState=" + r.haveState
2861                                + " stateNotNeeded=" + r.stateNotNeeded
2862                                + " finishing=" + r.finishing
2863                                + " state=" + r.state, here);
2864                    }
2865                    if (!r.finishing) {
2866                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2867                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2868                                System.identityHashCode(r),
2869                                r.task.taskId, r.shortComponentName,
2870                                "proc died without state saved");
2871                    }
2872                    mMainStack.removeActivityFromHistoryLocked(r);
2873
2874                } else {
2875                    // We have the current state for this activity, so
2876                    // it can be restarted later when needed.
2877                    if (localLOGV) Slog.v(
2878                        TAG, "Keeping entry, setting app to null");
2879                    if (r.visible) {
2880                        hasVisibleActivities = true;
2881                    }
2882                    r.app = null;
2883                    r.nowVisible = false;
2884                    if (!r.haveState) {
2885                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2886                                "App died, clearing saved state of " + r);
2887                        r.icicle = null;
2888                    }
2889                }
2890
2891                r.stack.cleanUpActivityLocked(r, true, true);
2892            }
2893            atTop = false;
2894        }
2895
2896        app.activities.clear();
2897
2898        if (app.instrumentationClass != null) {
2899            Slog.w(TAG, "Crash of app " + app.processName
2900                  + " running instrumentation " + app.instrumentationClass);
2901            Bundle info = new Bundle();
2902            info.putString("shortMsg", "Process crashed.");
2903            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2904        }
2905
2906        if (!restarting) {
2907            if (!mMainStack.resumeTopActivityLocked(null)) {
2908                // If there was nothing to resume, and we are not already
2909                // restarting this process, but there is a visible activity that
2910                // is hosted by the process...  then make sure all visible
2911                // activities are running, taking care of restarting this
2912                // process.
2913                if (hasVisibleActivities) {
2914                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2915                }
2916            }
2917        }
2918    }
2919
2920    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2921        IBinder threadBinder = thread.asBinder();
2922        // Find the application record.
2923        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2924            ProcessRecord rec = mLruProcesses.get(i);
2925            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2926                return i;
2927            }
2928        }
2929        return -1;
2930    }
2931
2932    final ProcessRecord getRecordForAppLocked(
2933            IApplicationThread thread) {
2934        if (thread == null) {
2935            return null;
2936        }
2937
2938        int appIndex = getLRURecordIndexForAppLocked(thread);
2939        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2940    }
2941
2942    final void appDiedLocked(ProcessRecord app, int pid,
2943            IApplicationThread thread) {
2944
2945        mProcDeaths[0]++;
2946
2947        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2948        synchronized (stats) {
2949            stats.noteProcessDiedLocked(app.info.uid, pid);
2950        }
2951
2952        // Clean up already done if the process has been re-started.
2953        if (app.pid == pid && app.thread != null &&
2954                app.thread.asBinder() == thread.asBinder()) {
2955            if (!app.killedBackground) {
2956                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2957                        + ") has died.");
2958            }
2959            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2960            if (localLOGV) Slog.v(
2961                TAG, "Dying app: " + app + ", pid: " + pid
2962                + ", thread: " + thread.asBinder());
2963            boolean doLowMem = app.instrumentationClass == null;
2964            handleAppDiedLocked(app, false, true);
2965
2966            if (doLowMem) {
2967                // If there are no longer any background processes running,
2968                // and the app that died was not running instrumentation,
2969                // then tell everyone we are now low on memory.
2970                boolean haveBg = false;
2971                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2972                    ProcessRecord rec = mLruProcesses.get(i);
2973                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2974                        haveBg = true;
2975                        break;
2976                    }
2977                }
2978
2979                if (!haveBg) {
2980                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2981                    long now = SystemClock.uptimeMillis();
2982                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2983                        ProcessRecord rec = mLruProcesses.get(i);
2984                        if (rec != app && rec.thread != null &&
2985                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2986                            // The low memory report is overriding any current
2987                            // state for a GC request.  Make sure to do
2988                            // heavy/important/visible/foreground processes first.
2989                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2990                                rec.lastRequestedGc = 0;
2991                            } else {
2992                                rec.lastRequestedGc = rec.lastLowMemory;
2993                            }
2994                            rec.reportLowMemory = true;
2995                            rec.lastLowMemory = now;
2996                            mProcessesToGc.remove(rec);
2997                            addProcessToGcListLocked(rec);
2998                        }
2999                    }
3000                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3001                    scheduleAppGcsLocked();
3002                }
3003            }
3004        } else if (app.pid != pid) {
3005            // A new process has already been started.
3006            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3007                    + ") has died and restarted (pid " + app.pid + ").");
3008            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3009        } else if (DEBUG_PROCESSES) {
3010            Slog.d(TAG, "Received spurious death notification for thread "
3011                    + thread.asBinder());
3012        }
3013    }
3014
3015    /**
3016     * If a stack trace dump file is configured, dump process stack traces.
3017     * @param clearTraces causes the dump file to be erased prior to the new
3018     *    traces being written, if true; when false, the new traces will be
3019     *    appended to any existing file content.
3020     * @param firstPids of dalvik VM processes to dump stack traces for first
3021     * @param lastPids of dalvik VM processes to dump stack traces for last
3022     * @param nativeProcs optional list of native process names to dump stack crawls
3023     * @return file containing stack traces, or null if no dump file is configured
3024     */
3025    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3026            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3027        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3028        if (tracesPath == null || tracesPath.length() == 0) {
3029            return null;
3030        }
3031
3032        File tracesFile = new File(tracesPath);
3033        try {
3034            File tracesDir = tracesFile.getParentFile();
3035            if (!tracesDir.exists()) tracesFile.mkdirs();
3036            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3037
3038            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3039            tracesFile.createNewFile();
3040            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3041        } catch (IOException e) {
3042            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3043            return null;
3044        }
3045
3046        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3047        return tracesFile;
3048    }
3049
3050    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3051            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3052        // Use a FileObserver to detect when traces finish writing.
3053        // The order of traces is considered important to maintain for legibility.
3054        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3055            public synchronized void onEvent(int event, String path) { notify(); }
3056        };
3057
3058        try {
3059            observer.startWatching();
3060
3061            // First collect all of the stacks of the most important pids.
3062            if (firstPids != null) {
3063                try {
3064                    int num = firstPids.size();
3065                    for (int i = 0; i < num; i++) {
3066                        synchronized (observer) {
3067                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3068                            observer.wait(200);  // Wait for write-close, give up after 200msec
3069                        }
3070                    }
3071                } catch (InterruptedException e) {
3072                    Log.wtf(TAG, e);
3073                }
3074            }
3075
3076            // Next measure CPU usage.
3077            if (processStats != null) {
3078                processStats.init();
3079                System.gc();
3080                processStats.update();
3081                try {
3082                    synchronized (processStats) {
3083                        processStats.wait(500); // measure over 1/2 second.
3084                    }
3085                } catch (InterruptedException e) {
3086                }
3087                processStats.update();
3088
3089                // We'll take the stack crawls of just the top apps using CPU.
3090                final int N = processStats.countWorkingStats();
3091                int numProcs = 0;
3092                for (int i=0; i<N && numProcs<5; i++) {
3093                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3094                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3095                        numProcs++;
3096                        try {
3097                            synchronized (observer) {
3098                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3099                                observer.wait(200);  // Wait for write-close, give up after 200msec
3100                            }
3101                        } catch (InterruptedException e) {
3102                            Log.wtf(TAG, e);
3103                        }
3104
3105                    }
3106                }
3107            }
3108
3109        } finally {
3110            observer.stopWatching();
3111        }
3112
3113        if (nativeProcs != null) {
3114            int[] pids = Process.getPidsForCommands(nativeProcs);
3115            if (pids != null) {
3116                for (int pid : pids) {
3117                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3118                }
3119            }
3120        }
3121    }
3122
3123    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3124        if (true || IS_USER_BUILD) {
3125            return;
3126        }
3127        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3128        if (tracesPath == null || tracesPath.length() == 0) {
3129            return;
3130        }
3131
3132        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3133        StrictMode.allowThreadDiskWrites();
3134        try {
3135            final File tracesFile = new File(tracesPath);
3136            final File tracesDir = tracesFile.getParentFile();
3137            final File tracesTmp = new File(tracesDir, "__tmp__");
3138            try {
3139                if (!tracesDir.exists()) tracesFile.mkdirs();
3140                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3141
3142                if (tracesFile.exists()) {
3143                    tracesTmp.delete();
3144                    tracesFile.renameTo(tracesTmp);
3145                }
3146                StringBuilder sb = new StringBuilder();
3147                Time tobj = new Time();
3148                tobj.set(System.currentTimeMillis());
3149                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3150                sb.append(": ");
3151                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3152                sb.append(" since ");
3153                sb.append(msg);
3154                FileOutputStream fos = new FileOutputStream(tracesFile);
3155                fos.write(sb.toString().getBytes());
3156                if (app == null) {
3157                    fos.write("\n*** No application process!".getBytes());
3158                }
3159                fos.close();
3160                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3161            } catch (IOException e) {
3162                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3163                return;
3164            }
3165
3166            if (app != null) {
3167                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3168                firstPids.add(app.pid);
3169                dumpStackTraces(tracesPath, firstPids, null, null, null);
3170            }
3171
3172            File lastTracesFile = null;
3173            File curTracesFile = null;
3174            for (int i=9; i>=0; i--) {
3175                String name = String.format("slow%02d.txt", i);
3176                curTracesFile = new File(tracesDir, name);
3177                if (curTracesFile.exists()) {
3178                    if (lastTracesFile != null) {
3179                        curTracesFile.renameTo(lastTracesFile);
3180                    } else {
3181                        curTracesFile.delete();
3182                    }
3183                }
3184                lastTracesFile = curTracesFile;
3185            }
3186            tracesFile.renameTo(curTracesFile);
3187            if (tracesTmp.exists()) {
3188                tracesTmp.renameTo(tracesFile);
3189            }
3190        } finally {
3191            StrictMode.setThreadPolicy(oldPolicy);
3192        }
3193    }
3194
3195    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3196            ActivityRecord parent, final String annotation) {
3197        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3198        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3199
3200        if (mController != null) {
3201            try {
3202                // 0 == continue, -1 = kill process immediately
3203                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3204                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3205            } catch (RemoteException e) {
3206                mController = null;
3207            }
3208        }
3209
3210        long anrTime = SystemClock.uptimeMillis();
3211        if (MONITOR_CPU_USAGE) {
3212            updateCpuStatsNow();
3213        }
3214
3215        synchronized (this) {
3216            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3217            if (mShuttingDown) {
3218                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3219                return;
3220            } else if (app.notResponding) {
3221                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3222                return;
3223            } else if (app.crashing) {
3224                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3225                return;
3226            }
3227
3228            // In case we come through here for the same app before completing
3229            // this one, mark as anring now so we will bail out.
3230            app.notResponding = true;
3231
3232            // Log the ANR to the event log.
3233            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3234                    annotation);
3235
3236            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3237            firstPids.add(app.pid);
3238
3239            int parentPid = app.pid;
3240            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3241            if (parentPid != app.pid) firstPids.add(parentPid);
3242
3243            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3244
3245            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3246                ProcessRecord r = mLruProcesses.get(i);
3247                if (r != null && r.thread != null) {
3248                    int pid = r.pid;
3249                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3250                        if (r.persistent) {
3251                            firstPids.add(pid);
3252                        } else {
3253                            lastPids.put(pid, Boolean.TRUE);
3254                        }
3255                    }
3256                }
3257            }
3258        }
3259
3260        // Log the ANR to the main log.
3261        StringBuilder info = new StringBuilder();
3262        info.setLength(0);
3263        info.append("ANR in ").append(app.processName);
3264        if (activity != null && activity.shortComponentName != null) {
3265            info.append(" (").append(activity.shortComponentName).append(")");
3266        }
3267        info.append("\n");
3268        if (annotation != null) {
3269            info.append("Reason: ").append(annotation).append("\n");
3270        }
3271        if (parent != null && parent != activity) {
3272            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3273        }
3274
3275        final ProcessStats processStats = new ProcessStats(true);
3276
3277        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3278
3279        String cpuInfo = null;
3280        if (MONITOR_CPU_USAGE) {
3281            updateCpuStatsNow();
3282            synchronized (mProcessStatsThread) {
3283                cpuInfo = mProcessStats.printCurrentState(anrTime);
3284            }
3285            info.append(processStats.printCurrentLoad());
3286            info.append(cpuInfo);
3287        }
3288
3289        info.append(processStats.printCurrentState(anrTime));
3290
3291        Slog.e(TAG, info.toString());
3292        if (tracesFile == null) {
3293            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3294            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3295        }
3296
3297        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3298                cpuInfo, tracesFile, null);
3299
3300        if (mController != null) {
3301            try {
3302                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3303                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3304                if (res != 0) {
3305                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3306                    return;
3307                }
3308            } catch (RemoteException e) {
3309                mController = null;
3310            }
3311        }
3312
3313        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3314        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3315                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3316
3317        synchronized (this) {
3318            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3319                Slog.w(TAG, "Killing " + app + ": background ANR");
3320                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3321                        app.processName, app.setAdj, "background ANR");
3322                Process.killProcessQuiet(app.pid);
3323                return;
3324            }
3325
3326            // Set the app's notResponding state, and look up the errorReportReceiver
3327            makeAppNotRespondingLocked(app,
3328                    activity != null ? activity.shortComponentName : null,
3329                    annotation != null ? "ANR " + annotation : "ANR",
3330                    info.toString());
3331
3332            // Bring up the infamous App Not Responding dialog
3333            Message msg = Message.obtain();
3334            HashMap map = new HashMap();
3335            msg.what = SHOW_NOT_RESPONDING_MSG;
3336            msg.obj = map;
3337            map.put("app", app);
3338            if (activity != null) {
3339                map.put("activity", activity);
3340            }
3341
3342            mHandler.sendMessage(msg);
3343        }
3344    }
3345
3346    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3347        if (!mLaunchWarningShown) {
3348            mLaunchWarningShown = true;
3349            mHandler.post(new Runnable() {
3350                @Override
3351                public void run() {
3352                    synchronized (ActivityManagerService.this) {
3353                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3354                        d.show();
3355                        mHandler.postDelayed(new Runnable() {
3356                            @Override
3357                            public void run() {
3358                                synchronized (ActivityManagerService.this) {
3359                                    d.dismiss();
3360                                    mLaunchWarningShown = false;
3361                                }
3362                            }
3363                        }, 4000);
3364                    }
3365                }
3366            });
3367        }
3368    }
3369
3370    public boolean clearApplicationUserData(final String packageName,
3371            final IPackageDataObserver observer, final int userId) {
3372        enforceNotIsolatedCaller("clearApplicationUserData");
3373        int uid = Binder.getCallingUid();
3374        int pid = Binder.getCallingPid();
3375        long callingId = Binder.clearCallingIdentity();
3376        try {
3377            IPackageManager pm = AppGlobals.getPackageManager();
3378            int pkgUid = -1;
3379            synchronized(this) {
3380                try {
3381                    pkgUid = pm.getPackageUid(packageName, userId);
3382                } catch (RemoteException e) {
3383                }
3384                if (pkgUid == -1) {
3385                    Slog.w(TAG, "Invalid packageName:" + packageName);
3386                    return false;
3387                }
3388                if (uid == pkgUid || checkComponentPermission(
3389                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3390                        pid, uid, -1, true)
3391                        == PackageManager.PERMISSION_GRANTED) {
3392                    forceStopPackageLocked(packageName, pkgUid);
3393                } else {
3394                    throw new SecurityException(pid+" does not have permission:"+
3395                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3396                                    "for process:"+packageName);
3397                }
3398            }
3399
3400            try {
3401                //clear application user data
3402                pm.clearApplicationUserData(packageName, observer, userId);
3403                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3404                        Uri.fromParts("package", packageName, null));
3405                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3406                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3407                        null, null, 0, null, null, null, false, false, userId);
3408            } catch (RemoteException e) {
3409            }
3410        } finally {
3411            Binder.restoreCallingIdentity(callingId);
3412        }
3413        return true;
3414    }
3415
3416    public void killBackgroundProcesses(final String packageName) {
3417        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3418                != PackageManager.PERMISSION_GRANTED &&
3419                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3420                        != PackageManager.PERMISSION_GRANTED) {
3421            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3422                    + Binder.getCallingPid()
3423                    + ", uid=" + Binder.getCallingUid()
3424                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3425            Slog.w(TAG, msg);
3426            throw new SecurityException(msg);
3427        }
3428
3429        int userId = UserId.getCallingUserId();
3430        long callingId = Binder.clearCallingIdentity();
3431        try {
3432            IPackageManager pm = AppGlobals.getPackageManager();
3433            int pkgUid = -1;
3434            synchronized(this) {
3435                try {
3436                    pkgUid = pm.getPackageUid(packageName, userId);
3437                } catch (RemoteException e) {
3438                }
3439                if (pkgUid == -1) {
3440                    Slog.w(TAG, "Invalid packageName: " + packageName);
3441                    return;
3442                }
3443                killPackageProcessesLocked(packageName, pkgUid,
3444                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3445            }
3446        } finally {
3447            Binder.restoreCallingIdentity(callingId);
3448        }
3449    }
3450
3451    public void killAllBackgroundProcesses() {
3452        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3453                != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        long callingId = Binder.clearCallingIdentity();
3463        try {
3464            synchronized(this) {
3465                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3466                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3467                    final int NA = apps.size();
3468                    for (int ia=0; ia<NA; ia++) {
3469                        ProcessRecord app = apps.valueAt(ia);
3470                        if (app.persistent) {
3471                            // we don't kill persistent processes
3472                            continue;
3473                        }
3474                        if (app.removed) {
3475                            procs.add(app);
3476                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3477                            app.removed = true;
3478                            procs.add(app);
3479                        }
3480                    }
3481                }
3482
3483                int N = procs.size();
3484                for (int i=0; i<N; i++) {
3485                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3486                }
3487            }
3488        } finally {
3489            Binder.restoreCallingIdentity(callingId);
3490        }
3491    }
3492
3493    public void forceStopPackage(final String packageName) {
3494        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3495                != PackageManager.PERMISSION_GRANTED) {
3496            String msg = "Permission Denial: forceStopPackage() from pid="
3497                    + Binder.getCallingPid()
3498                    + ", uid=" + Binder.getCallingUid()
3499                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3500            Slog.w(TAG, msg);
3501            throw new SecurityException(msg);
3502        }
3503        final int userId = UserId.getCallingUserId();
3504        long callingId = Binder.clearCallingIdentity();
3505        try {
3506            IPackageManager pm = AppGlobals.getPackageManager();
3507            int pkgUid = -1;
3508            synchronized(this) {
3509                try {
3510                    pkgUid = pm.getPackageUid(packageName, userId);
3511                } catch (RemoteException e) {
3512                }
3513                if (pkgUid == -1) {
3514                    Slog.w(TAG, "Invalid packageName: " + packageName);
3515                    return;
3516                }
3517                forceStopPackageLocked(packageName, pkgUid);
3518                try {
3519                    pm.setPackageStoppedState(packageName, true, userId);
3520                } catch (RemoteException e) {
3521                } catch (IllegalArgumentException e) {
3522                    Slog.w(TAG, "Failed trying to unstop package "
3523                            + packageName + ": " + e);
3524                }
3525            }
3526        } finally {
3527            Binder.restoreCallingIdentity(callingId);
3528        }
3529    }
3530
3531    /*
3532     * The pkg name and uid have to be specified.
3533     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3534     */
3535    public void killApplicationWithUid(String pkg, int uid) {
3536        if (pkg == null) {
3537            return;
3538        }
3539        // Make sure the uid is valid.
3540        if (uid < 0) {
3541            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3542            return;
3543        }
3544        int callerUid = Binder.getCallingUid();
3545        // Only the system server can kill an application
3546        if (callerUid == Process.SYSTEM_UID) {
3547            // Post an aysnc message to kill the application
3548            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3549            msg.arg1 = uid;
3550            msg.arg2 = 0;
3551            msg.obj = pkg;
3552            mHandler.sendMessage(msg);
3553        } else {
3554            throw new SecurityException(callerUid + " cannot kill pkg: " +
3555                    pkg);
3556        }
3557    }
3558
3559    public void closeSystemDialogs(String reason) {
3560        enforceNotIsolatedCaller("closeSystemDialogs");
3561
3562        final int uid = Binder.getCallingUid();
3563        final long origId = Binder.clearCallingIdentity();
3564        synchronized (this) {
3565            closeSystemDialogsLocked(uid, reason);
3566        }
3567        Binder.restoreCallingIdentity(origId);
3568    }
3569
3570    void closeSystemDialogsLocked(int callingUid, String reason) {
3571        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3572        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3573        if (reason != null) {
3574            intent.putExtra("reason", reason);
3575        }
3576        mWindowManager.closeSystemDialogs(reason);
3577
3578        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3579            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3580            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3581                r.stack.finishActivityLocked(r, i,
3582                        Activity.RESULT_CANCELED, null, "close-sys");
3583            }
3584        }
3585
3586        broadcastIntentLocked(null, null, intent, null,
3587                null, 0, null, null, null, false, false, -1,
3588                callingUid, 0 /* TODO: Verify */);
3589    }
3590
3591    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3592            throws RemoteException {
3593        enforceNotIsolatedCaller("getProcessMemoryInfo");
3594        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3595        for (int i=pids.length-1; i>=0; i--) {
3596            infos[i] = new Debug.MemoryInfo();
3597            Debug.getMemoryInfo(pids[i], infos[i]);
3598        }
3599        return infos;
3600    }
3601
3602    public long[] getProcessPss(int[] pids) throws RemoteException {
3603        enforceNotIsolatedCaller("getProcessPss");
3604        long[] pss = new long[pids.length];
3605        for (int i=pids.length-1; i>=0; i--) {
3606            pss[i] = Debug.getPss(pids[i]);
3607        }
3608        return pss;
3609    }
3610
3611    public void killApplicationProcess(String processName, int uid) {
3612        if (processName == null) {
3613            return;
3614        }
3615
3616        int callerUid = Binder.getCallingUid();
3617        // Only the system server can kill an application
3618        if (callerUid == Process.SYSTEM_UID) {
3619            synchronized (this) {
3620                ProcessRecord app = getProcessRecordLocked(processName, uid);
3621                if (app != null && app.thread != null) {
3622                    try {
3623                        app.thread.scheduleSuicide();
3624                    } catch (RemoteException e) {
3625                        // If the other end already died, then our work here is done.
3626                    }
3627                } else {
3628                    Slog.w(TAG, "Process/uid not found attempting kill of "
3629                            + processName + " / " + uid);
3630                }
3631            }
3632        } else {
3633            throw new SecurityException(callerUid + " cannot kill app process: " +
3634                    processName);
3635        }
3636    }
3637
3638    private void forceStopPackageLocked(final String packageName, int uid) {
3639        forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
3640        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3641                Uri.fromParts("package", packageName, null));
3642        if (!mProcessesReady) {
3643            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3644        }
3645        intent.putExtra(Intent.EXTRA_UID, uid);
3646        broadcastIntentLocked(null, null, intent,
3647                null, null, 0, null, null, null,
3648                false, false,
3649                MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
3650    }
3651
3652    private final boolean killPackageProcessesLocked(String packageName, int uid,
3653            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3654            boolean evenPersistent, String reason) {
3655        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3656
3657        // Remove all processes this package may have touched: all with the
3658        // same UID (except for the system or root user), and all whose name
3659        // matches the package name.
3660        final String procNamePrefix = packageName + ":";
3661        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3662            final int NA = apps.size();
3663            for (int ia=0; ia<NA; ia++) {
3664                ProcessRecord app = apps.valueAt(ia);
3665                if (app.persistent && !evenPersistent) {
3666                    // we don't kill persistent processes
3667                    continue;
3668                }
3669                if (app.removed) {
3670                    if (doit) {
3671                        procs.add(app);
3672                    }
3673                // If uid is specified and the uid and process name match
3674                // Or, the uid is not specified and the process name matches
3675                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3676                            || ((app.processName.equals(packageName)
3677                                 || app.processName.startsWith(procNamePrefix))
3678                                && uid < 0))) {
3679                    if (app.setAdj >= minOomAdj) {
3680                        if (!doit) {
3681                            return true;
3682                        }
3683                        app.removed = true;
3684                        procs.add(app);
3685                    }
3686                }
3687            }
3688        }
3689
3690        int N = procs.size();
3691        for (int i=0; i<N; i++) {
3692            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3693        }
3694        return N > 0;
3695    }
3696
3697    private final boolean forceStopPackageLocked(String name, int uid,
3698            boolean callerWillRestart, boolean purgeCache, boolean doit,
3699            boolean evenPersistent, int userId) {
3700        int i;
3701        int N;
3702
3703        if (uid < 0) {
3704            try {
3705                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3706            } catch (RemoteException e) {
3707            }
3708        }
3709
3710        if (doit) {
3711            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3712
3713            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3714            while (badApps.hasNext()) {
3715                SparseArray<Long> ba = badApps.next();
3716                if (ba.get(uid) != null) {
3717                    badApps.remove();
3718                }
3719            }
3720        }
3721
3722        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3723                callerWillRestart, false, doit, evenPersistent, "force stop");
3724
3725        TaskRecord lastTask = null;
3726        for (i=0; i<mMainStack.mHistory.size(); i++) {
3727            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3728            final boolean samePackage = r.packageName.equals(name);
3729            if (r.userId == userId
3730                    && (samePackage || r.task == lastTask)
3731                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3732                if (!doit) {
3733                    if (r.finishing) {
3734                        // If this activity is just finishing, then it is not
3735                        // interesting as far as something to stop.
3736                        continue;
3737                    }
3738                    return true;
3739                }
3740                didSomething = true;
3741                Slog.i(TAG, "  Force finishing activity " + r);
3742                if (samePackage) {
3743                    if (r.app != null) {
3744                        r.app.removed = true;
3745                    }
3746                    r.app = null;
3747                }
3748                lastTask = r.task;
3749                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3750                        null, "force-stop", true)) {
3751                    i--;
3752                }
3753            }
3754        }
3755
3756        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3757        for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
3758            if (service.packageName.equals(name)
3759                    && (service.app == null || evenPersistent || !service.app.persistent)) {
3760                if (!doit) {
3761                    return true;
3762                }
3763                didSomething = true;
3764                Slog.i(TAG, "  Force stopping service " + service);
3765                if (service.app != null) {
3766                    service.app.removed = true;
3767                }
3768                service.app = null;
3769                service.isolatedProc = null;
3770                services.add(service);
3771            }
3772        }
3773
3774        N = services.size();
3775        for (i=0; i<N; i++) {
3776            bringDownServiceLocked(services.get(i), true);
3777        }
3778
3779        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3780        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3781            if (provider.info.packageName.equals(name)
3782                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3783                if (!doit) {
3784                    return true;
3785                }
3786                didSomething = true;
3787                providers.add(provider);
3788            }
3789        }
3790
3791        N = providers.size();
3792        for (i=0; i<N; i++) {
3793            removeDyingProviderLocked(null, providers.get(i), true);
3794        }
3795
3796        if (doit) {
3797            if (purgeCache) {
3798                AttributeCache ac = AttributeCache.instance();
3799                if (ac != null) {
3800                    ac.removePackage(name);
3801                }
3802            }
3803            if (mBooted) {
3804                mMainStack.resumeTopActivityLocked(null);
3805                mMainStack.scheduleIdleLocked();
3806            }
3807        }
3808
3809        return didSomething;
3810    }
3811
3812    private final boolean removeProcessLocked(ProcessRecord app,
3813            boolean callerWillRestart, boolean allowRestart, String reason) {
3814        final String name = app.processName;
3815        final int uid = app.uid;
3816        if (DEBUG_PROCESSES) Slog.d(
3817            TAG, "Force removing proc " + app.toShortString() + " (" + name
3818            + "/" + uid + ")");
3819
3820        mProcessNames.remove(name, uid);
3821        mIsolatedProcesses.remove(app.uid);
3822        if (mHeavyWeightProcess == app) {
3823            mHeavyWeightProcess = null;
3824            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3825        }
3826        boolean needRestart = false;
3827        if (app.pid > 0 && app.pid != MY_PID) {
3828            int pid = app.pid;
3829            synchronized (mPidsSelfLocked) {
3830                mPidsSelfLocked.remove(pid);
3831                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3832            }
3833            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3834            handleAppDiedLocked(app, true, allowRestart);
3835            mLruProcesses.remove(app);
3836            Process.killProcessQuiet(pid);
3837
3838            if (app.persistent && !app.isolated) {
3839                if (!callerWillRestart) {
3840                    addAppLocked(app.info, false);
3841                } else {
3842                    needRestart = true;
3843                }
3844            }
3845        } else {
3846            mRemovedProcesses.add(app);
3847        }
3848
3849        return needRestart;
3850    }
3851
3852    private final void processStartTimedOutLocked(ProcessRecord app) {
3853        final int pid = app.pid;
3854        boolean gone = false;
3855        synchronized (mPidsSelfLocked) {
3856            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3857            if (knownApp != null && knownApp.thread == null) {
3858                mPidsSelfLocked.remove(pid);
3859                gone = true;
3860            }
3861        }
3862
3863        if (gone) {
3864            Slog.w(TAG, "Process " + app + " failed to attach");
3865            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3866                    app.processName);
3867            mProcessNames.remove(app.processName, app.uid);
3868            mIsolatedProcesses.remove(app.uid);
3869            if (mHeavyWeightProcess == app) {
3870                mHeavyWeightProcess = null;
3871                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3872            }
3873            // Take care of any launching providers waiting for this process.
3874            checkAppInLaunchingProvidersLocked(app, true);
3875            // Take care of any services that are waiting for the process.
3876            for (int i=0; i<mPendingServices.size(); i++) {
3877                ServiceRecord sr = mPendingServices.get(i);
3878                if ((app.uid == sr.appInfo.uid
3879                        && app.processName.equals(sr.processName))
3880                        || sr.isolatedProc == app) {
3881                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3882                    sr.isolatedProc = null;
3883                    mPendingServices.remove(i);
3884                    i--;
3885                    bringDownServiceLocked(sr, true);
3886                }
3887            }
3888            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3889                    app.processName, app.setAdj, "start timeout");
3890            Process.killProcessQuiet(pid);
3891            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3892                Slog.w(TAG, "Unattached app died before backup, skipping");
3893                try {
3894                    IBackupManager bm = IBackupManager.Stub.asInterface(
3895                            ServiceManager.getService(Context.BACKUP_SERVICE));
3896                    bm.agentDisconnected(app.info.packageName);
3897                } catch (RemoteException e) {
3898                    // Can't happen; the backup manager is local
3899                }
3900            }
3901            if (isPendingBroadcastProcessLocked(pid)) {
3902                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3903                skipPendingBroadcastLocked(pid);
3904            }
3905        } else {
3906            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3907        }
3908    }
3909
3910    private final boolean attachApplicationLocked(IApplicationThread thread,
3911            int pid) {
3912
3913        // Find the application record that is being attached...  either via
3914        // the pid if we are running in multiple processes, or just pull the
3915        // next app record if we are emulating process with anonymous threads.
3916        ProcessRecord app;
3917        if (pid != MY_PID && pid >= 0) {
3918            synchronized (mPidsSelfLocked) {
3919                app = mPidsSelfLocked.get(pid);
3920            }
3921        } else {
3922            app = null;
3923        }
3924
3925        if (app == null) {
3926            Slog.w(TAG, "No pending application record for pid " + pid
3927                    + " (IApplicationThread " + thread + "); dropping process");
3928            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3929            if (pid > 0 && pid != MY_PID) {
3930                Process.killProcessQuiet(pid);
3931            } else {
3932                try {
3933                    thread.scheduleExit();
3934                } catch (Exception e) {
3935                    // Ignore exceptions.
3936                }
3937            }
3938            return false;
3939        }
3940
3941        // If this application record is still attached to a previous
3942        // process, clean it up now.
3943        if (app.thread != null) {
3944            handleAppDiedLocked(app, true, true);
3945        }
3946
3947        // Tell the process all about itself.
3948
3949        if (localLOGV) Slog.v(
3950                TAG, "Binding process pid " + pid + " to record " + app);
3951
3952        String processName = app.processName;
3953        try {
3954            AppDeathRecipient adr = new AppDeathRecipient(
3955                    app, pid, thread);
3956            thread.asBinder().linkToDeath(adr, 0);
3957            app.deathRecipient = adr;
3958        } catch (RemoteException e) {
3959            app.resetPackageList();
3960            startProcessLocked(app, "link fail", processName);
3961            return false;
3962        }
3963
3964        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3965
3966        app.thread = thread;
3967        app.curAdj = app.setAdj = -100;
3968        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3969        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3970        app.forcingToForeground = null;
3971        app.foregroundServices = false;
3972        app.hasShownUi = false;
3973        app.debugging = false;
3974
3975        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3976
3977        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3978        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3979
3980        if (!normalMode) {
3981            Slog.i(TAG, "Launching preboot mode app: " + app);
3982        }
3983
3984        if (localLOGV) Slog.v(
3985            TAG, "New app record " + app
3986            + " thread=" + thread.asBinder() + " pid=" + pid);
3987        try {
3988            int testMode = IApplicationThread.DEBUG_OFF;
3989            if (mDebugApp != null && mDebugApp.equals(processName)) {
3990                testMode = mWaitForDebugger
3991                    ? IApplicationThread.DEBUG_WAIT
3992                    : IApplicationThread.DEBUG_ON;
3993                app.debugging = true;
3994                if (mDebugTransient) {
3995                    mDebugApp = mOrigDebugApp;
3996                    mWaitForDebugger = mOrigWaitForDebugger;
3997                }
3998            }
3999            String profileFile = app.instrumentationProfileFile;
4000            ParcelFileDescriptor profileFd = null;
4001            boolean profileAutoStop = false;
4002            if (mProfileApp != null && mProfileApp.equals(processName)) {
4003                mProfileProc = app;
4004                profileFile = mProfileFile;
4005                profileFd = mProfileFd;
4006                profileAutoStop = mAutoStopProfiler;
4007            }
4008            boolean enableOpenGlTrace = false;
4009            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4010                enableOpenGlTrace = true;
4011                mOpenGlTraceApp = null;
4012            }
4013
4014            // If the app is being launched for restore or full backup, set it up specially
4015            boolean isRestrictedBackupMode = false;
4016            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4017                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4018                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4019                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4020            }
4021
4022            ensurePackageDexOpt(app.instrumentationInfo != null
4023                    ? app.instrumentationInfo.packageName
4024                    : app.info.packageName);
4025            if (app.instrumentationClass != null) {
4026                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4027            }
4028            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4029                    + processName + " with config " + mConfiguration);
4030            ApplicationInfo appInfo = app.instrumentationInfo != null
4031                    ? app.instrumentationInfo : app.info;
4032            app.compat = compatibilityInfoForPackageLocked(appInfo);
4033            if (profileFd != null) {
4034                profileFd = profileFd.dup();
4035            }
4036            thread.bindApplication(processName, appInfo, providers,
4037                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4038                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4039                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4040                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4041                    mCoreSettingsObserver.getCoreSettingsLocked());
4042            updateLruProcessLocked(app, false, true);
4043            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4044        } catch (Exception e) {
4045            // todo: Yikes!  What should we do?  For now we will try to
4046            // start another process, but that could easily get us in
4047            // an infinite loop of restarting processes...
4048            Slog.w(TAG, "Exception thrown during bind!", e);
4049
4050            app.resetPackageList();
4051            app.unlinkDeathRecipient();
4052            startProcessLocked(app, "bind fail", processName);
4053            return false;
4054        }
4055
4056        // Remove this record from the list of starting applications.
4057        mPersistentStartingProcesses.remove(app);
4058        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4059                "Attach application locked removing on hold: " + app);
4060        mProcessesOnHold.remove(app);
4061
4062        boolean badApp = false;
4063        boolean didSomething = false;
4064
4065        // See if the top visible activity is waiting to run in this process...
4066        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4067        if (hr != null && normalMode) {
4068            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4069                    && processName.equals(hr.processName)) {
4070                try {
4071                    if (mHeadless) {
4072                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4073                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4074                        didSomething = true;
4075                    }
4076                } catch (Exception e) {
4077                    Slog.w(TAG, "Exception in new application when starting activity "
4078                          + hr.intent.getComponent().flattenToShortString(), e);
4079                    badApp = true;
4080                }
4081            } else {
4082                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4083            }
4084        }
4085
4086        // Find any services that should be running in this process...
4087        if (!badApp && mPendingServices.size() > 0) {
4088            ServiceRecord sr = null;
4089            try {
4090                for (int i=0; i<mPendingServices.size(); i++) {
4091                    sr = mPendingServices.get(i);
4092                    if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4093                            || !processName.equals(sr.processName))) {
4094                        continue;
4095                    }
4096
4097                    mPendingServices.remove(i);
4098                    i--;
4099                    realStartServiceLocked(sr, app);
4100                    didSomething = true;
4101                }
4102            } catch (Exception e) {
4103                Slog.w(TAG, "Exception in new application when starting service "
4104                      + sr.shortName, e);
4105                badApp = true;
4106            }
4107        }
4108
4109        // Check if a next-broadcast receiver is in this process...
4110        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4111            try {
4112                didSomething = sendPendingBroadcastsLocked(app);
4113            } catch (Exception e) {
4114                // If the app died trying to launch the receiver we declare it 'bad'
4115                badApp = true;
4116            }
4117        }
4118
4119        // Check whether the next backup agent is in this process...
4120        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4121            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4122            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4123            try {
4124                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4125                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4126                        mBackupTarget.backupMode);
4127            } catch (Exception e) {
4128                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4129                e.printStackTrace();
4130            }
4131        }
4132
4133        if (badApp) {
4134            // todo: Also need to kill application to deal with all
4135            // kinds of exceptions.
4136            handleAppDiedLocked(app, false, true);
4137            return false;
4138        }
4139
4140        if (!didSomething) {
4141            updateOomAdjLocked();
4142        }
4143
4144        return true;
4145    }
4146
4147    public final void attachApplication(IApplicationThread thread) {
4148        synchronized (this) {
4149            int callingPid = Binder.getCallingPid();
4150            final long origId = Binder.clearCallingIdentity();
4151            attachApplicationLocked(thread, callingPid);
4152            Binder.restoreCallingIdentity(origId);
4153        }
4154    }
4155
4156    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4157        final long origId = Binder.clearCallingIdentity();
4158        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4159        if (stopProfiling) {
4160            synchronized (this) {
4161                if (mProfileProc == r.app) {
4162                    if (mProfileFd != null) {
4163                        try {
4164                            mProfileFd.close();
4165                        } catch (IOException e) {
4166                        }
4167                        clearProfilerLocked();
4168                    }
4169                }
4170            }
4171        }
4172        Binder.restoreCallingIdentity(origId);
4173    }
4174
4175    void enableScreenAfterBoot() {
4176        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4177                SystemClock.uptimeMillis());
4178        mWindowManager.enableScreenAfterBoot();
4179
4180        synchronized (this) {
4181            updateEventDispatchingLocked();
4182        }
4183    }
4184
4185    public void showBootMessage(final CharSequence msg, final boolean always) {
4186        enforceNotIsolatedCaller("showBootMessage");
4187        mWindowManager.showBootMessage(msg, always);
4188    }
4189
4190    public void dismissKeyguardOnNextActivity() {
4191        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4192        final long token = Binder.clearCallingIdentity();
4193        try {
4194            synchronized (this) {
4195                if (mLockScreenShown) {
4196                    mLockScreenShown = false;
4197                    comeOutOfSleepIfNeededLocked();
4198                }
4199                mMainStack.dismissKeyguardOnNextActivityLocked();
4200            }
4201        } finally {
4202            Binder.restoreCallingIdentity(token);
4203        }
4204    }
4205
4206    final void finishBooting() {
4207        IntentFilter pkgFilter = new IntentFilter();
4208        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4209        pkgFilter.addDataScheme("package");
4210        mContext.registerReceiver(new BroadcastReceiver() {
4211            @Override
4212            public void onReceive(Context context, Intent intent) {
4213                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4214                if (pkgs != null) {
4215                    for (String pkg : pkgs) {
4216                        synchronized (ActivityManagerService.this) {
4217                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4218                                setResultCode(Activity.RESULT_OK);
4219                                return;
4220                            }
4221                        }
4222                    }
4223                }
4224            }
4225        }, pkgFilter);
4226
4227        IntentFilter userFilter = new IntentFilter();
4228        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4229        mContext.registerReceiver(new BroadcastReceiver() {
4230            @Override
4231            public void onReceive(Context context, Intent intent) {
4232                onUserRemoved(intent);
4233            }
4234        }, userFilter);
4235
4236        synchronized (this) {
4237            // Ensure that any processes we had put on hold are now started
4238            // up.
4239            final int NP = mProcessesOnHold.size();
4240            if (NP > 0) {
4241                ArrayList<ProcessRecord> procs =
4242                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4243                for (int ip=0; ip<NP; ip++) {
4244                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4245                            + procs.get(ip));
4246                    startProcessLocked(procs.get(ip), "on-hold", null);
4247                }
4248            }
4249
4250            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4251                // Start looking for apps that are abusing wake locks.
4252                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4253                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4254                // Tell anyone interested that we are done booting!
4255                SystemProperties.set("sys.boot_completed", "1");
4256                SystemProperties.set("dev.bootcomplete", "1");
4257                /* TODO: Send this to all users that are to be logged in on startup */
4258                broadcastIntentLocked(null, null,
4259                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4260                        null, null, 0, null, null,
4261                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4262                        false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
4263            }
4264        }
4265    }
4266
4267    final void ensureBootCompleted() {
4268        boolean booting;
4269        boolean enableScreen;
4270        synchronized (this) {
4271            booting = mBooting;
4272            mBooting = false;
4273            enableScreen = !mBooted;
4274            mBooted = true;
4275        }
4276
4277        if (booting) {
4278            finishBooting();
4279        }
4280
4281        if (enableScreen) {
4282            enableScreenAfterBoot();
4283        }
4284    }
4285
4286    public final void activityPaused(IBinder token) {
4287        final long origId = Binder.clearCallingIdentity();
4288        mMainStack.activityPaused(token, false);
4289        Binder.restoreCallingIdentity(origId);
4290    }
4291
4292    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4293            CharSequence description) {
4294        if (localLOGV) Slog.v(
4295            TAG, "Activity stopped: token=" + token);
4296
4297        // Refuse possible leaked file descriptors
4298        if (icicle != null && icicle.hasFileDescriptors()) {
4299            throw new IllegalArgumentException("File descriptors passed in Bundle");
4300        }
4301
4302        ActivityRecord r = null;
4303
4304        final long origId = Binder.clearCallingIdentity();
4305
4306        synchronized (this) {
4307            r = mMainStack.isInStackLocked(token);
4308            if (r != null) {
4309                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4310            }
4311        }
4312
4313        if (r != null) {
4314            sendPendingThumbnail(r, null, null, null, false);
4315        }
4316
4317        trimApplications();
4318
4319        Binder.restoreCallingIdentity(origId);
4320    }
4321
4322    public final void activityDestroyed(IBinder token) {
4323        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4324        mMainStack.activityDestroyed(token);
4325    }
4326
4327    public String getCallingPackage(IBinder token) {
4328        synchronized (this) {
4329            ActivityRecord r = getCallingRecordLocked(token);
4330            return r != null && r.app != null ? r.info.packageName : null;
4331        }
4332    }
4333
4334    public ComponentName getCallingActivity(IBinder token) {
4335        synchronized (this) {
4336            ActivityRecord r = getCallingRecordLocked(token);
4337            return r != null ? r.intent.getComponent() : null;
4338        }
4339    }
4340
4341    private ActivityRecord getCallingRecordLocked(IBinder token) {
4342        ActivityRecord r = mMainStack.isInStackLocked(token);
4343        if (r == null) {
4344            return null;
4345        }
4346        return r.resultTo;
4347    }
4348
4349    public ComponentName getActivityClassForToken(IBinder token) {
4350        synchronized(this) {
4351            ActivityRecord r = mMainStack.isInStackLocked(token);
4352            if (r == null) {
4353                return null;
4354            }
4355            return r.intent.getComponent();
4356        }
4357    }
4358
4359    public String getPackageForToken(IBinder token) {
4360        synchronized(this) {
4361            ActivityRecord r = mMainStack.isInStackLocked(token);
4362            if (r == null) {
4363                return null;
4364            }
4365            return r.packageName;
4366        }
4367    }
4368
4369    public IIntentSender getIntentSender(int type,
4370            String packageName, IBinder token, String resultWho,
4371            int requestCode, Intent[] intents, String[] resolvedTypes,
4372            int flags, Bundle options) {
4373        enforceNotIsolatedCaller("getIntentSender");
4374        // Refuse possible leaked file descriptors
4375        if (intents != null) {
4376            if (intents.length < 1) {
4377                throw new IllegalArgumentException("Intents array length must be >= 1");
4378            }
4379            for (int i=0; i<intents.length; i++) {
4380                Intent intent = intents[i];
4381                if (intent != null) {
4382                    if (intent.hasFileDescriptors()) {
4383                        throw new IllegalArgumentException("File descriptors passed in Intent");
4384                    }
4385                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4386                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4387                        throw new IllegalArgumentException(
4388                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4389                    }
4390                    intents[i] = new Intent(intent);
4391                }
4392            }
4393            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4394                throw new IllegalArgumentException(
4395                        "Intent array length does not match resolvedTypes length");
4396            }
4397        }
4398        if (options != null) {
4399            if (options.hasFileDescriptors()) {
4400                throw new IllegalArgumentException("File descriptors passed in options");
4401            }
4402        }
4403
4404        synchronized(this) {
4405            int callingUid = Binder.getCallingUid();
4406            try {
4407                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4408                    int uid = AppGlobals.getPackageManager()
4409                            .getPackageUid(packageName, UserId.getUserId(callingUid));
4410                    if (!UserId.isSameApp(callingUid, uid)) {
4411                        String msg = "Permission Denial: getIntentSender() from pid="
4412                            + Binder.getCallingPid()
4413                            + ", uid=" + Binder.getCallingUid()
4414                            + ", (need uid=" + uid + ")"
4415                            + " is not allowed to send as package " + packageName;
4416                        Slog.w(TAG, msg);
4417                        throw new SecurityException(msg);
4418                    }
4419                }
4420
4421                if (DEBUG_MU)
4422                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4423                            + Binder.getOrigCallingUid());
4424                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4425                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4426
4427            } catch (RemoteException e) {
4428                throw new SecurityException(e);
4429            }
4430        }
4431    }
4432
4433    IIntentSender getIntentSenderLocked(int type,
4434            String packageName, int callingUid, IBinder token, String resultWho,
4435            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4436            Bundle options) {
4437        if (DEBUG_MU)
4438            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4439        ActivityRecord activity = null;
4440        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4441            activity = mMainStack.isInStackLocked(token);
4442            if (activity == null) {
4443                return null;
4444            }
4445            if (activity.finishing) {
4446                return null;
4447            }
4448        }
4449
4450        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4451        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4452        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4453        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4454                |PendingIntent.FLAG_UPDATE_CURRENT);
4455
4456        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4457                type, packageName, activity, resultWho,
4458                requestCode, intents, resolvedTypes, flags, options);
4459        WeakReference<PendingIntentRecord> ref;
4460        ref = mIntentSenderRecords.get(key);
4461        PendingIntentRecord rec = ref != null ? ref.get() : null;
4462        if (rec != null) {
4463            if (!cancelCurrent) {
4464                if (updateCurrent) {
4465                    if (rec.key.requestIntent != null) {
4466                        rec.key.requestIntent.replaceExtras(intents != null ?
4467                                intents[intents.length - 1] : null);
4468                    }
4469                    if (intents != null) {
4470                        intents[intents.length-1] = rec.key.requestIntent;
4471                        rec.key.allIntents = intents;
4472                        rec.key.allResolvedTypes = resolvedTypes;
4473                    } else {
4474                        rec.key.allIntents = null;
4475                        rec.key.allResolvedTypes = null;
4476                    }
4477                }
4478                return rec;
4479            }
4480            rec.canceled = true;
4481            mIntentSenderRecords.remove(key);
4482        }
4483        if (noCreate) {
4484            return rec;
4485        }
4486        rec = new PendingIntentRecord(this, key, callingUid);
4487        mIntentSenderRecords.put(key, rec.ref);
4488        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4489            if (activity.pendingResults == null) {
4490                activity.pendingResults
4491                        = new HashSet<WeakReference<PendingIntentRecord>>();
4492            }
4493            activity.pendingResults.add(rec.ref);
4494        }
4495        return rec;
4496    }
4497
4498    public void cancelIntentSender(IIntentSender sender) {
4499        if (!(sender instanceof PendingIntentRecord)) {
4500            return;
4501        }
4502        synchronized(this) {
4503            PendingIntentRecord rec = (PendingIntentRecord)sender;
4504            try {
4505                int uid = AppGlobals.getPackageManager()
4506                        .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
4507                if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
4508                    String msg = "Permission Denial: cancelIntentSender() from pid="
4509                        + Binder.getCallingPid()
4510                        + ", uid=" + Binder.getCallingUid()
4511                        + " is not allowed to cancel packges "
4512                        + rec.key.packageName;
4513                    Slog.w(TAG, msg);
4514                    throw new SecurityException(msg);
4515                }
4516            } catch (RemoteException e) {
4517                throw new SecurityException(e);
4518            }
4519            cancelIntentSenderLocked(rec, true);
4520        }
4521    }
4522
4523    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4524        rec.canceled = true;
4525        mIntentSenderRecords.remove(rec.key);
4526        if (cleanActivity && rec.key.activity != null) {
4527            rec.key.activity.pendingResults.remove(rec.ref);
4528        }
4529    }
4530
4531    public String getPackageForIntentSender(IIntentSender pendingResult) {
4532        if (!(pendingResult instanceof PendingIntentRecord)) {
4533            return null;
4534        }
4535        try {
4536            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4537            return res.key.packageName;
4538        } catch (ClassCastException e) {
4539        }
4540        return null;
4541    }
4542
4543    public int getUidForIntentSender(IIntentSender sender) {
4544        if (sender instanceof PendingIntentRecord) {
4545            try {
4546                PendingIntentRecord res = (PendingIntentRecord)sender;
4547                return res.uid;
4548            } catch (ClassCastException e) {
4549            }
4550        }
4551        return -1;
4552    }
4553
4554    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4555        if (!(pendingResult instanceof PendingIntentRecord)) {
4556            return false;
4557        }
4558        try {
4559            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4560            if (res.key.allIntents == null) {
4561                return false;
4562            }
4563            for (int i=0; i<res.key.allIntents.length; i++) {
4564                Intent intent = res.key.allIntents[i];
4565                if (intent.getPackage() != null && intent.getComponent() != null) {
4566                    return false;
4567                }
4568            }
4569            return true;
4570        } catch (ClassCastException e) {
4571        }
4572        return false;
4573    }
4574
4575    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4576        if (!(pendingResult instanceof PendingIntentRecord)) {
4577            return false;
4578        }
4579        try {
4580            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4581            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4582                return true;
4583            }
4584            return false;
4585        } catch (ClassCastException e) {
4586        }
4587        return false;
4588    }
4589
4590    public void setProcessLimit(int max) {
4591        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4592                "setProcessLimit()");
4593        synchronized (this) {
4594            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4595            mProcessLimitOverride = max;
4596        }
4597        trimApplications();
4598    }
4599
4600    public int getProcessLimit() {
4601        synchronized (this) {
4602            return mProcessLimitOverride;
4603        }
4604    }
4605
4606    void foregroundTokenDied(ForegroundToken token) {
4607        synchronized (ActivityManagerService.this) {
4608            synchronized (mPidsSelfLocked) {
4609                ForegroundToken cur
4610                    = mForegroundProcesses.get(token.pid);
4611                if (cur != token) {
4612                    return;
4613                }
4614                mForegroundProcesses.remove(token.pid);
4615                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4616                if (pr == null) {
4617                    return;
4618                }
4619                pr.forcingToForeground = null;
4620                pr.foregroundServices = false;
4621            }
4622            updateOomAdjLocked();
4623        }
4624    }
4625
4626    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4627        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4628                "setProcessForeground()");
4629        synchronized(this) {
4630            boolean changed = false;
4631
4632            synchronized (mPidsSelfLocked) {
4633                ProcessRecord pr = mPidsSelfLocked.get(pid);
4634                if (pr == null && isForeground) {
4635                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4636                    return;
4637                }
4638                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4639                if (oldToken != null) {
4640                    oldToken.token.unlinkToDeath(oldToken, 0);
4641                    mForegroundProcesses.remove(pid);
4642                    if (pr != null) {
4643                        pr.forcingToForeground = null;
4644                    }
4645                    changed = true;
4646                }
4647                if (isForeground && token != null) {
4648                    ForegroundToken newToken = new ForegroundToken() {
4649                        public void binderDied() {
4650                            foregroundTokenDied(this);
4651                        }
4652                    };
4653                    newToken.pid = pid;
4654                    newToken.token = token;
4655                    try {
4656                        token.linkToDeath(newToken, 0);
4657                        mForegroundProcesses.put(pid, newToken);
4658                        pr.forcingToForeground = token;
4659                        changed = true;
4660                    } catch (RemoteException e) {
4661                        // If the process died while doing this, we will later
4662                        // do the cleanup with the process death link.
4663                    }
4664                }
4665            }
4666
4667            if (changed) {
4668                updateOomAdjLocked();
4669            }
4670        }
4671    }
4672
4673    // =========================================================
4674    // PERMISSIONS
4675    // =========================================================
4676
4677    static class PermissionController extends IPermissionController.Stub {
4678        ActivityManagerService mActivityManagerService;
4679        PermissionController(ActivityManagerService activityManagerService) {
4680            mActivityManagerService = activityManagerService;
4681        }
4682
4683        public boolean checkPermission(String permission, int pid, int uid) {
4684            return mActivityManagerService.checkPermission(permission, pid,
4685                    uid) == PackageManager.PERMISSION_GRANTED;
4686        }
4687    }
4688
4689    /**
4690     * This can be called with or without the global lock held.
4691     */
4692    int checkComponentPermission(String permission, int pid, int uid,
4693            int owningUid, boolean exported) {
4694        // We might be performing an operation on behalf of an indirect binder
4695        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4696        // client identity accordingly before proceeding.
4697        Identity tlsIdentity = sCallerIdentity.get();
4698        if (tlsIdentity != null) {
4699            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4700                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4701            uid = tlsIdentity.uid;
4702            pid = tlsIdentity.pid;
4703        }
4704
4705        if (pid == MY_PID) {
4706            return PackageManager.PERMISSION_GRANTED;
4707        }
4708
4709        return ActivityManager.checkComponentPermission(permission, uid,
4710                owningUid, exported);
4711    }
4712
4713    /**
4714     * As the only public entry point for permissions checking, this method
4715     * can enforce the semantic that requesting a check on a null global
4716     * permission is automatically denied.  (Internally a null permission
4717     * string is used when calling {@link #checkComponentPermission} in cases
4718     * when only uid-based security is needed.)
4719     *
4720     * This can be called with or without the global lock held.
4721     */
4722    public int checkPermission(String permission, int pid, int uid) {
4723        if (permission == null) {
4724            return PackageManager.PERMISSION_DENIED;
4725        }
4726        return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
4727    }
4728
4729    /**
4730     * Binder IPC calls go through the public entry point.
4731     * This can be called with or without the global lock held.
4732     */
4733    int checkCallingPermission(String permission) {
4734        return checkPermission(permission,
4735                Binder.getCallingPid(),
4736                UserId.getAppId(Binder.getCallingUid()));
4737    }
4738
4739    /**
4740     * This can be called with or without the global lock held.
4741     */
4742    void enforceCallingPermission(String permission, String func) {
4743        if (checkCallingPermission(permission)
4744                == PackageManager.PERMISSION_GRANTED) {
4745            return;
4746        }
4747
4748        String msg = "Permission Denial: " + func + " from pid="
4749                + Binder.getCallingPid()
4750                + ", uid=" + Binder.getCallingUid()
4751                + " requires " + permission;
4752        Slog.w(TAG, msg);
4753        throw new SecurityException(msg);
4754    }
4755
4756    /**
4757     * Determine if UID is holding permissions required to access {@link Uri} in
4758     * the given {@link ProviderInfo}. Final permission checking is always done
4759     * in {@link ContentProvider}.
4760     */
4761    private final boolean checkHoldingPermissionsLocked(
4762            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4763        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4764                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4765
4766        if (pi.applicationInfo.uid == uid) {
4767            return true;
4768        } else if (!pi.exported) {
4769            return false;
4770        }
4771
4772        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4773        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4774        try {
4775            // check if target holds top-level <provider> permissions
4776            if (!readMet && pi.readPermission != null
4777                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4778                readMet = true;
4779            }
4780            if (!writeMet && pi.writePermission != null
4781                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4782                writeMet = true;
4783            }
4784
4785            // track if unprotected read/write is allowed; any denied
4786            // <path-permission> below removes this ability
4787            boolean allowDefaultRead = pi.readPermission == null;
4788            boolean allowDefaultWrite = pi.writePermission == null;
4789
4790            // check if target holds any <path-permission> that match uri
4791            final PathPermission[] pps = pi.pathPermissions;
4792            if (pps != null) {
4793                final String path = uri.getPath();
4794                int i = pps.length;
4795                while (i > 0 && (!readMet || !writeMet)) {
4796                    i--;
4797                    PathPermission pp = pps[i];
4798                    if (pp.match(path)) {
4799                        if (!readMet) {
4800                            final String pprperm = pp.getReadPermission();
4801                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4802                                    + pprperm + " for " + pp.getPath()
4803                                    + ": match=" + pp.match(path)
4804                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4805                            if (pprperm != null) {
4806                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4807                                    readMet = true;
4808                                } else {
4809                                    allowDefaultRead = false;
4810                                }
4811                            }
4812                        }
4813                        if (!writeMet) {
4814                            final String ppwperm = pp.getWritePermission();
4815                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4816                                    + ppwperm + " for " + pp.getPath()
4817                                    + ": match=" + pp.match(path)
4818                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4819                            if (ppwperm != null) {
4820                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4821                                    writeMet = true;
4822                                } else {
4823                                    allowDefaultWrite = false;
4824                                }
4825                            }
4826                        }
4827                    }
4828                }
4829            }
4830
4831            // grant unprotected <provider> read/write, if not blocked by
4832            // <path-permission> above
4833            if (allowDefaultRead) readMet = true;
4834            if (allowDefaultWrite) writeMet = true;
4835
4836        } catch (RemoteException e) {
4837            return false;
4838        }
4839
4840        return readMet && writeMet;
4841    }
4842
4843    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4844            int modeFlags) {
4845        // Root gets to do everything.
4846        if (uid == 0) {
4847            return true;
4848        }
4849        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4850        if (perms == null) return false;
4851        UriPermission perm = perms.get(uri);
4852        if (perm == null) return false;
4853        return (modeFlags&perm.modeFlags) == modeFlags;
4854    }
4855
4856    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4857        enforceNotIsolatedCaller("checkUriPermission");
4858
4859        // Another redirected-binder-call permissions check as in
4860        // {@link checkComponentPermission}.
4861        Identity tlsIdentity = sCallerIdentity.get();
4862        if (tlsIdentity != null) {
4863            uid = tlsIdentity.uid;
4864            pid = tlsIdentity.pid;
4865        }
4866
4867        uid = UserId.getAppId(uid);
4868        // Our own process gets to do everything.
4869        if (pid == MY_PID) {
4870            return PackageManager.PERMISSION_GRANTED;
4871        }
4872        synchronized(this) {
4873            return checkUriPermissionLocked(uri, uid, modeFlags)
4874                    ? PackageManager.PERMISSION_GRANTED
4875                    : PackageManager.PERMISSION_DENIED;
4876        }
4877    }
4878
4879    /**
4880     * Check if the targetPkg can be granted permission to access uri by
4881     * the callingUid using the given modeFlags.  Throws a security exception
4882     * if callingUid is not allowed to do this.  Returns the uid of the target
4883     * if the URI permission grant should be performed; returns -1 if it is not
4884     * needed (for example targetPkg already has permission to access the URI).
4885     * If you already know the uid of the target, you can supply it in
4886     * lastTargetUid else set that to -1.
4887     */
4888    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4889            Uri uri, int modeFlags, int lastTargetUid) {
4890        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4891                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4892        if (modeFlags == 0) {
4893            return -1;
4894        }
4895
4896        if (targetPkg != null) {
4897            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4898                    "Checking grant " + targetPkg + " permission to " + uri);
4899        }
4900
4901        final IPackageManager pm = AppGlobals.getPackageManager();
4902
4903        // If this is not a content: uri, we can't do anything with it.
4904        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4905            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4906                    "Can't grant URI permission for non-content URI: " + uri);
4907            return -1;
4908        }
4909
4910        String name = uri.getAuthority();
4911        ProviderInfo pi = null;
4912        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4913                UserId.getUserId(callingUid));
4914        if (cpr != null) {
4915            pi = cpr.info;
4916        } else {
4917            try {
4918                pi = pm.resolveContentProvider(name,
4919                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
4920            } catch (RemoteException ex) {
4921            }
4922        }
4923        if (pi == null) {
4924            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4925            return -1;
4926        }
4927
4928        int targetUid = lastTargetUid;
4929        if (targetUid < 0 && targetPkg != null) {
4930            try {
4931                targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
4932                if (targetUid < 0) {
4933                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4934                            "Can't grant URI permission no uid for: " + targetPkg);
4935                    return -1;
4936                }
4937            } catch (RemoteException ex) {
4938                return -1;
4939            }
4940        }
4941
4942        if (targetUid >= 0) {
4943            // First...  does the target actually need this permission?
4944            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4945                // No need to grant the target this permission.
4946                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4947                        "Target " + targetPkg + " already has full permission to " + uri);
4948                return -1;
4949            }
4950        } else {
4951            // First...  there is no target package, so can anyone access it?
4952            boolean allowed = pi.exported;
4953            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4954                if (pi.readPermission != null) {
4955                    allowed = false;
4956                }
4957            }
4958            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4959                if (pi.writePermission != null) {
4960                    allowed = false;
4961                }
4962            }
4963            if (allowed) {
4964                return -1;
4965            }
4966        }
4967
4968        // Second...  is the provider allowing granting of URI permissions?
4969        if (!pi.grantUriPermissions) {
4970            throw new SecurityException("Provider " + pi.packageName
4971                    + "/" + pi.name
4972                    + " does not allow granting of Uri permissions (uri "
4973                    + uri + ")");
4974        }
4975        if (pi.uriPermissionPatterns != null) {
4976            final int N = pi.uriPermissionPatterns.length;
4977            boolean allowed = false;
4978            for (int i=0; i<N; i++) {
4979                if (pi.uriPermissionPatterns[i] != null
4980                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4981                    allowed = true;
4982                    break;
4983                }
4984            }
4985            if (!allowed) {
4986                throw new SecurityException("Provider " + pi.packageName
4987                        + "/" + pi.name
4988                        + " does not allow granting of permission to path of Uri "
4989                        + uri);
4990            }
4991        }
4992
4993        // Third...  does the caller itself have permission to access
4994        // this uri?
4995        if (callingUid != Process.myUid()) {
4996            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4997                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4998                    throw new SecurityException("Uid " + callingUid
4999                            + " does not have permission to uri " + uri);
5000                }
5001            }
5002        }
5003
5004        return targetUid;
5005    }
5006
5007    public int checkGrantUriPermission(int callingUid, String targetPkg,
5008            Uri uri, int modeFlags) {
5009        enforceNotIsolatedCaller("checkGrantUriPermission");
5010        synchronized(this) {
5011            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5012        }
5013    }
5014
5015    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5016            Uri uri, int modeFlags, UriPermissionOwner owner) {
5017        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5018                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5019        if (modeFlags == 0) {
5020            return;
5021        }
5022
5023        // So here we are: the caller has the assumed permission
5024        // to the uri, and the target doesn't.  Let's now give this to
5025        // the target.
5026
5027        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5028                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5029
5030        HashMap<Uri, UriPermission> targetUris
5031                = mGrantedUriPermissions.get(targetUid);
5032        if (targetUris == null) {
5033            targetUris = new HashMap<Uri, UriPermission>();
5034            mGrantedUriPermissions.put(targetUid, targetUris);
5035        }
5036
5037        UriPermission perm = targetUris.get(uri);
5038        if (perm == null) {
5039            perm = new UriPermission(targetUid, uri);
5040            targetUris.put(uri, perm);
5041        }
5042
5043        perm.modeFlags |= modeFlags;
5044        if (owner == null) {
5045            perm.globalModeFlags |= modeFlags;
5046        } else {
5047            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5048                 perm.readOwners.add(owner);
5049                 owner.addReadPermission(perm);
5050            }
5051            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5052                 perm.writeOwners.add(owner);
5053                 owner.addWritePermission(perm);
5054            }
5055        }
5056    }
5057
5058    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5059            int modeFlags, UriPermissionOwner owner) {
5060        if (targetPkg == null) {
5061            throw new NullPointerException("targetPkg");
5062        }
5063
5064        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5065        if (targetUid < 0) {
5066            return;
5067        }
5068
5069        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5070    }
5071
5072    static class NeededUriGrants extends ArrayList<Uri> {
5073        final String targetPkg;
5074        final int targetUid;
5075        final int flags;
5076
5077        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5078            targetPkg = _targetPkg;
5079            targetUid = _targetUid;
5080            flags = _flags;
5081        }
5082    }
5083
5084    /**
5085     * Like checkGrantUriPermissionLocked, but takes an Intent.
5086     */
5087    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5088            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5089        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5090                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5091                + " clip=" + (intent != null ? intent.getClipData() : null)
5092                + " from " + intent + "; flags=0x"
5093                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5094
5095        if (targetPkg == null) {
5096            throw new NullPointerException("targetPkg");
5097        }
5098
5099        if (intent == null) {
5100            return null;
5101        }
5102        Uri data = intent.getData();
5103        ClipData clip = intent.getClipData();
5104        if (data == null && clip == null) {
5105            return null;
5106        }
5107        if (data != null) {
5108            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5109                mode, needed != null ? needed.targetUid : -1);
5110            if (target > 0) {
5111                if (needed == null) {
5112                    needed = new NeededUriGrants(targetPkg, target, mode);
5113                }
5114                needed.add(data);
5115            }
5116        }
5117        if (clip != null) {
5118            for (int i=0; i<clip.getItemCount(); i++) {
5119                Uri uri = clip.getItemAt(i).getUri();
5120                if (uri != null) {
5121                    int target = -1;
5122                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5123                            mode, needed != null ? needed.targetUid : -1);
5124                    if (target > 0) {
5125                        if (needed == null) {
5126                            needed = new NeededUriGrants(targetPkg, target, mode);
5127                        }
5128                        needed.add(uri);
5129                    }
5130                } else {
5131                    Intent clipIntent = clip.getItemAt(i).getIntent();
5132                    if (clipIntent != null) {
5133                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5134                                callingUid, targetPkg, clipIntent, mode, needed);
5135                        if (newNeeded != null) {
5136                            needed = newNeeded;
5137                        }
5138                    }
5139                }
5140            }
5141        }
5142
5143        return needed;
5144    }
5145
5146    /**
5147     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5148     */
5149    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5150            UriPermissionOwner owner) {
5151        if (needed != null) {
5152            for (int i=0; i<needed.size(); i++) {
5153                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5154                        needed.get(i), needed.flags, owner);
5155            }
5156        }
5157    }
5158
5159    void grantUriPermissionFromIntentLocked(int callingUid,
5160            String targetPkg, Intent intent, UriPermissionOwner owner) {
5161        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5162                intent, intent != null ? intent.getFlags() : 0, null);
5163        if (needed == null) {
5164            return;
5165        }
5166
5167        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5168    }
5169
5170    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5171            Uri uri, int modeFlags) {
5172        enforceNotIsolatedCaller("grantUriPermission");
5173        synchronized(this) {
5174            final ProcessRecord r = getRecordForAppLocked(caller);
5175            if (r == null) {
5176                throw new SecurityException("Unable to find app for caller "
5177                        + caller
5178                        + " when granting permission to uri " + uri);
5179            }
5180            if (targetPkg == null) {
5181                throw new IllegalArgumentException("null target");
5182            }
5183            if (uri == null) {
5184                throw new IllegalArgumentException("null uri");
5185            }
5186
5187            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5188                    null);
5189        }
5190    }
5191
5192    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5193        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5194                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5195            HashMap<Uri, UriPermission> perms
5196                    = mGrantedUriPermissions.get(perm.uid);
5197            if (perms != null) {
5198                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5199                        "Removing " + perm.uid + " permission to " + perm.uri);
5200                perms.remove(perm.uri);
5201                if (perms.size() == 0) {
5202                    mGrantedUriPermissions.remove(perm.uid);
5203                }
5204            }
5205        }
5206    }
5207
5208    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5209            int modeFlags) {
5210        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5211                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5212        if (modeFlags == 0) {
5213            return;
5214        }
5215
5216        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5217                "Revoking all granted permissions to " + uri);
5218
5219        final IPackageManager pm = AppGlobals.getPackageManager();
5220
5221        final String authority = uri.getAuthority();
5222        ProviderInfo pi = null;
5223        int userId = UserId.getUserId(callingUid);
5224        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5225        if (cpr != null) {
5226            pi = cpr.info;
5227        } else {
5228            try {
5229                pi = pm.resolveContentProvider(authority,
5230                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5231            } catch (RemoteException ex) {
5232            }
5233        }
5234        if (pi == null) {
5235            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5236            return;
5237        }
5238
5239        // Does the caller have this permission on the URI?
5240        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5241            // Right now, if you are not the original owner of the permission,
5242            // you are not allowed to revoke it.
5243            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5244                throw new SecurityException("Uid " + callingUid
5245                        + " does not have permission to uri " + uri);
5246            //}
5247        }
5248
5249        // Go through all of the permissions and remove any that match.
5250        final List<String> SEGMENTS = uri.getPathSegments();
5251        if (SEGMENTS != null) {
5252            final int NS = SEGMENTS.size();
5253            int N = mGrantedUriPermissions.size();
5254            for (int i=0; i<N; i++) {
5255                HashMap<Uri, UriPermission> perms
5256                        = mGrantedUriPermissions.valueAt(i);
5257                Iterator<UriPermission> it = perms.values().iterator();
5258            toploop:
5259                while (it.hasNext()) {
5260                    UriPermission perm = it.next();
5261                    Uri targetUri = perm.uri;
5262                    if (!authority.equals(targetUri.getAuthority())) {
5263                        continue;
5264                    }
5265                    List<String> targetSegments = targetUri.getPathSegments();
5266                    if (targetSegments == null) {
5267                        continue;
5268                    }
5269                    if (targetSegments.size() < NS) {
5270                        continue;
5271                    }
5272                    for (int j=0; j<NS; j++) {
5273                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5274                            continue toploop;
5275                        }
5276                    }
5277                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5278                            "Revoking " + perm.uid + " permission to " + perm.uri);
5279                    perm.clearModes(modeFlags);
5280                    if (perm.modeFlags == 0) {
5281                        it.remove();
5282                    }
5283                }
5284                if (perms.size() == 0) {
5285                    mGrantedUriPermissions.remove(
5286                            mGrantedUriPermissions.keyAt(i));
5287                    N--;
5288                    i--;
5289                }
5290            }
5291        }
5292    }
5293
5294    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5295            int modeFlags) {
5296        enforceNotIsolatedCaller("revokeUriPermission");
5297        synchronized(this) {
5298            final ProcessRecord r = getRecordForAppLocked(caller);
5299            if (r == null) {
5300                throw new SecurityException("Unable to find app for caller "
5301                        + caller
5302                        + " when revoking permission to uri " + uri);
5303            }
5304            if (uri == null) {
5305                Slog.w(TAG, "revokeUriPermission: null uri");
5306                return;
5307            }
5308
5309            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5310                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5311            if (modeFlags == 0) {
5312                return;
5313            }
5314
5315            final IPackageManager pm = AppGlobals.getPackageManager();
5316
5317            final String authority = uri.getAuthority();
5318            ProviderInfo pi = null;
5319            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5320            if (cpr != null) {
5321                pi = cpr.info;
5322            } else {
5323                try {
5324                    pi = pm.resolveContentProvider(authority,
5325                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5326                } catch (RemoteException ex) {
5327                }
5328            }
5329            if (pi == null) {
5330                Slog.w(TAG, "No content provider found for permission revoke: "
5331                        + uri.toSafeString());
5332                return;
5333            }
5334
5335            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5336        }
5337    }
5338
5339    @Override
5340    public IBinder newUriPermissionOwner(String name) {
5341        enforceNotIsolatedCaller("newUriPermissionOwner");
5342        synchronized(this) {
5343            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5344            return owner.getExternalTokenLocked();
5345        }
5346    }
5347
5348    @Override
5349    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5350            Uri uri, int modeFlags) {
5351        synchronized(this) {
5352            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5353            if (owner == null) {
5354                throw new IllegalArgumentException("Unknown owner: " + token);
5355            }
5356            if (fromUid != Binder.getCallingUid()) {
5357                if (Binder.getCallingUid() != Process.myUid()) {
5358                    // Only system code can grant URI permissions on behalf
5359                    // of other users.
5360                    throw new SecurityException("nice try");
5361                }
5362            }
5363            if (targetPkg == null) {
5364                throw new IllegalArgumentException("null target");
5365            }
5366            if (uri == null) {
5367                throw new IllegalArgumentException("null uri");
5368            }
5369
5370            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5371        }
5372    }
5373
5374    @Override
5375    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5376        synchronized(this) {
5377            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5378            if (owner == null) {
5379                throw new IllegalArgumentException("Unknown owner: " + token);
5380            }
5381
5382            if (uri == null) {
5383                owner.removeUriPermissionsLocked(mode);
5384            } else {
5385                owner.removeUriPermissionLocked(uri, mode);
5386            }
5387        }
5388    }
5389
5390    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5391        synchronized (this) {
5392            ProcessRecord app =
5393                who != null ? getRecordForAppLocked(who) : null;
5394            if (app == null) return;
5395
5396            Message msg = Message.obtain();
5397            msg.what = WAIT_FOR_DEBUGGER_MSG;
5398            msg.obj = app;
5399            msg.arg1 = waiting ? 1 : 0;
5400            mHandler.sendMessage(msg);
5401        }
5402    }
5403
5404    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5405        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5406        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5407        outInfo.availMem = Process.getFreeMemory();
5408        outInfo.totalMem = Process.getTotalMemory();
5409        outInfo.threshold = homeAppMem;
5410        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5411        outInfo.hiddenAppThreshold = hiddenAppMem;
5412        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5413                ProcessList.SERVICE_ADJ);
5414        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5415                ProcessList.VISIBLE_APP_ADJ);
5416        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5417                ProcessList.FOREGROUND_APP_ADJ);
5418    }
5419
5420    // =========================================================
5421    // TASK MANAGEMENT
5422    // =========================================================
5423
5424    public List getTasks(int maxNum, int flags,
5425                         IThumbnailReceiver receiver) {
5426        ArrayList list = new ArrayList();
5427
5428        PendingThumbnailsRecord pending = null;
5429        IApplicationThread topThumbnail = null;
5430        ActivityRecord topRecord = null;
5431
5432        synchronized(this) {
5433            if (localLOGV) Slog.v(
5434                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5435                + ", receiver=" + receiver);
5436
5437            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5438                    != PackageManager.PERMISSION_GRANTED) {
5439                if (receiver != null) {
5440                    // If the caller wants to wait for pending thumbnails,
5441                    // it ain't gonna get them.
5442                    try {
5443                        receiver.finished();
5444                    } catch (RemoteException ex) {
5445                    }
5446                }
5447                String msg = "Permission Denial: getTasks() from pid="
5448                        + Binder.getCallingPid()
5449                        + ", uid=" + Binder.getCallingUid()
5450                        + " requires " + android.Manifest.permission.GET_TASKS;
5451                Slog.w(TAG, msg);
5452                throw new SecurityException(msg);
5453            }
5454
5455            int pos = mMainStack.mHistory.size()-1;
5456            ActivityRecord next =
5457                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5458            ActivityRecord top = null;
5459            TaskRecord curTask = null;
5460            int numActivities = 0;
5461            int numRunning = 0;
5462            while (pos >= 0 && maxNum > 0) {
5463                final ActivityRecord r = next;
5464                pos--;
5465                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5466
5467                // Initialize state for next task if needed.
5468                if (top == null ||
5469                        (top.state == ActivityState.INITIALIZING
5470                            && top.task == r.task)) {
5471                    top = r;
5472                    curTask = r.task;
5473                    numActivities = numRunning = 0;
5474                }
5475
5476                // Add 'r' into the current task.
5477                numActivities++;
5478                if (r.app != null && r.app.thread != null) {
5479                    numRunning++;
5480                }
5481
5482                if (localLOGV) Slog.v(
5483                    TAG, r.intent.getComponent().flattenToShortString()
5484                    + ": task=" + r.task);
5485
5486                // If the next one is a different task, generate a new
5487                // TaskInfo entry for what we have.
5488                if (next == null || next.task != curTask) {
5489                    ActivityManager.RunningTaskInfo ci
5490                            = new ActivityManager.RunningTaskInfo();
5491                    ci.id = curTask.taskId;
5492                    ci.baseActivity = r.intent.getComponent();
5493                    ci.topActivity = top.intent.getComponent();
5494                    if (top.thumbHolder != null) {
5495                        ci.description = top.thumbHolder.lastDescription;
5496                    }
5497                    ci.numActivities = numActivities;
5498                    ci.numRunning = numRunning;
5499                    //System.out.println(
5500                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5501                    if (ci.thumbnail == null && receiver != null) {
5502                        if (localLOGV) Slog.v(
5503                            TAG, "State=" + top.state + "Idle=" + top.idle
5504                            + " app=" + top.app
5505                            + " thr=" + (top.app != null ? top.app.thread : null));
5506                        if (top.state == ActivityState.RESUMED
5507                                || top.state == ActivityState.PAUSING) {
5508                            if (top.idle && top.app != null
5509                                && top.app.thread != null) {
5510                                topRecord = top;
5511                                topThumbnail = top.app.thread;
5512                            } else {
5513                                top.thumbnailNeeded = true;
5514                            }
5515                        }
5516                        if (pending == null) {
5517                            pending = new PendingThumbnailsRecord(receiver);
5518                        }
5519                        pending.pendingRecords.add(top);
5520                    }
5521                    list.add(ci);
5522                    maxNum--;
5523                    top = null;
5524                }
5525            }
5526
5527            if (pending != null) {
5528                mPendingThumbnails.add(pending);
5529            }
5530        }
5531
5532        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5533
5534        if (topThumbnail != null) {
5535            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5536            try {
5537                topThumbnail.requestThumbnail(topRecord.appToken);
5538            } catch (Exception e) {
5539                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5540                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5541            }
5542        }
5543
5544        if (pending == null && receiver != null) {
5545            // In this case all thumbnails were available and the client
5546            // is being asked to be told when the remaining ones come in...
5547            // which is unusually, since the top-most currently running
5548            // activity should never have a canned thumbnail!  Oh well.
5549            try {
5550                receiver.finished();
5551            } catch (RemoteException ex) {
5552            }
5553        }
5554
5555        return list;
5556    }
5557
5558    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5559            int flags) {
5560        final int callingUid = Binder.getCallingUid();
5561        // If it's the system uid asking, then use the current user id.
5562        // TODO: Make sure that there aren't any other legitimate calls from the system uid that
5563        // require the entire list.
5564        final int callingUserId = callingUid == Process.SYSTEM_UID
5565                ? mCurrentUserId : UserId.getUserId(callingUid);
5566        synchronized (this) {
5567            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5568                    "getRecentTasks()");
5569            final boolean detailed = checkCallingPermission(
5570                    android.Manifest.permission.GET_DETAILED_TASKS)
5571                    == PackageManager.PERMISSION_GRANTED;
5572
5573            IPackageManager pm = AppGlobals.getPackageManager();
5574
5575            final int N = mRecentTasks.size();
5576            ArrayList<ActivityManager.RecentTaskInfo> res
5577                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5578                            maxNum < N ? maxNum : N);
5579            for (int i=0; i<N && maxNum > 0; i++) {
5580                TaskRecord tr = mRecentTasks.get(i);
5581                // Only add calling user's recent tasks
5582                if (tr.userId != callingUserId) continue;
5583                // Return the entry if desired by the caller.  We always return
5584                // the first entry, because callers always expect this to be the
5585                // foreground app.  We may filter others if the caller has
5586                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5587                // we should exclude the entry.
5588
5589                if (i == 0
5590                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5591                        || (tr.intent == null)
5592                        || ((tr.intent.getFlags()
5593                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5594                    ActivityManager.RecentTaskInfo rti
5595                            = new ActivityManager.RecentTaskInfo();
5596                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5597                    rti.persistentId = tr.taskId;
5598                    rti.baseIntent = new Intent(
5599                            tr.intent != null ? tr.intent : tr.affinityIntent);
5600                    if (!detailed) {
5601                        rti.baseIntent.replaceExtras((Bundle)null);
5602                    }
5603                    rti.origActivity = tr.origActivity;
5604                    rti.description = tr.lastDescription;
5605
5606                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5607                        // Check whether this activity is currently available.
5608                        try {
5609                            if (rti.origActivity != null) {
5610                                if (pm.getActivityInfo(rti.origActivity, 0, callingUserId)
5611                                        == null) {
5612                                    continue;
5613                                }
5614                            } else if (rti.baseIntent != null) {
5615                                if (pm.queryIntentActivities(rti.baseIntent,
5616                                        null, 0, callingUserId) == null) {
5617                                    continue;
5618                                }
5619                            }
5620                        } catch (RemoteException e) {
5621                            // Will never happen.
5622                        }
5623                    }
5624
5625                    res.add(rti);
5626                    maxNum--;
5627                }
5628            }
5629            return res;
5630        }
5631    }
5632
5633    private TaskRecord taskForIdLocked(int id) {
5634        final int N = mRecentTasks.size();
5635        for (int i=0; i<N; i++) {
5636            TaskRecord tr = mRecentTasks.get(i);
5637            if (tr.taskId == id) {
5638                return tr;
5639            }
5640        }
5641        return null;
5642    }
5643
5644    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5645        synchronized (this) {
5646            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5647                    "getTaskThumbnails()");
5648            TaskRecord tr = taskForIdLocked(id);
5649            if (tr != null) {
5650                return mMainStack.getTaskThumbnailsLocked(tr);
5651            }
5652        }
5653        return null;
5654    }
5655
5656    public boolean removeSubTask(int taskId, int subTaskIndex) {
5657        synchronized (this) {
5658            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5659                    "removeSubTask()");
5660            long ident = Binder.clearCallingIdentity();
5661            try {
5662                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5663                        true) != null;
5664            } finally {
5665                Binder.restoreCallingIdentity(ident);
5666            }
5667        }
5668    }
5669
5670    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5671        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5672        Intent baseIntent = new Intent(
5673                tr.intent != null ? tr.intent : tr.affinityIntent);
5674        ComponentName component = baseIntent.getComponent();
5675        if (component == null) {
5676            Slog.w(TAG, "Now component for base intent of task: " + tr);
5677            return;
5678        }
5679
5680        // Find any running services associated with this app.
5681        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5682        for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) {
5683            if (sr.packageName.equals(component.getPackageName())) {
5684                services.add(sr);
5685            }
5686        }
5687
5688        // Take care of any running services associated with the app.
5689        for (int i=0; i<services.size(); i++) {
5690            ServiceRecord sr = services.get(i);
5691            if (sr.startRequested) {
5692                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5693                    Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
5694                    stopServiceLocked(sr);
5695                } else {
5696                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5697                            sr.makeNextStartId(), baseIntent, null));
5698                    if (sr.app != null && sr.app.thread != null) {
5699                        sendServiceArgsLocked(sr, false);
5700                    }
5701                }
5702            }
5703        }
5704
5705        if (killProcesses) {
5706            // Find any running processes associated with this app.
5707            final String pkg = component.getPackageName();
5708            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5709            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5710            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5711                for (int i=0; i<uids.size(); i++) {
5712                    ProcessRecord proc = uids.valueAt(i);
5713                    if (proc.userId != tr.userId) {
5714                        continue;
5715                    }
5716                    if (!proc.pkgList.contains(pkg)) {
5717                        continue;
5718                    }
5719                    procs.add(proc);
5720                }
5721            }
5722
5723            // Kill the running processes.
5724            for (int i=0; i<procs.size(); i++) {
5725                ProcessRecord pr = procs.get(i);
5726                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5727                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5728                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5729                            pr.processName, pr.setAdj, "remove task");
5730                    pr.killedBackground = true;
5731                    Process.killProcessQuiet(pr.pid);
5732                } else {
5733                    pr.waitingToKill = "remove task";
5734                }
5735            }
5736        }
5737    }
5738
5739    public boolean removeTask(int taskId, int flags) {
5740        synchronized (this) {
5741            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5742                    "removeTask()");
5743            long ident = Binder.clearCallingIdentity();
5744            try {
5745                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5746                        false);
5747                if (r != null) {
5748                    mRecentTasks.remove(r.task);
5749                    cleanUpRemovedTaskLocked(r.task, flags);
5750                    return true;
5751                } else {
5752                    TaskRecord tr = null;
5753                    int i=0;
5754                    while (i < mRecentTasks.size()) {
5755                        TaskRecord t = mRecentTasks.get(i);
5756                        if (t.taskId == taskId) {
5757                            tr = t;
5758                            break;
5759                        }
5760                        i++;
5761                    }
5762                    if (tr != null) {
5763                        if (tr.numActivities <= 0) {
5764                            // Caller is just removing a recent task that is
5765                            // not actively running.  That is easy!
5766                            mRecentTasks.remove(i);
5767                            cleanUpRemovedTaskLocked(tr, flags);
5768                            return true;
5769                        } else {
5770                            Slog.w(TAG, "removeTask: task " + taskId
5771                                    + " does not have activities to remove, "
5772                                    + " but numActivities=" + tr.numActivities
5773                                    + ": " + tr);
5774                        }
5775                    }
5776                }
5777            } finally {
5778                Binder.restoreCallingIdentity(ident);
5779            }
5780        }
5781        return false;
5782    }
5783
5784    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5785        int j;
5786        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5787        TaskRecord jt = startTask;
5788
5789        // First look backwards
5790        for (j=startIndex-1; j>=0; j--) {
5791            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5792            if (r.task != jt) {
5793                jt = r.task;
5794                if (affinity.equals(jt.affinity)) {
5795                    return j;
5796                }
5797            }
5798        }
5799
5800        // Now look forwards
5801        final int N = mMainStack.mHistory.size();
5802        jt = startTask;
5803        for (j=startIndex+1; j<N; j++) {
5804            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5805            if (r.task != jt) {
5806                if (affinity.equals(jt.affinity)) {
5807                    return j;
5808                }
5809                jt = r.task;
5810            }
5811        }
5812
5813        // Might it be at the top?
5814        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5815            return N-1;
5816        }
5817
5818        return -1;
5819    }
5820
5821    /**
5822     * TODO: Add mController hook
5823     */
5824    public void moveTaskToFront(int task, int flags, Bundle options) {
5825        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5826                "moveTaskToFront()");
5827
5828        synchronized(this) {
5829            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5830                    Binder.getCallingUid(), "Task to front")) {
5831                ActivityOptions.abort(options);
5832                return;
5833            }
5834            final long origId = Binder.clearCallingIdentity();
5835            try {
5836                TaskRecord tr = taskForIdLocked(task);
5837                if (tr != null) {
5838                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5839                        mMainStack.mUserLeaving = true;
5840                    }
5841                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5842                        // Caller wants the home activity moved with it.  To accomplish this,
5843                        // we'll just move the home task to the top first.
5844                        mMainStack.moveHomeToFrontLocked();
5845                    }
5846                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5847                    return;
5848                }
5849                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5850                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5851                    if (hr.task.taskId == task) {
5852                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5853                            mMainStack.mUserLeaving = true;
5854                        }
5855                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5856                            // Caller wants the home activity moved with it.  To accomplish this,
5857                            // we'll just move the home task to the top first.
5858                            mMainStack.moveHomeToFrontLocked();
5859                        }
5860                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5861                        return;
5862                    }
5863                }
5864            } finally {
5865                Binder.restoreCallingIdentity(origId);
5866            }
5867            ActivityOptions.abort(options);
5868        }
5869    }
5870
5871    public void moveTaskToBack(int task) {
5872        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5873                "moveTaskToBack()");
5874
5875        synchronized(this) {
5876            if (mMainStack.mResumedActivity != null
5877                    && mMainStack.mResumedActivity.task.taskId == task) {
5878                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5879                        Binder.getCallingUid(), "Task to back")) {
5880                    return;
5881                }
5882            }
5883            final long origId = Binder.clearCallingIdentity();
5884            mMainStack.moveTaskToBackLocked(task, null);
5885            Binder.restoreCallingIdentity(origId);
5886        }
5887    }
5888
5889    /**
5890     * Moves an activity, and all of the other activities within the same task, to the bottom
5891     * of the history stack.  The activity's order within the task is unchanged.
5892     *
5893     * @param token A reference to the activity we wish to move
5894     * @param nonRoot If false then this only works if the activity is the root
5895     *                of a task; if true it will work for any activity in a task.
5896     * @return Returns true if the move completed, false if not.
5897     */
5898    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5899        enforceNotIsolatedCaller("moveActivityTaskToBack");
5900        synchronized(this) {
5901            final long origId = Binder.clearCallingIdentity();
5902            int taskId = getTaskForActivityLocked(token, !nonRoot);
5903            if (taskId >= 0) {
5904                return mMainStack.moveTaskToBackLocked(taskId, null);
5905            }
5906            Binder.restoreCallingIdentity(origId);
5907        }
5908        return false;
5909    }
5910
5911    public void moveTaskBackwards(int task) {
5912        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5913                "moveTaskBackwards()");
5914
5915        synchronized(this) {
5916            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5917                    Binder.getCallingUid(), "Task backwards")) {
5918                return;
5919            }
5920            final long origId = Binder.clearCallingIdentity();
5921            moveTaskBackwardsLocked(task);
5922            Binder.restoreCallingIdentity(origId);
5923        }
5924    }
5925
5926    private final void moveTaskBackwardsLocked(int task) {
5927        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5928    }
5929
5930    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5931        synchronized(this) {
5932            return getTaskForActivityLocked(token, onlyRoot);
5933        }
5934    }
5935
5936    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5937        final int N = mMainStack.mHistory.size();
5938        TaskRecord lastTask = null;
5939        for (int i=0; i<N; i++) {
5940            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5941            if (r.appToken == token) {
5942                if (!onlyRoot || lastTask != r.task) {
5943                    return r.task.taskId;
5944                }
5945                return -1;
5946            }
5947            lastTask = r.task;
5948        }
5949
5950        return -1;
5951    }
5952
5953    // =========================================================
5954    // THUMBNAILS
5955    // =========================================================
5956
5957    public void reportThumbnail(IBinder token,
5958            Bitmap thumbnail, CharSequence description) {
5959        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5960        final long origId = Binder.clearCallingIdentity();
5961        sendPendingThumbnail(null, token, thumbnail, description, true);
5962        Binder.restoreCallingIdentity(origId);
5963    }
5964
5965    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5966            Bitmap thumbnail, CharSequence description, boolean always) {
5967        TaskRecord task = null;
5968        ArrayList receivers = null;
5969
5970        //System.out.println("Send pending thumbnail: " + r);
5971
5972        synchronized(this) {
5973            if (r == null) {
5974                r = mMainStack.isInStackLocked(token);
5975                if (r == null) {
5976                    return;
5977                }
5978            }
5979            if (thumbnail == null && r.thumbHolder != null) {
5980                thumbnail = r.thumbHolder.lastThumbnail;
5981                description = r.thumbHolder.lastDescription;
5982            }
5983            if (thumbnail == null && !always) {
5984                // If there is no thumbnail, and this entry is not actually
5985                // going away, then abort for now and pick up the next
5986                // thumbnail we get.
5987                return;
5988            }
5989            task = r.task;
5990
5991            int N = mPendingThumbnails.size();
5992            int i=0;
5993            while (i<N) {
5994                PendingThumbnailsRecord pr =
5995                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5996                //System.out.println("Looking in " + pr.pendingRecords);
5997                if (pr.pendingRecords.remove(r)) {
5998                    if (receivers == null) {
5999                        receivers = new ArrayList();
6000                    }
6001                    receivers.add(pr);
6002                    if (pr.pendingRecords.size() == 0) {
6003                        pr.finished = true;
6004                        mPendingThumbnails.remove(i);
6005                        N--;
6006                        continue;
6007                    }
6008                }
6009                i++;
6010            }
6011        }
6012
6013        if (receivers != null) {
6014            final int N = receivers.size();
6015            for (int i=0; i<N; i++) {
6016                try {
6017                    PendingThumbnailsRecord pr =
6018                        (PendingThumbnailsRecord)receivers.get(i);
6019                    pr.receiver.newThumbnail(
6020                        task != null ? task.taskId : -1, thumbnail, description);
6021                    if (pr.finished) {
6022                        pr.receiver.finished();
6023                    }
6024                } catch (Exception e) {
6025                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6026                }
6027            }
6028        }
6029    }
6030
6031    // =========================================================
6032    // CONTENT PROVIDERS
6033    // =========================================================
6034
6035    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6036        List<ProviderInfo> providers = null;
6037        try {
6038            providers = AppGlobals.getPackageManager().
6039                queryContentProviders(app.processName, app.uid,
6040                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6041        } catch (RemoteException ex) {
6042        }
6043        if (DEBUG_MU)
6044            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6045        int userId = app.userId;
6046        if (providers != null) {
6047            final int N = providers.size();
6048            for (int i=0; i<N; i++) {
6049                ProviderInfo cpi =
6050                    (ProviderInfo)providers.get(i);
6051
6052                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6053                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6054                if (cpr == null) {
6055                    cpr = new ContentProviderRecord(this, cpi, app.info, comp);
6056                    mProviderMap.putProviderByClass(comp, cpr);
6057                }
6058                if (DEBUG_MU)
6059                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6060                app.pubProviders.put(cpi.name, cpr);
6061                app.addPackage(cpi.applicationInfo.packageName);
6062                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6063            }
6064        }
6065        return providers;
6066    }
6067
6068    /**
6069     * Check if {@link ProcessRecord} has a possible chance at accessing the
6070     * given {@link ProviderInfo}. Final permission checking is always done
6071     * in {@link ContentProvider}.
6072     */
6073    private final String checkContentProviderPermissionLocked(
6074            ProviderInfo cpi, ProcessRecord r) {
6075        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6076        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6077        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6078                cpi.applicationInfo.uid, cpi.exported)
6079                == PackageManager.PERMISSION_GRANTED) {
6080            return null;
6081        }
6082        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6083                cpi.applicationInfo.uid, cpi.exported)
6084                == PackageManager.PERMISSION_GRANTED) {
6085            return null;
6086        }
6087
6088        PathPermission[] pps = cpi.pathPermissions;
6089        if (pps != null) {
6090            int i = pps.length;
6091            while (i > 0) {
6092                i--;
6093                PathPermission pp = pps[i];
6094                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6095                        cpi.applicationInfo.uid, cpi.exported)
6096                        == PackageManager.PERMISSION_GRANTED) {
6097                    return null;
6098                }
6099                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6100                        cpi.applicationInfo.uid, cpi.exported)
6101                        == PackageManager.PERMISSION_GRANTED) {
6102                    return null;
6103                }
6104            }
6105        }
6106
6107        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6108        if (perms != null) {
6109            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6110                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6111                    return null;
6112                }
6113            }
6114        }
6115
6116        String msg;
6117        if (!cpi.exported) {
6118            msg = "Permission Denial: opening provider " + cpi.name
6119                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6120                    + ", uid=" + callingUid + ") that is not exported from uid "
6121                    + cpi.applicationInfo.uid;
6122        } else {
6123            msg = "Permission Denial: opening provider " + cpi.name
6124                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6125                    + ", uid=" + callingUid + ") requires "
6126                    + cpi.readPermission + " or " + cpi.writePermission;
6127        }
6128        Slog.w(TAG, msg);
6129        return msg;
6130    }
6131
6132    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6133            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6134        if (r != null) {
6135            for (int i=0; i<r.conProviders.size(); i++) {
6136                ContentProviderConnection conn = r.conProviders.get(i);
6137                if (conn.provider == cpr) {
6138                    if (DEBUG_PROVIDER) Slog.v(TAG,
6139                            "Adding provider requested by "
6140                            + r.processName + " from process "
6141                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6142                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6143                    if (stable) {
6144                        conn.stableCount++;
6145                        conn.numStableIncs++;
6146                    } else {
6147                        conn.unstableCount++;
6148                        conn.numUnstableIncs++;
6149                    }
6150                    return conn;
6151                }
6152            }
6153            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6154            if (stable) {
6155                conn.stableCount = 1;
6156                conn.numStableIncs = 1;
6157            } else {
6158                conn.unstableCount = 1;
6159                conn.numUnstableIncs = 1;
6160            }
6161            cpr.connections.add(conn);
6162            r.conProviders.add(conn);
6163            return conn;
6164        }
6165        cpr.addExternalProcessHandleLocked(externalProcessToken);
6166        return null;
6167    }
6168
6169    boolean decProviderCountLocked(ContentProviderConnection conn,
6170            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6171        if (conn != null) {
6172            cpr = conn.provider;
6173            if (DEBUG_PROVIDER) Slog.v(TAG,
6174                    "Removing provider requested by "
6175                    + conn.client.processName + " from process "
6176                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6177                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6178            if (stable) {
6179                conn.stableCount--;
6180            } else {
6181                conn.unstableCount--;
6182            }
6183            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6184                cpr.connections.remove(conn);
6185                conn.client.conProviders.remove(conn);
6186                return true;
6187            }
6188            return false;
6189        }
6190        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6191        return false;
6192    }
6193
6194    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6195            String name, IBinder token, boolean stable) {
6196        ContentProviderRecord cpr;
6197        ContentProviderConnection conn = null;
6198        ProviderInfo cpi = null;
6199
6200        synchronized(this) {
6201            ProcessRecord r = null;
6202            if (caller != null) {
6203                r = getRecordForAppLocked(caller);
6204                if (r == null) {
6205                    throw new SecurityException(
6206                            "Unable to find app for caller " + caller
6207                          + " (pid=" + Binder.getCallingPid()
6208                          + ") when getting content provider " + name);
6209                }
6210            }
6211
6212            // First check if this content provider has been published...
6213            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6214            cpr = mProviderMap.getProviderByName(name, userId);
6215            boolean providerRunning = cpr != null;
6216            if (providerRunning) {
6217                cpi = cpr.info;
6218                String msg;
6219                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6220                    throw new SecurityException(msg);
6221                }
6222
6223                if (r != null && cpr.canRunHere(r)) {
6224                    // This provider has been published or is in the process
6225                    // of being published...  but it is also allowed to run
6226                    // in the caller's process, so don't make a connection
6227                    // and just let the caller instantiate its own instance.
6228                    ContentProviderHolder holder = cpr.newHolder(null);
6229                    // don't give caller the provider object, it needs
6230                    // to make its own.
6231                    holder.provider = null;
6232                    return holder;
6233                }
6234
6235                final long origId = Binder.clearCallingIdentity();
6236
6237                // In this case the provider instance already exists, so we can
6238                // return it right away.
6239                conn = incProviderCountLocked(r, cpr, token, stable);
6240                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6241                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6242                        // If this is a perceptible app accessing the provider,
6243                        // make sure to count it as being accessed and thus
6244                        // back up on the LRU list.  This is good because
6245                        // content providers are often expensive to start.
6246                        updateLruProcessLocked(cpr.proc, false, true);
6247                    }
6248                }
6249
6250                if (cpr.proc != null) {
6251                    if (false) {
6252                        if (cpr.name.flattenToShortString().equals(
6253                                "com.android.providers.calendar/.CalendarProvider2")) {
6254                            Slog.v(TAG, "****************** KILLING "
6255                                + cpr.name.flattenToShortString());
6256                            Process.killProcess(cpr.proc.pid);
6257                        }
6258                    }
6259                    boolean success = updateOomAdjLocked(cpr.proc);
6260                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6261                    // NOTE: there is still a race here where a signal could be
6262                    // pending on the process even though we managed to update its
6263                    // adj level.  Not sure what to do about this, but at least
6264                    // the race is now smaller.
6265                    if (!success) {
6266                        // Uh oh...  it looks like the provider's process
6267                        // has been killed on us.  We need to wait for a new
6268                        // process to be started, and make sure its death
6269                        // doesn't kill our process.
6270                        Slog.i(TAG,
6271                                "Existing provider " + cpr.name.flattenToShortString()
6272                                + " is crashing; detaching " + r);
6273                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6274                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6275                        if (!lastRef) {
6276                            // This wasn't the last ref our process had on
6277                            // the provider...  we have now been killed, bail.
6278                            return null;
6279                        }
6280                        providerRunning = false;
6281                        conn = null;
6282                    }
6283                }
6284
6285                Binder.restoreCallingIdentity(origId);
6286            }
6287
6288            if (!providerRunning) {
6289                try {
6290                    cpi = AppGlobals.getPackageManager().
6291                        resolveContentProvider(name,
6292                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6293                } catch (RemoteException ex) {
6294                }
6295                if (cpi == null) {
6296                    return null;
6297                }
6298                if (isSingleton(cpi.processName, cpi.applicationInfo)) {
6299                    userId = 0;
6300                }
6301                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6302
6303                String msg;
6304                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6305                    throw new SecurityException(msg);
6306                }
6307
6308                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6309                        && !cpi.processName.equals("system")) {
6310                    // If this content provider does not run in the system
6311                    // process, and the system is not yet ready to run other
6312                    // processes, then fail fast instead of hanging.
6313                    throw new IllegalArgumentException(
6314                            "Attempt to launch content provider before system ready");
6315                }
6316
6317                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6318                cpr = mProviderMap.getProviderByClass(comp, userId);
6319                final boolean firstClass = cpr == null;
6320                if (firstClass) {
6321                    try {
6322                        ApplicationInfo ai =
6323                            AppGlobals.getPackageManager().
6324                                getApplicationInfo(
6325                                        cpi.applicationInfo.packageName,
6326                                        STOCK_PM_FLAGS, userId);
6327                        if (ai == null) {
6328                            Slog.w(TAG, "No package info for content provider "
6329                                    + cpi.name);
6330                            return null;
6331                        }
6332                        ai = getAppInfoForUser(ai, userId);
6333                        cpr = new ContentProviderRecord(this, cpi, ai, comp);
6334                    } catch (RemoteException ex) {
6335                        // pm is in same process, this will never happen.
6336                    }
6337                }
6338
6339                if (r != null && cpr.canRunHere(r)) {
6340                    // If this is a multiprocess provider, then just return its
6341                    // info and allow the caller to instantiate it.  Only do
6342                    // this if the provider is the same user as the caller's
6343                    // process, or can run as root (so can be in any process).
6344                    return cpr.newHolder(null);
6345                }
6346
6347                if (DEBUG_PROVIDER) {
6348                    RuntimeException e = new RuntimeException("here");
6349                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6350                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6351                }
6352
6353                // This is single process, and our app is now connecting to it.
6354                // See if we are already in the process of launching this
6355                // provider.
6356                final int N = mLaunchingProviders.size();
6357                int i;
6358                for (i=0; i<N; i++) {
6359                    if (mLaunchingProviders.get(i) == cpr) {
6360                        break;
6361                    }
6362                }
6363
6364                // If the provider is not already being launched, then get it
6365                // started.
6366                if (i >= N) {
6367                    final long origId = Binder.clearCallingIdentity();
6368
6369                    try {
6370                        // Content provider is now in use, its package can't be stopped.
6371                        try {
6372                            AppGlobals.getPackageManager().setPackageStoppedState(
6373                                    cpr.appInfo.packageName, false, userId);
6374                        } catch (RemoteException e) {
6375                        } catch (IllegalArgumentException e) {
6376                            Slog.w(TAG, "Failed trying to unstop package "
6377                                    + cpr.appInfo.packageName + ": " + e);
6378                        }
6379
6380                        ProcessRecord proc = startProcessLocked(cpi.processName,
6381                                cpr.appInfo, false, 0, "content provider",
6382                                new ComponentName(cpi.applicationInfo.packageName,
6383                                        cpi.name), false, false);
6384                        if (proc == null) {
6385                            Slog.w(TAG, "Unable to launch app "
6386                                    + cpi.applicationInfo.packageName + "/"
6387                                    + cpi.applicationInfo.uid + " for provider "
6388                                    + name + ": process is bad");
6389                            return null;
6390                        }
6391                        cpr.launchingApp = proc;
6392                        mLaunchingProviders.add(cpr);
6393                    } finally {
6394                        Binder.restoreCallingIdentity(origId);
6395                    }
6396                }
6397
6398                // Make sure the provider is published (the same provider class
6399                // may be published under multiple names).
6400                if (firstClass) {
6401                    mProviderMap.putProviderByClass(comp, cpr);
6402                }
6403
6404                mProviderMap.putProviderByName(name, cpr);
6405                conn = incProviderCountLocked(r, cpr, token, stable);
6406                if (conn != null) {
6407                    conn.waiting = true;
6408                }
6409            }
6410        }
6411
6412        // Wait for the provider to be published...
6413        synchronized (cpr) {
6414            while (cpr.provider == null) {
6415                if (cpr.launchingApp == null) {
6416                    Slog.w(TAG, "Unable to launch app "
6417                            + cpi.applicationInfo.packageName + "/"
6418                            + cpi.applicationInfo.uid + " for provider "
6419                            + name + ": launching app became null");
6420                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6421                            cpi.applicationInfo.packageName,
6422                            cpi.applicationInfo.uid, name);
6423                    return null;
6424                }
6425                try {
6426                    if (DEBUG_MU) {
6427                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6428                                + cpr.launchingApp);
6429                    }
6430                    if (conn != null) {
6431                        conn.waiting = true;
6432                    }
6433                    cpr.wait();
6434                } catch (InterruptedException ex) {
6435                } finally {
6436                    if (conn != null) {
6437                        conn.waiting = false;
6438                    }
6439                }
6440            }
6441        }
6442        return cpr != null ? cpr.newHolder(conn) : null;
6443    }
6444
6445    public final ContentProviderHolder getContentProvider(
6446            IApplicationThread caller, String name, boolean stable) {
6447        enforceNotIsolatedCaller("getContentProvider");
6448        if (caller == null) {
6449            String msg = "null IApplicationThread when getting content provider "
6450                    + name;
6451            Slog.w(TAG, msg);
6452            throw new SecurityException(msg);
6453        }
6454
6455        return getContentProviderImpl(caller, name, null, stable);
6456    }
6457
6458    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6459        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6460            "Do not have permission in call getContentProviderExternal()");
6461        return getContentProviderExternalUnchecked(name, token);
6462    }
6463
6464    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6465        return getContentProviderImpl(null, name, token, true);
6466    }
6467
6468    /**
6469     * Drop a content provider from a ProcessRecord's bookkeeping
6470     * @param cpr
6471     */
6472    public void removeContentProvider(IBinder connection, boolean stable) {
6473        enforceNotIsolatedCaller("removeContentProvider");
6474        synchronized (this) {
6475            ContentProviderConnection conn;
6476            try {
6477                conn = (ContentProviderConnection)connection;
6478            } catch (ClassCastException e) {
6479                String msg ="removeContentProvider: " + connection
6480                        + " not a ContentProviderConnection";
6481                Slog.w(TAG, msg);
6482                throw new IllegalArgumentException(msg);
6483            }
6484            if (conn == null) {
6485                throw new NullPointerException("connection is null");
6486            }
6487            if (decProviderCountLocked(conn, null, null, stable)) {
6488                updateOomAdjLocked();
6489            }
6490        }
6491    }
6492
6493    public void removeContentProviderExternal(String name, IBinder token) {
6494        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6495            "Do not have permission in call removeContentProviderExternal()");
6496        removeContentProviderExternalUnchecked(name, token);
6497    }
6498
6499    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6500        synchronized (this) {
6501            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6502                    Binder.getOrigCallingUser());
6503            if(cpr == null) {
6504                //remove from mProvidersByClass
6505                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6506                return;
6507            }
6508
6509            //update content provider record entry info
6510            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6511            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6512                    Binder.getOrigCallingUser());
6513            if (localCpr.hasExternalProcessHandles()) {
6514                if (localCpr.removeExternalProcessHandleLocked(token)) {
6515                    updateOomAdjLocked();
6516                } else {
6517                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6518                            + " with no external reference for token: "
6519                            + token + ".");
6520                }
6521            } else {
6522                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6523                        + " with no external references.");
6524            }
6525        }
6526    }
6527
6528    public final void publishContentProviders(IApplicationThread caller,
6529            List<ContentProviderHolder> providers) {
6530        if (providers == null) {
6531            return;
6532        }
6533
6534        enforceNotIsolatedCaller("publishContentProviders");
6535        synchronized (this) {
6536            final ProcessRecord r = getRecordForAppLocked(caller);
6537            if (DEBUG_MU)
6538                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6539            if (r == null) {
6540                throw new SecurityException(
6541                        "Unable to find app for caller " + caller
6542                      + " (pid=" + Binder.getCallingPid()
6543                      + ") when publishing content providers");
6544            }
6545
6546            final long origId = Binder.clearCallingIdentity();
6547
6548            final int N = providers.size();
6549            for (int i=0; i<N; i++) {
6550                ContentProviderHolder src = providers.get(i);
6551                if (src == null || src.info == null || src.provider == null) {
6552                    continue;
6553                }
6554                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6555                if (DEBUG_MU)
6556                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6557                if (dst != null) {
6558                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6559                    mProviderMap.putProviderByClass(comp, dst);
6560                    String names[] = dst.info.authority.split(";");
6561                    for (int j = 0; j < names.length; j++) {
6562                        mProviderMap.putProviderByName(names[j], dst);
6563                    }
6564
6565                    int NL = mLaunchingProviders.size();
6566                    int j;
6567                    for (j=0; j<NL; j++) {
6568                        if (mLaunchingProviders.get(j) == dst) {
6569                            mLaunchingProviders.remove(j);
6570                            j--;
6571                            NL--;
6572                        }
6573                    }
6574                    synchronized (dst) {
6575                        dst.provider = src.provider;
6576                        dst.proc = r;
6577                        dst.notifyAll();
6578                    }
6579                    updateOomAdjLocked(r);
6580                }
6581            }
6582
6583            Binder.restoreCallingIdentity(origId);
6584        }
6585    }
6586
6587    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6588        ContentProviderConnection conn;
6589        try {
6590            conn = (ContentProviderConnection)connection;
6591        } catch (ClassCastException e) {
6592            String msg ="refContentProvider: " + connection
6593                    + " not a ContentProviderConnection";
6594            Slog.w(TAG, msg);
6595            throw new IllegalArgumentException(msg);
6596        }
6597        if (conn == null) {
6598            throw new NullPointerException("connection is null");
6599        }
6600
6601        synchronized (this) {
6602            if (stable > 0) {
6603                conn.numStableIncs += stable;
6604            }
6605            stable = conn.stableCount + stable;
6606            if (stable < 0) {
6607                throw new IllegalStateException("stableCount < 0: " + stable);
6608            }
6609
6610            if (unstable > 0) {
6611                conn.numUnstableIncs += unstable;
6612            }
6613            unstable = conn.unstableCount + unstable;
6614            if (unstable < 0) {
6615                throw new IllegalStateException("unstableCount < 0: " + unstable);
6616            }
6617
6618            if ((stable+unstable) <= 0) {
6619                throw new IllegalStateException("ref counts can't go to zero here: stable="
6620                        + stable + " unstable=" + unstable);
6621            }
6622            conn.stableCount = stable;
6623            conn.unstableCount = unstable;
6624            return !conn.dead;
6625        }
6626    }
6627
6628    public void unstableProviderDied(IBinder connection) {
6629        ContentProviderConnection conn;
6630        try {
6631            conn = (ContentProviderConnection)connection;
6632        } catch (ClassCastException e) {
6633            String msg ="refContentProvider: " + connection
6634                    + " not a ContentProviderConnection";
6635            Slog.w(TAG, msg);
6636            throw new IllegalArgumentException(msg);
6637        }
6638        if (conn == null) {
6639            throw new NullPointerException("connection is null");
6640        }
6641
6642        // Safely retrieve the content provider associated with the connection.
6643        IContentProvider provider;
6644        synchronized (this) {
6645            provider = conn.provider.provider;
6646        }
6647
6648        if (provider == null) {
6649            // Um, yeah, we're way ahead of you.
6650            return;
6651        }
6652
6653        // Make sure the caller is being honest with us.
6654        if (provider.asBinder().pingBinder()) {
6655            // Er, no, still looks good to us.
6656            synchronized (this) {
6657                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6658                        + " says " + conn + " died, but we don't agree");
6659                return;
6660            }
6661        }
6662
6663        // Well look at that!  It's dead!
6664        synchronized (this) {
6665            if (conn.provider.provider != provider) {
6666                // But something changed...  good enough.
6667                return;
6668            }
6669
6670            ProcessRecord proc = conn.provider.proc;
6671            if (proc == null || proc.thread == null) {
6672                // Seems like the process is already cleaned up.
6673                return;
6674            }
6675
6676            // As far as we're concerned, this is just like receiving a
6677            // death notification...  just a bit prematurely.
6678            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6679                    + ") early provider death");
6680            final long ident = Binder.clearCallingIdentity();
6681            try {
6682                appDiedLocked(proc, proc.pid, proc.thread);
6683            } finally {
6684                Binder.restoreCallingIdentity(ident);
6685            }
6686        }
6687    }
6688
6689    public static final void installSystemProviders() {
6690        List<ProviderInfo> providers;
6691        synchronized (mSelf) {
6692            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6693            providers = mSelf.generateApplicationProvidersLocked(app);
6694            if (providers != null) {
6695                for (int i=providers.size()-1; i>=0; i--) {
6696                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6697                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6698                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6699                                + ": not system .apk");
6700                        providers.remove(i);
6701                    }
6702                }
6703            }
6704        }
6705        if (providers != null) {
6706            mSystemThread.installSystemProviders(providers);
6707        }
6708
6709        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6710
6711        mSelf.mUsageStatsService.monitorPackages();
6712    }
6713
6714    /**
6715     * Allows app to retrieve the MIME type of a URI without having permission
6716     * to access its content provider.
6717     *
6718     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6719     *
6720     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6721     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6722     */
6723    public String getProviderMimeType(Uri uri) {
6724        enforceNotIsolatedCaller("getProviderMimeType");
6725        final String name = uri.getAuthority();
6726        final long ident = Binder.clearCallingIdentity();
6727        ContentProviderHolder holder = null;
6728
6729        try {
6730            holder = getContentProviderExternalUnchecked(name, null);
6731            if (holder != null) {
6732                return holder.provider.getType(uri);
6733            }
6734        } catch (RemoteException e) {
6735            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6736            return null;
6737        } finally {
6738            if (holder != null) {
6739                removeContentProviderExternalUnchecked(name, null);
6740            }
6741            Binder.restoreCallingIdentity(ident);
6742        }
6743
6744        return null;
6745    }
6746
6747    // =========================================================
6748    // GLOBAL MANAGEMENT
6749    // =========================================================
6750
6751    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6752            ApplicationInfo info, String customProcess, boolean isolated) {
6753        String proc = customProcess != null ? customProcess : info.processName;
6754        BatteryStatsImpl.Uid.Proc ps = null;
6755        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6756        int uid = info.uid;
6757        if (isolated) {
6758            int userId = UserId.getUserId(uid);
6759            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6760            uid = 0;
6761            while (true) {
6762                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6763                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6764                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6765                }
6766                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6767                mNextIsolatedProcessUid++;
6768                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6769                    // No process for this uid, use it.
6770                    break;
6771                }
6772                stepsLeft--;
6773                if (stepsLeft <= 0) {
6774                    return null;
6775                }
6776            }
6777        }
6778        synchronized (stats) {
6779            ps = stats.getProcessStatsLocked(info.uid, proc);
6780        }
6781        return new ProcessRecord(ps, thread, info, proc, uid);
6782    }
6783
6784    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6785        ProcessRecord app;
6786        if (!isolated) {
6787            app = getProcessRecordLocked(info.processName, info.uid);
6788        } else {
6789            app = null;
6790        }
6791
6792        if (app == null) {
6793            app = newProcessRecordLocked(null, info, null, isolated);
6794            mProcessNames.put(info.processName, app.uid, app);
6795            if (isolated) {
6796                mIsolatedProcesses.put(app.uid, app);
6797            }
6798            updateLruProcessLocked(app, true, true);
6799        }
6800
6801        // This package really, really can not be stopped.
6802        try {
6803            AppGlobals.getPackageManager().setPackageStoppedState(
6804                    info.packageName, false, UserId.getUserId(app.uid));
6805        } catch (RemoteException e) {
6806        } catch (IllegalArgumentException e) {
6807            Slog.w(TAG, "Failed trying to unstop package "
6808                    + info.packageName + ": " + e);
6809        }
6810
6811        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6812                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6813            app.persistent = true;
6814            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6815        }
6816        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6817            mPersistentStartingProcesses.add(app);
6818            startProcessLocked(app, "added application", app.processName);
6819        }
6820
6821        return app;
6822    }
6823
6824    public void unhandledBack() {
6825        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6826                "unhandledBack()");
6827
6828        synchronized(this) {
6829            int count = mMainStack.mHistory.size();
6830            if (DEBUG_SWITCH) Slog.d(
6831                TAG, "Performing unhandledBack(): stack size = " + count);
6832            if (count > 1) {
6833                final long origId = Binder.clearCallingIdentity();
6834                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6835                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6836                Binder.restoreCallingIdentity(origId);
6837            }
6838        }
6839    }
6840
6841    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6842        enforceNotIsolatedCaller("openContentUri");
6843        String name = uri.getAuthority();
6844        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6845        ParcelFileDescriptor pfd = null;
6846        if (cph != null) {
6847            // We record the binder invoker's uid in thread-local storage before
6848            // going to the content provider to open the file.  Later, in the code
6849            // that handles all permissions checks, we look for this uid and use
6850            // that rather than the Activity Manager's own uid.  The effect is that
6851            // we do the check against the caller's permissions even though it looks
6852            // to the content provider like the Activity Manager itself is making
6853            // the request.
6854            sCallerIdentity.set(new Identity(
6855                    Binder.getCallingPid(), Binder.getCallingUid()));
6856            try {
6857                pfd = cph.provider.openFile(uri, "r");
6858            } catch (FileNotFoundException e) {
6859                // do nothing; pfd will be returned null
6860            } finally {
6861                // Ensure that whatever happens, we clean up the identity state
6862                sCallerIdentity.remove();
6863            }
6864
6865            // We've got the fd now, so we're done with the provider.
6866            removeContentProviderExternalUnchecked(name, null);
6867        } else {
6868            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6869        }
6870        return pfd;
6871    }
6872
6873    // Actually is sleeping or shutting down or whatever else in the future
6874    // is an inactive state.
6875    public boolean isSleeping() {
6876        return mSleeping || mShuttingDown;
6877    }
6878
6879    public void goingToSleep() {
6880        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6881                != PackageManager.PERMISSION_GRANTED) {
6882            throw new SecurityException("Requires permission "
6883                    + android.Manifest.permission.DEVICE_POWER);
6884        }
6885
6886        synchronized(this) {
6887            mWentToSleep = true;
6888            updateEventDispatchingLocked();
6889
6890            if (!mSleeping) {
6891                mSleeping = true;
6892                mMainStack.stopIfSleepingLocked();
6893
6894                // Initialize the wake times of all processes.
6895                checkExcessivePowerUsageLocked(false);
6896                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6897                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6898                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6899            }
6900        }
6901    }
6902
6903    public boolean shutdown(int timeout) {
6904        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6905                != PackageManager.PERMISSION_GRANTED) {
6906            throw new SecurityException("Requires permission "
6907                    + android.Manifest.permission.SHUTDOWN);
6908        }
6909
6910        boolean timedout = false;
6911
6912        synchronized(this) {
6913            mShuttingDown = true;
6914            updateEventDispatchingLocked();
6915
6916            if (mMainStack.mResumedActivity != null) {
6917                mMainStack.stopIfSleepingLocked();
6918                final long endTime = System.currentTimeMillis() + timeout;
6919                while (mMainStack.mResumedActivity != null
6920                        || mMainStack.mPausingActivity != null) {
6921                    long delay = endTime - System.currentTimeMillis();
6922                    if (delay <= 0) {
6923                        Slog.w(TAG, "Activity manager shutdown timed out");
6924                        timedout = true;
6925                        break;
6926                    }
6927                    try {
6928                        this.wait();
6929                    } catch (InterruptedException e) {
6930                    }
6931                }
6932            }
6933        }
6934
6935        mUsageStatsService.shutdown();
6936        mBatteryStatsService.shutdown();
6937
6938        return timedout;
6939    }
6940
6941    public final void activitySlept(IBinder token) {
6942        if (localLOGV) Slog.v(
6943            TAG, "Activity slept: token=" + token);
6944
6945        ActivityRecord r = null;
6946
6947        final long origId = Binder.clearCallingIdentity();
6948
6949        synchronized (this) {
6950            r = mMainStack.isInStackLocked(token);
6951            if (r != null) {
6952                mMainStack.activitySleptLocked(r);
6953            }
6954        }
6955
6956        Binder.restoreCallingIdentity(origId);
6957    }
6958
6959    private void comeOutOfSleepIfNeededLocked() {
6960        if (!mWentToSleep && !mLockScreenShown) {
6961            if (mSleeping) {
6962                mSleeping = false;
6963                mMainStack.awakeFromSleepingLocked();
6964                mMainStack.resumeTopActivityLocked(null);
6965            }
6966        }
6967    }
6968
6969    public void wakingUp() {
6970        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6971                != PackageManager.PERMISSION_GRANTED) {
6972            throw new SecurityException("Requires permission "
6973                    + android.Manifest.permission.DEVICE_POWER);
6974        }
6975
6976        synchronized(this) {
6977            mWentToSleep = false;
6978            updateEventDispatchingLocked();
6979            comeOutOfSleepIfNeededLocked();
6980        }
6981    }
6982
6983    private void updateEventDispatchingLocked() {
6984        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6985    }
6986
6987    public void setLockScreenShown(boolean shown) {
6988        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6989                != PackageManager.PERMISSION_GRANTED) {
6990            throw new SecurityException("Requires permission "
6991                    + android.Manifest.permission.DEVICE_POWER);
6992        }
6993
6994        synchronized(this) {
6995            mLockScreenShown = shown;
6996            comeOutOfSleepIfNeededLocked();
6997        }
6998    }
6999
7000    public void stopAppSwitches() {
7001        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7002                != PackageManager.PERMISSION_GRANTED) {
7003            throw new SecurityException("Requires permission "
7004                    + android.Manifest.permission.STOP_APP_SWITCHES);
7005        }
7006
7007        synchronized(this) {
7008            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7009                    + APP_SWITCH_DELAY_TIME;
7010            mDidAppSwitch = false;
7011            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7012            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7013            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7014        }
7015    }
7016
7017    public void resumeAppSwitches() {
7018        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7019                != PackageManager.PERMISSION_GRANTED) {
7020            throw new SecurityException("Requires permission "
7021                    + android.Manifest.permission.STOP_APP_SWITCHES);
7022        }
7023
7024        synchronized(this) {
7025            // Note that we don't execute any pending app switches... we will
7026            // let those wait until either the timeout, or the next start
7027            // activity request.
7028            mAppSwitchesAllowedTime = 0;
7029        }
7030    }
7031
7032    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7033            String name) {
7034        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7035            return true;
7036        }
7037
7038        final int perm = checkComponentPermission(
7039                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7040                callingUid, -1, true);
7041        if (perm == PackageManager.PERMISSION_GRANTED) {
7042            return true;
7043        }
7044
7045        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7046        return false;
7047    }
7048
7049    public void setDebugApp(String packageName, boolean waitForDebugger,
7050            boolean persistent) {
7051        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7052                "setDebugApp()");
7053
7054        // Note that this is not really thread safe if there are multiple
7055        // callers into it at the same time, but that's not a situation we
7056        // care about.
7057        if (persistent) {
7058            final ContentResolver resolver = mContext.getContentResolver();
7059            Settings.System.putString(
7060                resolver, Settings.System.DEBUG_APP,
7061                packageName);
7062            Settings.System.putInt(
7063                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7064                waitForDebugger ? 1 : 0);
7065        }
7066
7067        synchronized (this) {
7068            if (!persistent) {
7069                mOrigDebugApp = mDebugApp;
7070                mOrigWaitForDebugger = mWaitForDebugger;
7071            }
7072            mDebugApp = packageName;
7073            mWaitForDebugger = waitForDebugger;
7074            mDebugTransient = !persistent;
7075            if (packageName != null) {
7076                final long origId = Binder.clearCallingIdentity();
7077                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7078                Binder.restoreCallingIdentity(origId);
7079            }
7080        }
7081    }
7082
7083    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7084        synchronized (this) {
7085            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7086            if (!isDebuggable) {
7087                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7088                    throw new SecurityException("Process not debuggable: " + app.packageName);
7089                }
7090            }
7091
7092            mOpenGlTraceApp = processName;
7093        }
7094    }
7095
7096    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7097            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7098        synchronized (this) {
7099            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7100            if (!isDebuggable) {
7101                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7102                    throw new SecurityException("Process not debuggable: " + app.packageName);
7103                }
7104            }
7105            mProfileApp = processName;
7106            mProfileFile = profileFile;
7107            if (mProfileFd != null) {
7108                try {
7109                    mProfileFd.close();
7110                } catch (IOException e) {
7111                }
7112                mProfileFd = null;
7113            }
7114            mProfileFd = profileFd;
7115            mProfileType = 0;
7116            mAutoStopProfiler = autoStopProfiler;
7117        }
7118    }
7119
7120    public void setAlwaysFinish(boolean enabled) {
7121        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7122                "setAlwaysFinish()");
7123
7124        Settings.System.putInt(
7125                mContext.getContentResolver(),
7126                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7127
7128        synchronized (this) {
7129            mAlwaysFinishActivities = enabled;
7130        }
7131    }
7132
7133    public void setActivityController(IActivityController controller) {
7134        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7135                "setActivityController()");
7136        synchronized (this) {
7137            mController = controller;
7138        }
7139    }
7140
7141    public boolean isUserAMonkey() {
7142        // For now the fact that there is a controller implies
7143        // we have a monkey.
7144        synchronized (this) {
7145            return mController != null;
7146        }
7147    }
7148
7149    public void registerProcessObserver(IProcessObserver observer) {
7150        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7151                "registerProcessObserver()");
7152        synchronized (this) {
7153            mProcessObservers.register(observer);
7154        }
7155    }
7156
7157    public void unregisterProcessObserver(IProcessObserver observer) {
7158        synchronized (this) {
7159            mProcessObservers.unregister(observer);
7160        }
7161    }
7162
7163    public void setImmersive(IBinder token, boolean immersive) {
7164        synchronized(this) {
7165            ActivityRecord r = mMainStack.isInStackLocked(token);
7166            if (r == null) {
7167                throw new IllegalArgumentException();
7168            }
7169            r.immersive = immersive;
7170        }
7171    }
7172
7173    public boolean isImmersive(IBinder token) {
7174        synchronized (this) {
7175            ActivityRecord r = mMainStack.isInStackLocked(token);
7176            if (r == null) {
7177                throw new IllegalArgumentException();
7178            }
7179            return r.immersive;
7180        }
7181    }
7182
7183    public boolean isTopActivityImmersive() {
7184        enforceNotIsolatedCaller("startActivity");
7185        synchronized (this) {
7186            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7187            return (r != null) ? r.immersive : false;
7188        }
7189    }
7190
7191    public final void enterSafeMode() {
7192        synchronized(this) {
7193            // It only makes sense to do this before the system is ready
7194            // and started launching other packages.
7195            if (!mSystemReady) {
7196                try {
7197                    AppGlobals.getPackageManager().enterSafeMode();
7198                } catch (RemoteException e) {
7199                }
7200            }
7201        }
7202    }
7203
7204    public final void showSafeModeOverlay() {
7205        View v = LayoutInflater.from(mContext).inflate(
7206                com.android.internal.R.layout.safe_mode, null);
7207        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7208        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7209        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7210        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7211        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7212        lp.format = v.getBackground().getOpacity();
7213        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7214                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7215        ((WindowManager)mContext.getSystemService(
7216                Context.WINDOW_SERVICE)).addView(v, lp);
7217    }
7218
7219    public void noteWakeupAlarm(IIntentSender sender) {
7220        if (!(sender instanceof PendingIntentRecord)) {
7221            return;
7222        }
7223        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7224        synchronized (stats) {
7225            if (mBatteryStatsService.isOnBattery()) {
7226                mBatteryStatsService.enforceCallingPermission();
7227                PendingIntentRecord rec = (PendingIntentRecord)sender;
7228                int MY_UID = Binder.getCallingUid();
7229                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7230                BatteryStatsImpl.Uid.Pkg pkg =
7231                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7232                pkg.incWakeupsLocked();
7233            }
7234        }
7235    }
7236
7237    public boolean killPids(int[] pids, String pReason, boolean secure) {
7238        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7239            throw new SecurityException("killPids only available to the system");
7240        }
7241        String reason = (pReason == null) ? "Unknown" : pReason;
7242        // XXX Note: don't acquire main activity lock here, because the window
7243        // manager calls in with its locks held.
7244
7245        boolean killed = false;
7246        synchronized (mPidsSelfLocked) {
7247            int[] types = new int[pids.length];
7248            int worstType = 0;
7249            for (int i=0; i<pids.length; i++) {
7250                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7251                if (proc != null) {
7252                    int type = proc.setAdj;
7253                    types[i] = type;
7254                    if (type > worstType) {
7255                        worstType = type;
7256                    }
7257                }
7258            }
7259
7260            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7261            // then constrain it so we will kill all hidden procs.
7262            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7263                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7264                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7265            }
7266
7267            // If this is not a secure call, don't let it kill processes that
7268            // are important.
7269            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7270                worstType = ProcessList.SERVICE_ADJ;
7271            }
7272
7273            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7274            for (int i=0; i<pids.length; i++) {
7275                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7276                if (proc == null) {
7277                    continue;
7278                }
7279                int adj = proc.setAdj;
7280                if (adj >= worstType && !proc.killedBackground) {
7281                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7282                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7283                            proc.processName, adj, reason);
7284                    killed = true;
7285                    proc.killedBackground = true;
7286                    Process.killProcessQuiet(pids[i]);
7287                }
7288            }
7289        }
7290        return killed;
7291    }
7292
7293    @Override
7294    public boolean killProcessesBelowForeground(String reason) {
7295        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7296            throw new SecurityException("killProcessesBelowForeground() only available to system");
7297        }
7298
7299        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7300    }
7301
7302    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7303        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7304            throw new SecurityException("killProcessesBelowAdj() only available to system");
7305        }
7306
7307        boolean killed = false;
7308        synchronized (mPidsSelfLocked) {
7309            final int size = mPidsSelfLocked.size();
7310            for (int i = 0; i < size; i++) {
7311                final int pid = mPidsSelfLocked.keyAt(i);
7312                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7313                if (proc == null) continue;
7314
7315                final int adj = proc.setAdj;
7316                if (adj > belowAdj && !proc.killedBackground) {
7317                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7318                    EventLog.writeEvent(
7319                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7320                    killed = true;
7321                    proc.killedBackground = true;
7322                    Process.killProcessQuiet(pid);
7323                }
7324            }
7325        }
7326        return killed;
7327    }
7328
7329    public final void startRunning(String pkg, String cls, String action,
7330            String data) {
7331        synchronized(this) {
7332            if (mStartRunning) {
7333                return;
7334            }
7335            mStartRunning = true;
7336            mTopComponent = pkg != null && cls != null
7337                    ? new ComponentName(pkg, cls) : null;
7338            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7339            mTopData = data;
7340            if (!mSystemReady) {
7341                return;
7342            }
7343        }
7344
7345        systemReady(null);
7346    }
7347
7348    private void retrieveSettings() {
7349        final ContentResolver resolver = mContext.getContentResolver();
7350        String debugApp = Settings.System.getString(
7351            resolver, Settings.System.DEBUG_APP);
7352        boolean waitForDebugger = Settings.System.getInt(
7353            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7354        boolean alwaysFinishActivities = Settings.System.getInt(
7355            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7356
7357        Configuration configuration = new Configuration();
7358        Settings.System.getConfiguration(resolver, configuration);
7359
7360        synchronized (this) {
7361            mDebugApp = mOrigDebugApp = debugApp;
7362            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7363            mAlwaysFinishActivities = alwaysFinishActivities;
7364            // This happens before any activities are started, so we can
7365            // change mConfiguration in-place.
7366            updateConfigurationLocked(configuration, null, false, true);
7367            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7368        }
7369    }
7370
7371    public boolean testIsSystemReady() {
7372        // no need to synchronize(this) just to read & return the value
7373        return mSystemReady;
7374    }
7375
7376    private static File getCalledPreBootReceiversFile() {
7377        File dataDir = Environment.getDataDirectory();
7378        File systemDir = new File(dataDir, "system");
7379        File fname = new File(systemDir, "called_pre_boots.dat");
7380        return fname;
7381    }
7382
7383    static final int LAST_DONE_VERSION = 10000;
7384
7385    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7386        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7387        File file = getCalledPreBootReceiversFile();
7388        FileInputStream fis = null;
7389        try {
7390            fis = new FileInputStream(file);
7391            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7392            int fvers = dis.readInt();
7393            if (fvers == LAST_DONE_VERSION) {
7394                String vers = dis.readUTF();
7395                String codename = dis.readUTF();
7396                String build = dis.readUTF();
7397                if (android.os.Build.VERSION.RELEASE.equals(vers)
7398                        && android.os.Build.VERSION.CODENAME.equals(codename)
7399                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7400                    int num = dis.readInt();
7401                    while (num > 0) {
7402                        num--;
7403                        String pkg = dis.readUTF();
7404                        String cls = dis.readUTF();
7405                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7406                    }
7407                }
7408            }
7409        } catch (FileNotFoundException e) {
7410        } catch (IOException e) {
7411            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7412        } finally {
7413            if (fis != null) {
7414                try {
7415                    fis.close();
7416                } catch (IOException e) {
7417                }
7418            }
7419        }
7420        return lastDoneReceivers;
7421    }
7422
7423    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7424        File file = getCalledPreBootReceiversFile();
7425        FileOutputStream fos = null;
7426        DataOutputStream dos = null;
7427        try {
7428            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7429            fos = new FileOutputStream(file);
7430            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7431            dos.writeInt(LAST_DONE_VERSION);
7432            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7433            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7434            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7435            dos.writeInt(list.size());
7436            for (int i=0; i<list.size(); i++) {
7437                dos.writeUTF(list.get(i).getPackageName());
7438                dos.writeUTF(list.get(i).getClassName());
7439            }
7440        } catch (IOException e) {
7441            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7442            file.delete();
7443        } finally {
7444            FileUtils.sync(fos);
7445            if (dos != null) {
7446                try {
7447                    dos.close();
7448                } catch (IOException e) {
7449                    // TODO Auto-generated catch block
7450                    e.printStackTrace();
7451                }
7452            }
7453        }
7454    }
7455
7456    public void systemReady(final Runnable goingCallback) {
7457        synchronized(this) {
7458            if (mSystemReady) {
7459                if (goingCallback != null) goingCallback.run();
7460                return;
7461            }
7462
7463            // Check to see if there are any update receivers to run.
7464            if (!mDidUpdate) {
7465                if (mWaitingUpdate) {
7466                    return;
7467                }
7468                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7469                List<ResolveInfo> ris = null;
7470                try {
7471                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7472                            intent, null, 0, 0);
7473                } catch (RemoteException e) {
7474                }
7475                if (ris != null) {
7476                    for (int i=ris.size()-1; i>=0; i--) {
7477                        if ((ris.get(i).activityInfo.applicationInfo.flags
7478                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7479                            ris.remove(i);
7480                        }
7481                    }
7482                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7483
7484                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7485
7486                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7487                    for (int i=0; i<ris.size(); i++) {
7488                        ActivityInfo ai = ris.get(i).activityInfo;
7489                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7490                        if (lastDoneReceivers.contains(comp)) {
7491                            ris.remove(i);
7492                            i--;
7493                        }
7494                    }
7495
7496                    for (int i=0; i<ris.size(); i++) {
7497                        ActivityInfo ai = ris.get(i).activityInfo;
7498                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7499                        doneReceivers.add(comp);
7500                        intent.setComponent(comp);
7501                        IIntentReceiver finisher = null;
7502                        if (i == ris.size()-1) {
7503                            finisher = new IIntentReceiver.Stub() {
7504                                public void performReceive(Intent intent, int resultCode,
7505                                        String data, Bundle extras, boolean ordered,
7506                                        boolean sticky) {
7507                                    // The raw IIntentReceiver interface is called
7508                                    // with the AM lock held, so redispatch to
7509                                    // execute our code without the lock.
7510                                    mHandler.post(new Runnable() {
7511                                        public void run() {
7512                                            synchronized (ActivityManagerService.this) {
7513                                                mDidUpdate = true;
7514                                            }
7515                                            writeLastDonePreBootReceivers(doneReceivers);
7516                                            showBootMessage(mContext.getText(
7517                                                    R.string.android_upgrading_complete),
7518                                                    false);
7519                                            systemReady(goingCallback);
7520                                        }
7521                                    });
7522                                }
7523                            };
7524                        }
7525                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7526                        /* TODO: Send this to all users */
7527                        broadcastIntentLocked(null, null, intent, null, finisher,
7528                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7529                                0 /* UserId zero */);
7530                        if (finisher != null) {
7531                            mWaitingUpdate = true;
7532                        }
7533                    }
7534                }
7535                if (mWaitingUpdate) {
7536                    return;
7537                }
7538                mDidUpdate = true;
7539            }
7540
7541            mSystemReady = true;
7542            if (!mStartRunning) {
7543                return;
7544            }
7545        }
7546
7547        ArrayList<ProcessRecord> procsToKill = null;
7548        synchronized(mPidsSelfLocked) {
7549            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7550                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7551                if (!isAllowedWhileBooting(proc.info)){
7552                    if (procsToKill == null) {
7553                        procsToKill = new ArrayList<ProcessRecord>();
7554                    }
7555                    procsToKill.add(proc);
7556                }
7557            }
7558        }
7559
7560        synchronized(this) {
7561            if (procsToKill != null) {
7562                for (int i=procsToKill.size()-1; i>=0; i--) {
7563                    ProcessRecord proc = procsToKill.get(i);
7564                    Slog.i(TAG, "Removing system update proc: " + proc);
7565                    removeProcessLocked(proc, true, false, "system update done");
7566                }
7567            }
7568
7569            // Now that we have cleaned up any update processes, we
7570            // are ready to start launching real processes and know that
7571            // we won't trample on them any more.
7572            mProcessesReady = true;
7573        }
7574
7575        Slog.i(TAG, "System now ready");
7576        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7577            SystemClock.uptimeMillis());
7578
7579        synchronized(this) {
7580            // Make sure we have no pre-ready processes sitting around.
7581
7582            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7583                ResolveInfo ri = mContext.getPackageManager()
7584                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7585                                STOCK_PM_FLAGS);
7586                CharSequence errorMsg = null;
7587                if (ri != null) {
7588                    ActivityInfo ai = ri.activityInfo;
7589                    ApplicationInfo app = ai.applicationInfo;
7590                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7591                        mTopAction = Intent.ACTION_FACTORY_TEST;
7592                        mTopData = null;
7593                        mTopComponent = new ComponentName(app.packageName,
7594                                ai.name);
7595                    } else {
7596                        errorMsg = mContext.getResources().getText(
7597                                com.android.internal.R.string.factorytest_not_system);
7598                    }
7599                } else {
7600                    errorMsg = mContext.getResources().getText(
7601                            com.android.internal.R.string.factorytest_no_action);
7602                }
7603                if (errorMsg != null) {
7604                    mTopAction = null;
7605                    mTopData = null;
7606                    mTopComponent = null;
7607                    Message msg = Message.obtain();
7608                    msg.what = SHOW_FACTORY_ERROR_MSG;
7609                    msg.getData().putCharSequence("msg", errorMsg);
7610                    mHandler.sendMessage(msg);
7611                }
7612            }
7613        }
7614
7615        retrieveSettings();
7616
7617        if (goingCallback != null) goingCallback.run();
7618
7619        synchronized (this) {
7620            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7621                try {
7622                    List apps = AppGlobals.getPackageManager().
7623                        getPersistentApplications(STOCK_PM_FLAGS);
7624                    if (apps != null) {
7625                        int N = apps.size();
7626                        int i;
7627                        for (i=0; i<N; i++) {
7628                            ApplicationInfo info
7629                                = (ApplicationInfo)apps.get(i);
7630                            if (info != null &&
7631                                    !info.packageName.equals("android")) {
7632                                addAppLocked(info, false);
7633                            }
7634                        }
7635                    }
7636                } catch (RemoteException ex) {
7637                    // pm is in same process, this will never happen.
7638                }
7639            }
7640
7641            // Start up initial activity.
7642            mBooting = true;
7643
7644            try {
7645                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7646                    Message msg = Message.obtain();
7647                    msg.what = SHOW_UID_ERROR_MSG;
7648                    mHandler.sendMessage(msg);
7649                }
7650            } catch (RemoteException e) {
7651            }
7652
7653            mMainStack.resumeTopActivityLocked(null);
7654        }
7655    }
7656
7657    private boolean makeAppCrashingLocked(ProcessRecord app,
7658            String shortMsg, String longMsg, String stackTrace) {
7659        app.crashing = true;
7660        app.crashingReport = generateProcessError(app,
7661                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7662        startAppProblemLocked(app);
7663        app.stopFreezingAllLocked();
7664        return handleAppCrashLocked(app);
7665    }
7666
7667    private void makeAppNotRespondingLocked(ProcessRecord app,
7668            String activity, String shortMsg, String longMsg) {
7669        app.notResponding = true;
7670        app.notRespondingReport = generateProcessError(app,
7671                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7672                activity, shortMsg, longMsg, null);
7673        startAppProblemLocked(app);
7674        app.stopFreezingAllLocked();
7675    }
7676
7677    /**
7678     * Generate a process error record, suitable for attachment to a ProcessRecord.
7679     *
7680     * @param app The ProcessRecord in which the error occurred.
7681     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7682     *                      ActivityManager.AppErrorStateInfo
7683     * @param activity The activity associated with the crash, if known.
7684     * @param shortMsg Short message describing the crash.
7685     * @param longMsg Long message describing the crash.
7686     * @param stackTrace Full crash stack trace, may be null.
7687     *
7688     * @return Returns a fully-formed AppErrorStateInfo record.
7689     */
7690    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7691            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7692        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7693
7694        report.condition = condition;
7695        report.processName = app.processName;
7696        report.pid = app.pid;
7697        report.uid = app.info.uid;
7698        report.tag = activity;
7699        report.shortMsg = shortMsg;
7700        report.longMsg = longMsg;
7701        report.stackTrace = stackTrace;
7702
7703        return report;
7704    }
7705
7706    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7707        synchronized (this) {
7708            app.crashing = false;
7709            app.crashingReport = null;
7710            app.notResponding = false;
7711            app.notRespondingReport = null;
7712            if (app.anrDialog == fromDialog) {
7713                app.anrDialog = null;
7714            }
7715            if (app.waitDialog == fromDialog) {
7716                app.waitDialog = null;
7717            }
7718            if (app.pid > 0 && app.pid != MY_PID) {
7719                handleAppCrashLocked(app);
7720                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7721                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7722                        app.processName, app.setAdj, "user's request after error");
7723                Process.killProcessQuiet(app.pid);
7724            }
7725        }
7726    }
7727
7728    private boolean handleAppCrashLocked(ProcessRecord app) {
7729        if (mHeadless) {
7730            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7731            return false;
7732        }
7733        long now = SystemClock.uptimeMillis();
7734
7735        Long crashTime;
7736        if (!app.isolated) {
7737            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7738        } else {
7739            crashTime = null;
7740        }
7741        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7742            // This process loses!
7743            Slog.w(TAG, "Process " + app.info.processName
7744                    + " has crashed too many times: killing!");
7745            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7746                    app.info.processName, app.uid);
7747            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7748                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7749                if (r.app == app) {
7750                    Slog.w(TAG, "  Force finishing activity "
7751                        + r.intent.getComponent().flattenToShortString());
7752                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7753                }
7754            }
7755            if (!app.persistent) {
7756                // We don't want to start this process again until the user
7757                // explicitly does so...  but for persistent process, we really
7758                // need to keep it running.  If a persistent process is actually
7759                // repeatedly crashing, then badness for everyone.
7760                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7761                        app.info.processName);
7762                if (!app.isolated) {
7763                    // XXX We don't have a way to mark isolated processes
7764                    // as bad, since they don't have a peristent identity.
7765                    mBadProcesses.put(app.info.processName, app.uid, now);
7766                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7767                }
7768                app.bad = true;
7769                app.removed = true;
7770                // Don't let services in this process be restarted and potentially
7771                // annoy the user repeatedly.  Unless it is persistent, since those
7772                // processes run critical code.
7773                removeProcessLocked(app, false, false, "crash");
7774                mMainStack.resumeTopActivityLocked(null);
7775                return false;
7776            }
7777            mMainStack.resumeTopActivityLocked(null);
7778        } else {
7779            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7780            if (r != null && r.app == app) {
7781                // If the top running activity is from this crashing
7782                // process, then terminate it to avoid getting in a loop.
7783                Slog.w(TAG, "  Force finishing activity "
7784                        + r.intent.getComponent().flattenToShortString());
7785                int index = mMainStack.indexOfActivityLocked(r);
7786                r.stack.finishActivityLocked(r, index,
7787                        Activity.RESULT_CANCELED, null, "crashed");
7788                // Also terminate any activities below it that aren't yet
7789                // stopped, to avoid a situation where one will get
7790                // re-start our crashing activity once it gets resumed again.
7791                index--;
7792                if (index >= 0) {
7793                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7794                    if (r.state == ActivityState.RESUMED
7795                            || r.state == ActivityState.PAUSING
7796                            || r.state == ActivityState.PAUSED) {
7797                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7798                            Slog.w(TAG, "  Force finishing activity "
7799                                    + r.intent.getComponent().flattenToShortString());
7800                            r.stack.finishActivityLocked(r, index,
7801                                    Activity.RESULT_CANCELED, null, "crashed");
7802                        }
7803                    }
7804                }
7805            }
7806        }
7807
7808        // Bump up the crash count of any services currently running in the proc.
7809        if (app.services.size() != 0) {
7810            // Any services running in the application need to be placed
7811            // back in the pending list.
7812            Iterator<ServiceRecord> it = app.services.iterator();
7813            while (it.hasNext()) {
7814                ServiceRecord sr = it.next();
7815                sr.crashCount++;
7816            }
7817        }
7818
7819        // If the crashing process is what we consider to be the "home process" and it has been
7820        // replaced by a third-party app, clear the package preferred activities from packages
7821        // with a home activity running in the process to prevent a repeatedly crashing app
7822        // from blocking the user to manually clear the list.
7823        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7824                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7825            Iterator it = mHomeProcess.activities.iterator();
7826            while (it.hasNext()) {
7827                ActivityRecord r = (ActivityRecord)it.next();
7828                if (r.isHomeActivity) {
7829                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7830                    try {
7831                        ActivityThread.getPackageManager()
7832                                .clearPackagePreferredActivities(r.packageName);
7833                    } catch (RemoteException c) {
7834                        // pm is in same process, this will never happen.
7835                    }
7836                }
7837            }
7838        }
7839
7840        if (!app.isolated) {
7841            // XXX Can't keep track of crash times for isolated processes,
7842            // because they don't have a perisistent identity.
7843            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7844        }
7845
7846        return true;
7847    }
7848
7849    void startAppProblemLocked(ProcessRecord app) {
7850        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7851                mContext, app.info.packageName, app.info.flags);
7852        skipCurrentReceiverLocked(app);
7853    }
7854
7855    void skipCurrentReceiverLocked(ProcessRecord app) {
7856        for (BroadcastQueue queue : mBroadcastQueues) {
7857            queue.skipCurrentReceiverLocked(app);
7858        }
7859    }
7860
7861    /**
7862     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7863     * The application process will exit immediately after this call returns.
7864     * @param app object of the crashing app, null for the system server
7865     * @param crashInfo describing the exception
7866     */
7867    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7868        ProcessRecord r = findAppProcess(app, "Crash");
7869        final String processName = app == null ? "system_server"
7870                : (r == null ? "unknown" : r.processName);
7871
7872        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7873                processName,
7874                r == null ? -1 : r.info.flags,
7875                crashInfo.exceptionClassName,
7876                crashInfo.exceptionMessage,
7877                crashInfo.throwFileName,
7878                crashInfo.throwLineNumber);
7879
7880        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7881
7882        crashApplication(r, crashInfo);
7883    }
7884
7885    public void handleApplicationStrictModeViolation(
7886            IBinder app,
7887            int violationMask,
7888            StrictMode.ViolationInfo info) {
7889        ProcessRecord r = findAppProcess(app, "StrictMode");
7890        if (r == null) {
7891            return;
7892        }
7893
7894        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7895            Integer stackFingerprint = info.hashCode();
7896            boolean logIt = true;
7897            synchronized (mAlreadyLoggedViolatedStacks) {
7898                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7899                    logIt = false;
7900                    // TODO: sub-sample into EventLog for these, with
7901                    // the info.durationMillis?  Then we'd get
7902                    // the relative pain numbers, without logging all
7903                    // the stack traces repeatedly.  We'd want to do
7904                    // likewise in the client code, which also does
7905                    // dup suppression, before the Binder call.
7906                } else {
7907                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7908                        mAlreadyLoggedViolatedStacks.clear();
7909                    }
7910                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7911                }
7912            }
7913            if (logIt) {
7914                logStrictModeViolationToDropBox(r, info);
7915            }
7916        }
7917
7918        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7919            AppErrorResult result = new AppErrorResult();
7920            synchronized (this) {
7921                final long origId = Binder.clearCallingIdentity();
7922
7923                Message msg = Message.obtain();
7924                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7925                HashMap<String, Object> data = new HashMap<String, Object>();
7926                data.put("result", result);
7927                data.put("app", r);
7928                data.put("violationMask", violationMask);
7929                data.put("info", info);
7930                msg.obj = data;
7931                mHandler.sendMessage(msg);
7932
7933                Binder.restoreCallingIdentity(origId);
7934            }
7935            int res = result.get();
7936            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7937        }
7938    }
7939
7940    // Depending on the policy in effect, there could be a bunch of
7941    // these in quick succession so we try to batch these together to
7942    // minimize disk writes, number of dropbox entries, and maximize
7943    // compression, by having more fewer, larger records.
7944    private void logStrictModeViolationToDropBox(
7945            ProcessRecord process,
7946            StrictMode.ViolationInfo info) {
7947        if (info == null) {
7948            return;
7949        }
7950        final boolean isSystemApp = process == null ||
7951                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7952                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7953        final String processName = process == null ? "unknown" : process.processName;
7954        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7955        final DropBoxManager dbox = (DropBoxManager)
7956                mContext.getSystemService(Context.DROPBOX_SERVICE);
7957
7958        // Exit early if the dropbox isn't configured to accept this report type.
7959        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7960
7961        boolean bufferWasEmpty;
7962        boolean needsFlush;
7963        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7964        synchronized (sb) {
7965            bufferWasEmpty = sb.length() == 0;
7966            appendDropBoxProcessHeaders(process, processName, sb);
7967            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7968            sb.append("System-App: ").append(isSystemApp).append("\n");
7969            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7970            if (info.violationNumThisLoop != 0) {
7971                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7972            }
7973            if (info.numAnimationsRunning != 0) {
7974                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7975            }
7976            if (info.broadcastIntentAction != null) {
7977                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7978            }
7979            if (info.durationMillis != -1) {
7980                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7981            }
7982            if (info.numInstances != -1) {
7983                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7984            }
7985            if (info.tags != null) {
7986                for (String tag : info.tags) {
7987                    sb.append("Span-Tag: ").append(tag).append("\n");
7988                }
7989            }
7990            sb.append("\n");
7991            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7992                sb.append(info.crashInfo.stackTrace);
7993            }
7994            sb.append("\n");
7995
7996            // Only buffer up to ~64k.  Various logging bits truncate
7997            // things at 128k.
7998            needsFlush = (sb.length() > 64 * 1024);
7999        }
8000
8001        // Flush immediately if the buffer's grown too large, or this
8002        // is a non-system app.  Non-system apps are isolated with a
8003        // different tag & policy and not batched.
8004        //
8005        // Batching is useful during internal testing with
8006        // StrictMode settings turned up high.  Without batching,
8007        // thousands of separate files could be created on boot.
8008        if (!isSystemApp || needsFlush) {
8009            new Thread("Error dump: " + dropboxTag) {
8010                @Override
8011                public void run() {
8012                    String report;
8013                    synchronized (sb) {
8014                        report = sb.toString();
8015                        sb.delete(0, sb.length());
8016                        sb.trimToSize();
8017                    }
8018                    if (report.length() != 0) {
8019                        dbox.addText(dropboxTag, report);
8020                    }
8021                }
8022            }.start();
8023            return;
8024        }
8025
8026        // System app batching:
8027        if (!bufferWasEmpty) {
8028            // An existing dropbox-writing thread is outstanding, so
8029            // we don't need to start it up.  The existing thread will
8030            // catch the buffer appends we just did.
8031            return;
8032        }
8033
8034        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8035        // (After this point, we shouldn't access AMS internal data structures.)
8036        new Thread("Error dump: " + dropboxTag) {
8037            @Override
8038            public void run() {
8039                // 5 second sleep to let stacks arrive and be batched together
8040                try {
8041                    Thread.sleep(5000);  // 5 seconds
8042                } catch (InterruptedException e) {}
8043
8044                String errorReport;
8045                synchronized (mStrictModeBuffer) {
8046                    errorReport = mStrictModeBuffer.toString();
8047                    if (errorReport.length() == 0) {
8048                        return;
8049                    }
8050                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8051                    mStrictModeBuffer.trimToSize();
8052                }
8053                dbox.addText(dropboxTag, errorReport);
8054            }
8055        }.start();
8056    }
8057
8058    /**
8059     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8060     * @param app object of the crashing app, null for the system server
8061     * @param tag reported by the caller
8062     * @param crashInfo describing the context of the error
8063     * @return true if the process should exit immediately (WTF is fatal)
8064     */
8065    public boolean handleApplicationWtf(IBinder app, String tag,
8066            ApplicationErrorReport.CrashInfo crashInfo) {
8067        ProcessRecord r = findAppProcess(app, "WTF");
8068        final String processName = app == null ? "system_server"
8069                : (r == null ? "unknown" : r.processName);
8070
8071        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8072                processName,
8073                r == null ? -1 : r.info.flags,
8074                tag, crashInfo.exceptionMessage);
8075
8076        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8077
8078        if (r != null && r.pid != Process.myPid() &&
8079                Settings.Secure.getInt(mContext.getContentResolver(),
8080                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8081            crashApplication(r, crashInfo);
8082            return true;
8083        } else {
8084            return false;
8085        }
8086    }
8087
8088    /**
8089     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8090     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8091     */
8092    private ProcessRecord findAppProcess(IBinder app, String reason) {
8093        if (app == null) {
8094            return null;
8095        }
8096
8097        synchronized (this) {
8098            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8099                final int NA = apps.size();
8100                for (int ia=0; ia<NA; ia++) {
8101                    ProcessRecord p = apps.valueAt(ia);
8102                    if (p.thread != null && p.thread.asBinder() == app) {
8103                        return p;
8104                    }
8105                }
8106            }
8107
8108            Slog.w(TAG, "Can't find mystery application for " + reason
8109                    + " from pid=" + Binder.getCallingPid()
8110                    + " uid=" + Binder.getCallingUid() + ": " + app);
8111            return null;
8112        }
8113    }
8114
8115    /**
8116     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8117     * to append various headers to the dropbox log text.
8118     */
8119    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8120            StringBuilder sb) {
8121        // Watchdog thread ends up invoking this function (with
8122        // a null ProcessRecord) to add the stack file to dropbox.
8123        // Do not acquire a lock on this (am) in such cases, as it
8124        // could cause a potential deadlock, if and when watchdog
8125        // is invoked due to unavailability of lock on am and it
8126        // would prevent watchdog from killing system_server.
8127        if (process == null) {
8128            sb.append("Process: ").append(processName).append("\n");
8129            return;
8130        }
8131        // Note: ProcessRecord 'process' is guarded by the service
8132        // instance.  (notably process.pkgList, which could otherwise change
8133        // concurrently during execution of this method)
8134        synchronized (this) {
8135            sb.append("Process: ").append(processName).append("\n");
8136            int flags = process.info.flags;
8137            IPackageManager pm = AppGlobals.getPackageManager();
8138            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8139            for (String pkg : process.pkgList) {
8140                sb.append("Package: ").append(pkg);
8141                try {
8142                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8143                    if (pi != null) {
8144                        sb.append(" v").append(pi.versionCode);
8145                        if (pi.versionName != null) {
8146                            sb.append(" (").append(pi.versionName).append(")");
8147                        }
8148                    }
8149                } catch (RemoteException e) {
8150                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8151                }
8152                sb.append("\n");
8153            }
8154        }
8155    }
8156
8157    private static String processClass(ProcessRecord process) {
8158        if (process == null || process.pid == MY_PID) {
8159            return "system_server";
8160        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8161            return "system_app";
8162        } else {
8163            return "data_app";
8164        }
8165    }
8166
8167    /**
8168     * Write a description of an error (crash, WTF, ANR) to the drop box.
8169     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8170     * @param process which caused the error, null means the system server
8171     * @param activity which triggered the error, null if unknown
8172     * @param parent activity related to the error, null if unknown
8173     * @param subject line related to the error, null if absent
8174     * @param report in long form describing the error, null if absent
8175     * @param logFile to include in the report, null if none
8176     * @param crashInfo giving an application stack trace, null if absent
8177     */
8178    public void addErrorToDropBox(String eventType,
8179            ProcessRecord process, String processName, ActivityRecord activity,
8180            ActivityRecord parent, String subject,
8181            final String report, final File logFile,
8182            final ApplicationErrorReport.CrashInfo crashInfo) {
8183        // NOTE -- this must never acquire the ActivityManagerService lock,
8184        // otherwise the watchdog may be prevented from resetting the system.
8185
8186        final String dropboxTag = processClass(process) + "_" + eventType;
8187        final DropBoxManager dbox = (DropBoxManager)
8188                mContext.getSystemService(Context.DROPBOX_SERVICE);
8189
8190        // Exit early if the dropbox isn't configured to accept this report type.
8191        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8192
8193        final StringBuilder sb = new StringBuilder(1024);
8194        appendDropBoxProcessHeaders(process, processName, sb);
8195        if (activity != null) {
8196            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8197        }
8198        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8199            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8200        }
8201        if (parent != null && parent != activity) {
8202            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8203        }
8204        if (subject != null) {
8205            sb.append("Subject: ").append(subject).append("\n");
8206        }
8207        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8208        if (Debug.isDebuggerConnected()) {
8209            sb.append("Debugger: Connected\n");
8210        }
8211        sb.append("\n");
8212
8213        // Do the rest in a worker thread to avoid blocking the caller on I/O
8214        // (After this point, we shouldn't access AMS internal data structures.)
8215        Thread worker = new Thread("Error dump: " + dropboxTag) {
8216            @Override
8217            public void run() {
8218                if (report != null) {
8219                    sb.append(report);
8220                }
8221                if (logFile != null) {
8222                    try {
8223                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8224                    } catch (IOException e) {
8225                        Slog.e(TAG, "Error reading " + logFile, e);
8226                    }
8227                }
8228                if (crashInfo != null && crashInfo.stackTrace != null) {
8229                    sb.append(crashInfo.stackTrace);
8230                }
8231
8232                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8233                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8234                if (lines > 0) {
8235                    sb.append("\n");
8236
8237                    // Merge several logcat streams, and take the last N lines
8238                    InputStreamReader input = null;
8239                    try {
8240                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8241                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8242                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8243
8244                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8245                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8246                        input = new InputStreamReader(logcat.getInputStream());
8247
8248                        int num;
8249                        char[] buf = new char[8192];
8250                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8251                    } catch (IOException e) {
8252                        Slog.e(TAG, "Error running logcat", e);
8253                    } finally {
8254                        if (input != null) try { input.close(); } catch (IOException e) {}
8255                    }
8256                }
8257
8258                dbox.addText(dropboxTag, sb.toString());
8259            }
8260        };
8261
8262        if (process == null) {
8263            // If process is null, we are being called from some internal code
8264            // and may be about to die -- run this synchronously.
8265            worker.run();
8266        } else {
8267            worker.start();
8268        }
8269    }
8270
8271    /**
8272     * Bring up the "unexpected error" dialog box for a crashing app.
8273     * Deal with edge cases (intercepts from instrumented applications,
8274     * ActivityController, error intent receivers, that sort of thing).
8275     * @param r the application crashing
8276     * @param crashInfo describing the failure
8277     */
8278    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8279        long timeMillis = System.currentTimeMillis();
8280        String shortMsg = crashInfo.exceptionClassName;
8281        String longMsg = crashInfo.exceptionMessage;
8282        String stackTrace = crashInfo.stackTrace;
8283        if (shortMsg != null && longMsg != null) {
8284            longMsg = shortMsg + ": " + longMsg;
8285        } else if (shortMsg != null) {
8286            longMsg = shortMsg;
8287        }
8288
8289        AppErrorResult result = new AppErrorResult();
8290        synchronized (this) {
8291            if (mController != null) {
8292                try {
8293                    String name = r != null ? r.processName : null;
8294                    int pid = r != null ? r.pid : Binder.getCallingPid();
8295                    if (!mController.appCrashed(name, pid,
8296                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8297                        Slog.w(TAG, "Force-killing crashed app " + name
8298                                + " at watcher's request");
8299                        Process.killProcess(pid);
8300                        return;
8301                    }
8302                } catch (RemoteException e) {
8303                    mController = null;
8304                }
8305            }
8306
8307            final long origId = Binder.clearCallingIdentity();
8308
8309            // If this process is running instrumentation, finish it.
8310            if (r != null && r.instrumentationClass != null) {
8311                Slog.w(TAG, "Error in app " + r.processName
8312                      + " running instrumentation " + r.instrumentationClass + ":");
8313                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8314                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8315                Bundle info = new Bundle();
8316                info.putString("shortMsg", shortMsg);
8317                info.putString("longMsg", longMsg);
8318                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8319                Binder.restoreCallingIdentity(origId);
8320                return;
8321            }
8322
8323            // If we can't identify the process or it's already exceeded its crash quota,
8324            // quit right away without showing a crash dialog.
8325            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8326                Binder.restoreCallingIdentity(origId);
8327                return;
8328            }
8329
8330            Message msg = Message.obtain();
8331            msg.what = SHOW_ERROR_MSG;
8332            HashMap data = new HashMap();
8333            data.put("result", result);
8334            data.put("app", r);
8335            msg.obj = data;
8336            mHandler.sendMessage(msg);
8337
8338            Binder.restoreCallingIdentity(origId);
8339        }
8340
8341        int res = result.get();
8342
8343        Intent appErrorIntent = null;
8344        synchronized (this) {
8345            if (r != null && !r.isolated) {
8346                // XXX Can't keep track of crash time for isolated processes,
8347                // since they don't have a persistent identity.
8348                mProcessCrashTimes.put(r.info.processName, r.uid,
8349                        SystemClock.uptimeMillis());
8350            }
8351            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8352                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8353            }
8354        }
8355
8356        if (appErrorIntent != null) {
8357            try {
8358                mContext.startActivity(appErrorIntent);
8359            } catch (ActivityNotFoundException e) {
8360                Slog.w(TAG, "bug report receiver dissappeared", e);
8361            }
8362        }
8363    }
8364
8365    Intent createAppErrorIntentLocked(ProcessRecord r,
8366            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8367        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8368        if (report == null) {
8369            return null;
8370        }
8371        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8372        result.setComponent(r.errorReportReceiver);
8373        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8374        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8375        return result;
8376    }
8377
8378    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8379            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8380        if (r.errorReportReceiver == null) {
8381            return null;
8382        }
8383
8384        if (!r.crashing && !r.notResponding) {
8385            return null;
8386        }
8387
8388        ApplicationErrorReport report = new ApplicationErrorReport();
8389        report.packageName = r.info.packageName;
8390        report.installerPackageName = r.errorReportReceiver.getPackageName();
8391        report.processName = r.processName;
8392        report.time = timeMillis;
8393        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8394
8395        if (r.crashing) {
8396            report.type = ApplicationErrorReport.TYPE_CRASH;
8397            report.crashInfo = crashInfo;
8398        } else if (r.notResponding) {
8399            report.type = ApplicationErrorReport.TYPE_ANR;
8400            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8401
8402            report.anrInfo.activity = r.notRespondingReport.tag;
8403            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8404            report.anrInfo.info = r.notRespondingReport.longMsg;
8405        }
8406
8407        return report;
8408    }
8409
8410    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8411        enforceNotIsolatedCaller("getProcessesInErrorState");
8412        // assume our apps are happy - lazy create the list
8413        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8414
8415        synchronized (this) {
8416
8417            // iterate across all processes
8418            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8419                ProcessRecord app = mLruProcesses.get(i);
8420                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8421                    // This one's in trouble, so we'll generate a report for it
8422                    // crashes are higher priority (in case there's a crash *and* an anr)
8423                    ActivityManager.ProcessErrorStateInfo report = null;
8424                    if (app.crashing) {
8425                        report = app.crashingReport;
8426                    } else if (app.notResponding) {
8427                        report = app.notRespondingReport;
8428                    }
8429
8430                    if (report != null) {
8431                        if (errList == null) {
8432                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8433                        }
8434                        errList.add(report);
8435                    } else {
8436                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8437                                " crashing = " + app.crashing +
8438                                " notResponding = " + app.notResponding);
8439                    }
8440                }
8441            }
8442        }
8443
8444        return errList;
8445    }
8446
8447    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8448        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8449            if (currApp != null) {
8450                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8451            }
8452            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8453        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8454            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8455        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8456            if (currApp != null) {
8457                currApp.lru = 0;
8458            }
8459            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8460        } else if (adj >= ProcessList.SERVICE_ADJ) {
8461            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8462        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8463            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8464        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8465            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8466        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8467            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8468        } else {
8469            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8470        }
8471    }
8472
8473    private void fillInProcMemInfo(ProcessRecord app,
8474            ActivityManager.RunningAppProcessInfo outInfo) {
8475        outInfo.pid = app.pid;
8476        outInfo.uid = app.info.uid;
8477        if (mHeavyWeightProcess == app) {
8478            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8479        }
8480        if (app.persistent) {
8481            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8482        }
8483        outInfo.lastTrimLevel = app.trimMemoryLevel;
8484        int adj = app.curAdj;
8485        outInfo.importance = oomAdjToImportance(adj, outInfo);
8486        outInfo.importanceReasonCode = app.adjTypeCode;
8487    }
8488
8489    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8490        enforceNotIsolatedCaller("getRunningAppProcesses");
8491        // Lazy instantiation of list
8492        List<ActivityManager.RunningAppProcessInfo> runList = null;
8493        synchronized (this) {
8494            // Iterate across all processes
8495            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8496                ProcessRecord app = mLruProcesses.get(i);
8497                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8498                    // Generate process state info for running application
8499                    ActivityManager.RunningAppProcessInfo currApp =
8500                        new ActivityManager.RunningAppProcessInfo(app.processName,
8501                                app.pid, app.getPackageList());
8502                    fillInProcMemInfo(app, currApp);
8503                    if (app.adjSource instanceof ProcessRecord) {
8504                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8505                        currApp.importanceReasonImportance = oomAdjToImportance(
8506                                app.adjSourceOom, null);
8507                    } else if (app.adjSource instanceof ActivityRecord) {
8508                        ActivityRecord r = (ActivityRecord)app.adjSource;
8509                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8510                    }
8511                    if (app.adjTarget instanceof ComponentName) {
8512                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8513                    }
8514                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8515                    //        + " lru=" + currApp.lru);
8516                    if (runList == null) {
8517                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8518                    }
8519                    runList.add(currApp);
8520                }
8521            }
8522        }
8523        return runList;
8524    }
8525
8526    public List<ApplicationInfo> getRunningExternalApplications() {
8527        enforceNotIsolatedCaller("getRunningExternalApplications");
8528        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8529        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8530        if (runningApps != null && runningApps.size() > 0) {
8531            Set<String> extList = new HashSet<String>();
8532            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8533                if (app.pkgList != null) {
8534                    for (String pkg : app.pkgList) {
8535                        extList.add(pkg);
8536                    }
8537                }
8538            }
8539            IPackageManager pm = AppGlobals.getPackageManager();
8540            for (String pkg : extList) {
8541                try {
8542                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8543                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8544                        retList.add(info);
8545                    }
8546                } catch (RemoteException e) {
8547                }
8548            }
8549        }
8550        return retList;
8551    }
8552
8553    @Override
8554    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8555        enforceNotIsolatedCaller("getMyMemoryState");
8556        synchronized (this) {
8557            ProcessRecord proc;
8558            synchronized (mPidsSelfLocked) {
8559                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8560            }
8561            fillInProcMemInfo(proc, outInfo);
8562        }
8563    }
8564
8565    @Override
8566    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8567        if (checkCallingPermission(android.Manifest.permission.DUMP)
8568                != PackageManager.PERMISSION_GRANTED) {
8569            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8570                    + Binder.getCallingPid()
8571                    + ", uid=" + Binder.getCallingUid()
8572                    + " without permission "
8573                    + android.Manifest.permission.DUMP);
8574            return;
8575        }
8576
8577        boolean dumpAll = false;
8578        boolean dumpClient = false;
8579        String dumpPackage = null;
8580
8581        int opti = 0;
8582        while (opti < args.length) {
8583            String opt = args[opti];
8584            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8585                break;
8586            }
8587            opti++;
8588            if ("-a".equals(opt)) {
8589                dumpAll = true;
8590            } else if ("-c".equals(opt)) {
8591                dumpClient = true;
8592            } else if ("-h".equals(opt)) {
8593                pw.println("Activity manager dump options:");
8594                pw.println("  [-a] [-c] [-h] [cmd] ...");
8595                pw.println("  cmd may be one of:");
8596                pw.println("    a[ctivities]: activity stack state");
8597                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8598                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8599                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8600                pw.println("    o[om]: out of memory management");
8601                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8602                pw.println("    provider [COMP_SPEC]: provider client-side state");
8603                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8604                pw.println("    service [COMP_SPEC]: service client-side state");
8605                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8606                pw.println("    all: dump all activities");
8607                pw.println("    top: dump the top activity");
8608                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8609                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8610                pw.println("    a partial substring in a component name, a");
8611                pw.println("    hex object identifier.");
8612                pw.println("  -a: include all available server state.");
8613                pw.println("  -c: include client state.");
8614                return;
8615            } else {
8616                pw.println("Unknown argument: " + opt + "; use -h for help");
8617            }
8618        }
8619
8620        long origId = Binder.clearCallingIdentity();
8621        boolean more = false;
8622        // Is the caller requesting to dump a particular piece of data?
8623        if (opti < args.length) {
8624            String cmd = args[opti];
8625            opti++;
8626            if ("activities".equals(cmd) || "a".equals(cmd)) {
8627                synchronized (this) {
8628                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8629                }
8630            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8631                String[] newArgs;
8632                String name;
8633                if (opti >= args.length) {
8634                    name = null;
8635                    newArgs = EMPTY_STRING_ARRAY;
8636                } else {
8637                    name = args[opti];
8638                    opti++;
8639                    newArgs = new String[args.length - opti];
8640                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8641                            args.length - opti);
8642                }
8643                synchronized (this) {
8644                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8645                }
8646            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8647                String[] newArgs;
8648                String name;
8649                if (opti >= args.length) {
8650                    name = null;
8651                    newArgs = EMPTY_STRING_ARRAY;
8652                } else {
8653                    name = args[opti];
8654                    opti++;
8655                    newArgs = new String[args.length - opti];
8656                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8657                            args.length - opti);
8658                }
8659                synchronized (this) {
8660                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8661                }
8662            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8663                String[] newArgs;
8664                String name;
8665                if (opti >= args.length) {
8666                    name = null;
8667                    newArgs = EMPTY_STRING_ARRAY;
8668                } else {
8669                    name = args[opti];
8670                    opti++;
8671                    newArgs = new String[args.length - opti];
8672                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8673                            args.length - opti);
8674                }
8675                synchronized (this) {
8676                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8677                }
8678            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8679                synchronized (this) {
8680                    dumpOomLocked(fd, pw, args, opti, true);
8681                }
8682            } else if ("provider".equals(cmd)) {
8683                String[] newArgs;
8684                String name;
8685                if (opti >= args.length) {
8686                    name = null;
8687                    newArgs = EMPTY_STRING_ARRAY;
8688                } else {
8689                    name = args[opti];
8690                    opti++;
8691                    newArgs = new String[args.length - opti];
8692                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8693                }
8694                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8695                    pw.println("No providers match: " + name);
8696                    pw.println("Use -h for help.");
8697                }
8698            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8699                synchronized (this) {
8700                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8701                }
8702            } else if ("service".equals(cmd)) {
8703                String[] newArgs;
8704                String name;
8705                if (opti >= args.length) {
8706                    name = null;
8707                    newArgs = EMPTY_STRING_ARRAY;
8708                } else {
8709                    name = args[opti];
8710                    opti++;
8711                    newArgs = new String[args.length - opti];
8712                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8713                            args.length - opti);
8714                }
8715                if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8716                    pw.println("No services match: " + name);
8717                    pw.println("Use -h for help.");
8718                }
8719            } else if ("package".equals(cmd)) {
8720                String[] newArgs;
8721                if (opti >= args.length) {
8722                    pw.println("package: no package name specified");
8723                    pw.println("Use -h for help.");
8724                } else {
8725                    dumpPackage = args[opti];
8726                    opti++;
8727                    newArgs = new String[args.length - opti];
8728                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8729                            args.length - opti);
8730                    args = newArgs;
8731                    opti = 0;
8732                    more = true;
8733                }
8734            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8735                synchronized (this) {
8736                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8737                }
8738            } else {
8739                // Dumping a single activity?
8740                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8741                    pw.println("Bad activity command, or no activities match: " + cmd);
8742                    pw.println("Use -h for help.");
8743                }
8744            }
8745            if (!more) {
8746                Binder.restoreCallingIdentity(origId);
8747                return;
8748            }
8749        }
8750
8751        // No piece of data specified, dump everything.
8752        synchronized (this) {
8753            boolean needSep;
8754            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8755            if (needSep) {
8756                pw.println(" ");
8757            }
8758            if (dumpAll) {
8759                pw.println("-------------------------------------------------------------------------------");
8760            }
8761            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8762            if (needSep) {
8763                pw.println(" ");
8764            }
8765            if (dumpAll) {
8766                pw.println("-------------------------------------------------------------------------------");
8767            }
8768            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8769            if (needSep) {
8770                pw.println(" ");
8771            }
8772            if (dumpAll) {
8773                pw.println("-------------------------------------------------------------------------------");
8774            }
8775            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8776            if (needSep) {
8777                pw.println(" ");
8778            }
8779            if (dumpAll) {
8780                pw.println("-------------------------------------------------------------------------------");
8781            }
8782            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8783            if (needSep) {
8784                pw.println(" ");
8785            }
8786            if (dumpAll) {
8787                pw.println("-------------------------------------------------------------------------------");
8788            }
8789            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8790        }
8791        Binder.restoreCallingIdentity(origId);
8792    }
8793
8794    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8795            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8796        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8797        pw.println("  Main stack:");
8798        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8799                dumpPackage);
8800        pw.println(" ");
8801        pw.println("  Running activities (most recent first):");
8802        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8803                dumpPackage);
8804        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8805            pw.println(" ");
8806            pw.println("  Activities waiting for another to become visible:");
8807            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8808                    !dumpAll, false, dumpPackage);
8809        }
8810        if (mMainStack.mStoppingActivities.size() > 0) {
8811            pw.println(" ");
8812            pw.println("  Activities waiting to stop:");
8813            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8814                    !dumpAll, false, dumpPackage);
8815        }
8816        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8817            pw.println(" ");
8818            pw.println("  Activities waiting to sleep:");
8819            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8820                    !dumpAll, false, dumpPackage);
8821        }
8822        if (mMainStack.mFinishingActivities.size() > 0) {
8823            pw.println(" ");
8824            pw.println("  Activities waiting to finish:");
8825            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8826                    !dumpAll, false, dumpPackage);
8827        }
8828
8829        pw.println(" ");
8830        if (mMainStack.mPausingActivity != null) {
8831            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8832        }
8833        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8834        pw.println("  mFocusedActivity: " + mFocusedActivity);
8835        if (dumpAll) {
8836            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8837            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8838            pw.println("  mDismissKeyguardOnNextActivity: "
8839                    + mMainStack.mDismissKeyguardOnNextActivity);
8840        }
8841
8842        if (mRecentTasks.size() > 0) {
8843            pw.println();
8844            pw.println("  Recent tasks:");
8845
8846            final int N = mRecentTasks.size();
8847            for (int i=0; i<N; i++) {
8848                TaskRecord tr = mRecentTasks.get(i);
8849                if (dumpPackage != null) {
8850                    if (tr.realActivity == null ||
8851                            !dumpPackage.equals(tr.realActivity)) {
8852                        continue;
8853                    }
8854                }
8855                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8856                        pw.println(tr);
8857                if (dumpAll) {
8858                    mRecentTasks.get(i).dump(pw, "    ");
8859                }
8860            }
8861        }
8862
8863        if (dumpAll) {
8864            pw.println(" ");
8865            pw.println("  mCurTask: " + mCurTask);
8866        }
8867
8868        return true;
8869    }
8870
8871    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8872            int opti, boolean dumpAll, String dumpPackage) {
8873        boolean needSep = false;
8874        int numPers = 0;
8875
8876        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8877
8878        if (dumpAll) {
8879            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8880                final int NA = procs.size();
8881                for (int ia=0; ia<NA; ia++) {
8882                    ProcessRecord r = procs.valueAt(ia);
8883                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8884                        continue;
8885                    }
8886                    if (!needSep) {
8887                        pw.println("  All known processes:");
8888                        needSep = true;
8889                    }
8890                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8891                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8892                        pw.print(" "); pw.println(r);
8893                    r.dump(pw, "    ");
8894                    if (r.persistent) {
8895                        numPers++;
8896                    }
8897                }
8898            }
8899        }
8900
8901        if (mIsolatedProcesses.size() > 0) {
8902            if (needSep) pw.println(" ");
8903            needSep = true;
8904            pw.println("  Isolated process list (sorted by uid):");
8905            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8906                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8907                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8908                    continue;
8909                }
8910                pw.println(String.format("%sIsolated #%2d: %s",
8911                        "    ", i, r.toString()));
8912            }
8913        }
8914
8915        if (mLruProcesses.size() > 0) {
8916            if (needSep) pw.println(" ");
8917            needSep = true;
8918            pw.println("  Process LRU list (sorted by oom_adj):");
8919            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8920                    "Proc", "PERS", false, dumpPackage);
8921            needSep = true;
8922        }
8923
8924        if (dumpAll) {
8925            synchronized (mPidsSelfLocked) {
8926                boolean printed = false;
8927                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8928                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8929                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8930                        continue;
8931                    }
8932                    if (!printed) {
8933                        if (needSep) pw.println(" ");
8934                        needSep = true;
8935                        pw.println("  PID mappings:");
8936                        printed = true;
8937                    }
8938                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8939                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8940                }
8941            }
8942        }
8943
8944        if (mForegroundProcesses.size() > 0) {
8945            synchronized (mPidsSelfLocked) {
8946                boolean printed = false;
8947                for (int i=0; i<mForegroundProcesses.size(); i++) {
8948                    ProcessRecord r = mPidsSelfLocked.get(
8949                            mForegroundProcesses.valueAt(i).pid);
8950                    if (dumpPackage != null && (r == null
8951                            || !dumpPackage.equals(r.info.packageName))) {
8952                        continue;
8953                    }
8954                    if (!printed) {
8955                        if (needSep) pw.println(" ");
8956                        needSep = true;
8957                        pw.println("  Foreground Processes:");
8958                        printed = true;
8959                    }
8960                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8961                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8962                }
8963            }
8964        }
8965
8966        if (mPersistentStartingProcesses.size() > 0) {
8967            if (needSep) pw.println(" ");
8968            needSep = true;
8969            pw.println("  Persisent processes that are starting:");
8970            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8971                    "Starting Norm", "Restarting PERS", dumpPackage);
8972        }
8973
8974        if (mRemovedProcesses.size() > 0) {
8975            if (needSep) pw.println(" ");
8976            needSep = true;
8977            pw.println("  Processes that are being removed:");
8978            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8979                    "Removed Norm", "Removed PERS", dumpPackage);
8980        }
8981
8982        if (mProcessesOnHold.size() > 0) {
8983            if (needSep) pw.println(" ");
8984            needSep = true;
8985            pw.println("  Processes that are on old until the system is ready:");
8986            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8987                    "OnHold Norm", "OnHold PERS", dumpPackage);
8988        }
8989
8990        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8991
8992        if (mProcessCrashTimes.getMap().size() > 0) {
8993            boolean printed = false;
8994            long now = SystemClock.uptimeMillis();
8995            for (Map.Entry<String, SparseArray<Long>> procs
8996                    : mProcessCrashTimes.getMap().entrySet()) {
8997                String pname = procs.getKey();
8998                SparseArray<Long> uids = procs.getValue();
8999                final int N = uids.size();
9000                for (int i=0; i<N; i++) {
9001                    int puid = uids.keyAt(i);
9002                    ProcessRecord r = mProcessNames.get(pname, puid);
9003                    if (dumpPackage != null && (r == null
9004                            || !dumpPackage.equals(r.info.packageName))) {
9005                        continue;
9006                    }
9007                    if (!printed) {
9008                        if (needSep) pw.println(" ");
9009                        needSep = true;
9010                        pw.println("  Time since processes crashed:");
9011                        printed = true;
9012                    }
9013                    pw.print("    Process "); pw.print(pname);
9014                            pw.print(" uid "); pw.print(puid);
9015                            pw.print(": last crashed ");
9016                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9017                            pw.println(" ago");
9018                }
9019            }
9020        }
9021
9022        if (mBadProcesses.getMap().size() > 0) {
9023            boolean printed = false;
9024            for (Map.Entry<String, SparseArray<Long>> procs
9025                    : mBadProcesses.getMap().entrySet()) {
9026                String pname = procs.getKey();
9027                SparseArray<Long> uids = procs.getValue();
9028                final int N = uids.size();
9029                for (int i=0; i<N; i++) {
9030                    int puid = uids.keyAt(i);
9031                    ProcessRecord r = mProcessNames.get(pname, puid);
9032                    if (dumpPackage != null && (r == null
9033                            || !dumpPackage.equals(r.info.packageName))) {
9034                        continue;
9035                    }
9036                    if (!printed) {
9037                        if (needSep) pw.println(" ");
9038                        needSep = true;
9039                        pw.println("  Bad processes:");
9040                    }
9041                    pw.print("    Bad process "); pw.print(pname);
9042                            pw.print(" uid "); pw.print(puid);
9043                            pw.print(": crashed at time ");
9044                            pw.println(uids.valueAt(i));
9045                }
9046            }
9047        }
9048
9049        pw.println();
9050        pw.println("  mHomeProcess: " + mHomeProcess);
9051        pw.println("  mPreviousProcess: " + mPreviousProcess);
9052        if (dumpAll) {
9053            StringBuilder sb = new StringBuilder(128);
9054            sb.append("  mPreviousProcessVisibleTime: ");
9055            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9056            pw.println(sb);
9057        }
9058        if (mHeavyWeightProcess != null) {
9059            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9060        }
9061        pw.println("  mConfiguration: " + mConfiguration);
9062        if (dumpAll) {
9063            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9064            if (mCompatModePackages.getPackages().size() > 0) {
9065                boolean printed = false;
9066                for (Map.Entry<String, Integer> entry
9067                        : mCompatModePackages.getPackages().entrySet()) {
9068                    String pkg = entry.getKey();
9069                    int mode = entry.getValue();
9070                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9071                        continue;
9072                    }
9073                    if (!printed) {
9074                        pw.println("  mScreenCompatPackages:");
9075                        printed = true;
9076                    }
9077                    pw.print("    "); pw.print(pkg); pw.print(": ");
9078                            pw.print(mode); pw.println();
9079                }
9080            }
9081        }
9082        if (mSleeping || mWentToSleep || mLockScreenShown) {
9083            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9084                    + " mLockScreenShown " + mLockScreenShown);
9085        }
9086        if (mShuttingDown) {
9087            pw.println("  mShuttingDown=" + mShuttingDown);
9088        }
9089        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9090                || mOrigWaitForDebugger) {
9091            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9092                    + " mDebugTransient=" + mDebugTransient
9093                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9094        }
9095        if (mOpenGlTraceApp != null) {
9096            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9097        }
9098        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9099                || mProfileFd != null) {
9100            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9101            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9102            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9103                    + mAutoStopProfiler);
9104        }
9105        if (mAlwaysFinishActivities || mController != null) {
9106            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9107                    + " mController=" + mController);
9108        }
9109        if (dumpAll) {
9110            pw.println("  Total persistent processes: " + numPers);
9111            pw.println("  mStartRunning=" + mStartRunning
9112                    + " mProcessesReady=" + mProcessesReady
9113                    + " mSystemReady=" + mSystemReady);
9114            pw.println("  mBooting=" + mBooting
9115                    + " mBooted=" + mBooted
9116                    + " mFactoryTest=" + mFactoryTest);
9117            pw.print("  mLastPowerCheckRealtime=");
9118                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9119                    pw.println("");
9120            pw.print("  mLastPowerCheckUptime=");
9121                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9122                    pw.println("");
9123            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9124            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9125            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9126            pw.println("  mNumServiceProcs=" + mNumServiceProcs
9127                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9128        }
9129
9130        return true;
9131    }
9132
9133    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9134            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9135        if (mProcessesToGc.size() > 0) {
9136            boolean printed = false;
9137            long now = SystemClock.uptimeMillis();
9138            for (int i=0; i<mProcessesToGc.size(); i++) {
9139                ProcessRecord proc = mProcessesToGc.get(i);
9140                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9141                    continue;
9142                }
9143                if (!printed) {
9144                    if (needSep) pw.println(" ");
9145                    needSep = true;
9146                    pw.println("  Processes that are waiting to GC:");
9147                    printed = true;
9148                }
9149                pw.print("    Process "); pw.println(proc);
9150                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9151                        pw.print(", last gced=");
9152                        pw.print(now-proc.lastRequestedGc);
9153                        pw.print(" ms ago, last lowMem=");
9154                        pw.print(now-proc.lastLowMemory);
9155                        pw.println(" ms ago");
9156
9157            }
9158        }
9159        return needSep;
9160    }
9161
9162    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9163            int opti, boolean dumpAll) {
9164        boolean needSep = false;
9165
9166        if (mLruProcesses.size() > 0) {
9167            if (needSep) pw.println(" ");
9168            needSep = true;
9169            pw.println("  OOM levels:");
9170            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9171            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9172            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9173            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9174            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9175            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9176            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9177            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9178            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9179            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9180            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9181            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9182            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9183
9184            if (needSep) pw.println(" ");
9185            needSep = true;
9186            pw.println("  Process OOM control:");
9187            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9188                    "Proc", "PERS", true, null);
9189            needSep = true;
9190        }
9191
9192        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9193
9194        pw.println();
9195        pw.println("  mHomeProcess: " + mHomeProcess);
9196        pw.println("  mPreviousProcess: " + mPreviousProcess);
9197        if (mHeavyWeightProcess != null) {
9198            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9199        }
9200
9201        return true;
9202    }
9203
9204    /**
9205     * There are three ways to call this:
9206     *  - no service specified: dump all the services
9207     *  - a flattened component name that matched an existing service was specified as the
9208     *    first arg: dump that one service
9209     *  - the first arg isn't the flattened component name of an existing service:
9210     *    dump all services whose component contains the first arg as a substring
9211     */
9212    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9213            int opti, boolean dumpAll) {
9214        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
9215
9216        if ("all".equals(name)) {
9217            synchronized (this) {
9218                try {
9219                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9220                    for (UserInfo user : users) {
9221                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9222                            services.add(r1);
9223                        }
9224                    }
9225                } catch (RemoteException re) {
9226                }
9227            }
9228        } else {
9229            ComponentName componentName = name != null
9230                    ? ComponentName.unflattenFromString(name) : null;
9231            int objectId = 0;
9232            if (componentName == null) {
9233                // Not a '/' separated full component name; maybe an object ID?
9234                try {
9235                    objectId = Integer.parseInt(name, 16);
9236                    name = null;
9237                    componentName = null;
9238                } catch (RuntimeException e) {
9239                }
9240            }
9241
9242            synchronized (this) {
9243                try {
9244                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9245                    for (UserInfo user : users) {
9246                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9247                            if (componentName != null) {
9248                                if (r1.name.equals(componentName)) {
9249                                    services.add(r1);
9250                                }
9251                            } else if (name != null) {
9252                                if (r1.name.flattenToString().contains(name)) {
9253                                    services.add(r1);
9254                                }
9255                            } else if (System.identityHashCode(r1) == objectId) {
9256                                services.add(r1);
9257                            }
9258                        }
9259                    }
9260                } catch (RemoteException re) {
9261                }
9262            }
9263        }
9264
9265        if (services.size() <= 0) {
9266            return false;
9267        }
9268
9269        boolean needSep = false;
9270        for (int i=0; i<services.size(); i++) {
9271            if (needSep) {
9272                pw.println();
9273            }
9274            needSep = true;
9275            dumpService("", fd, pw, services.get(i), args, dumpAll);
9276        }
9277        return true;
9278    }
9279
9280    /**
9281     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9282     * there is a thread associated with the service.
9283     */
9284    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9285            final ServiceRecord r, String[] args, boolean dumpAll) {
9286        String innerPrefix = prefix + "  ";
9287        synchronized (this) {
9288            pw.print(prefix); pw.print("SERVICE ");
9289                    pw.print(r.shortName); pw.print(" ");
9290                    pw.print(Integer.toHexString(System.identityHashCode(r)));
9291                    pw.print(" pid=");
9292                    if (r.app != null) pw.println(r.app.pid);
9293                    else pw.println("(not running)");
9294            if (dumpAll) {
9295                r.dump(pw, innerPrefix);
9296            }
9297        }
9298        if (r.app != null && r.app.thread != null) {
9299            pw.print(prefix); pw.println("  Client:");
9300            pw.flush();
9301            try {
9302                TransferPipe tp = new TransferPipe();
9303                try {
9304                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9305                    tp.setBufferPrefix(prefix + "    ");
9306                    tp.go(fd);
9307                } finally {
9308                    tp.kill();
9309                }
9310            } catch (IOException e) {
9311                pw.println(prefix + "    Failure while dumping the service: " + e);
9312            } catch (RemoteException e) {
9313                pw.println(prefix + "    Got a RemoteException while dumping the service");
9314            }
9315        }
9316    }
9317
9318    /**
9319     * There are three ways to call this:
9320     *  - no provider specified: dump all the providers
9321     *  - a flattened component name that matched an existing provider was specified as the
9322     *    first arg: dump that one provider
9323     *  - the first arg isn't the flattened component name of an existing provider:
9324     *    dump all providers whose component contains the first arg as a substring
9325     */
9326    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9327            int opti, boolean dumpAll) {
9328        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9329    }
9330
9331    static class ItemMatcher {
9332        ArrayList<ComponentName> components;
9333        ArrayList<String> strings;
9334        ArrayList<Integer> objects;
9335        boolean all;
9336
9337        ItemMatcher() {
9338            all = true;
9339        }
9340
9341        void build(String name) {
9342            ComponentName componentName = ComponentName.unflattenFromString(name);
9343            if (componentName != null) {
9344                if (components == null) {
9345                    components = new ArrayList<ComponentName>();
9346                }
9347                components.add(componentName);
9348                all = false;
9349            } else {
9350                int objectId = 0;
9351                // Not a '/' separated full component name; maybe an object ID?
9352                try {
9353                    objectId = Integer.parseInt(name, 16);
9354                    if (objects == null) {
9355                        objects = new ArrayList<Integer>();
9356                    }
9357                    objects.add(objectId);
9358                    all = false;
9359                } catch (RuntimeException e) {
9360                    // Not an integer; just do string match.
9361                    if (strings == null) {
9362                        strings = new ArrayList<String>();
9363                    }
9364                    strings.add(name);
9365                    all = false;
9366                }
9367            }
9368        }
9369
9370        int build(String[] args, int opti) {
9371            for (; opti<args.length; opti++) {
9372                String name = args[opti];
9373                if ("--".equals(name)) {
9374                    return opti+1;
9375                }
9376                build(name);
9377            }
9378            return opti;
9379        }
9380
9381        boolean match(Object object, ComponentName comp) {
9382            if (all) {
9383                return true;
9384            }
9385            if (components != null) {
9386                for (int i=0; i<components.size(); i++) {
9387                    if (components.get(i).equals(comp)) {
9388                        return true;
9389                    }
9390                }
9391            }
9392            if (objects != null) {
9393                for (int i=0; i<objects.size(); i++) {
9394                    if (System.identityHashCode(object) == objects.get(i)) {
9395                        return true;
9396                    }
9397                }
9398            }
9399            if (strings != null) {
9400                String flat = comp.flattenToString();
9401                for (int i=0; i<strings.size(); i++) {
9402                    if (flat.contains(strings.get(i))) {
9403                        return true;
9404                    }
9405                }
9406            }
9407            return false;
9408        }
9409    }
9410
9411    /**
9412     * There are three things that cmd can be:
9413     *  - a flattened component name that matches an existing activity
9414     *  - the cmd arg isn't the flattened component name of an existing activity:
9415     *    dump all activity whose component contains the cmd as a substring
9416     *  - A hex number of the ActivityRecord object instance.
9417     */
9418    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9419            int opti, boolean dumpAll) {
9420        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9421
9422        if ("all".equals(name)) {
9423            synchronized (this) {
9424                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9425                    activities.add(r1);
9426                }
9427            }
9428        } else if ("top".equals(name)) {
9429            synchronized (this) {
9430                final int N = mMainStack.mHistory.size();
9431                if (N > 0) {
9432                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9433                }
9434            }
9435        } else {
9436            ItemMatcher matcher = new ItemMatcher();
9437            matcher.build(name);
9438
9439            synchronized (this) {
9440                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9441                    if (matcher.match(r1, r1.intent.getComponent())) {
9442                        activities.add(r1);
9443                    }
9444                }
9445            }
9446        }
9447
9448        if (activities.size() <= 0) {
9449            return false;
9450        }
9451
9452        String[] newArgs = new String[args.length - opti];
9453        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9454
9455        TaskRecord lastTask = null;
9456        boolean needSep = false;
9457        for (int i=activities.size()-1; i>=0; i--) {
9458            ActivityRecord r = (ActivityRecord)activities.get(i);
9459            if (needSep) {
9460                pw.println();
9461            }
9462            needSep = true;
9463            synchronized (this) {
9464                if (lastTask != r.task) {
9465                    lastTask = r.task;
9466                    pw.print("TASK "); pw.print(lastTask.affinity);
9467                            pw.print(" id="); pw.println(lastTask.taskId);
9468                    if (dumpAll) {
9469                        lastTask.dump(pw, "  ");
9470                    }
9471                }
9472            }
9473            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9474        }
9475        return true;
9476    }
9477
9478    /**
9479     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9480     * there is a thread associated with the activity.
9481     */
9482    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9483            final ActivityRecord r, String[] args, boolean dumpAll) {
9484        String innerPrefix = prefix + "  ";
9485        synchronized (this) {
9486            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9487                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9488                    pw.print(" pid=");
9489                    if (r.app != null) pw.println(r.app.pid);
9490                    else pw.println("(not running)");
9491            if (dumpAll) {
9492                r.dump(pw, innerPrefix);
9493            }
9494        }
9495        if (r.app != null && r.app.thread != null) {
9496            // flush anything that is already in the PrintWriter since the thread is going
9497            // to write to the file descriptor directly
9498            pw.flush();
9499            try {
9500                TransferPipe tp = new TransferPipe();
9501                try {
9502                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9503                            r.appToken, innerPrefix, args);
9504                    tp.go(fd);
9505                } finally {
9506                    tp.kill();
9507                }
9508            } catch (IOException e) {
9509                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9510            } catch (RemoteException e) {
9511                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9512            }
9513        }
9514    }
9515
9516    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9517            int opti, boolean dumpAll, String dumpPackage) {
9518        boolean needSep = false;
9519
9520        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9521        if (dumpAll) {
9522            if (mRegisteredReceivers.size() > 0) {
9523                boolean printed = false;
9524                Iterator it = mRegisteredReceivers.values().iterator();
9525                while (it.hasNext()) {
9526                    ReceiverList r = (ReceiverList)it.next();
9527                    if (dumpPackage != null && (r.app == null ||
9528                            !dumpPackage.equals(r.app.info.packageName))) {
9529                        continue;
9530                    }
9531                    if (!printed) {
9532                        pw.println("  Registered Receivers:");
9533                        needSep = true;
9534                        printed = true;
9535                    }
9536                    pw.print("  * "); pw.println(r);
9537                    r.dump(pw, "    ");
9538                }
9539            }
9540
9541            if (mReceiverResolver.dump(pw, needSep ?
9542                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9543                    "    ", dumpPackage, false)) {
9544                needSep = true;
9545            }
9546        }
9547
9548        for (BroadcastQueue q : mBroadcastQueues) {
9549            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9550        }
9551
9552        needSep = true;
9553
9554        if (mStickyBroadcasts != null && dumpPackage == null) {
9555            if (needSep) {
9556                pw.println();
9557            }
9558            needSep = true;
9559            pw.println("  Sticky broadcasts:");
9560            StringBuilder sb = new StringBuilder(128);
9561            for (Map.Entry<String, ArrayList<Intent>> ent
9562                    : mStickyBroadcasts.entrySet()) {
9563                pw.print("  * Sticky action "); pw.print(ent.getKey());
9564                if (dumpAll) {
9565                    pw.println(":");
9566                    ArrayList<Intent> intents = ent.getValue();
9567                    final int N = intents.size();
9568                    for (int i=0; i<N; i++) {
9569                        sb.setLength(0);
9570                        sb.append("    Intent: ");
9571                        intents.get(i).toShortString(sb, false, true, false, false);
9572                        pw.println(sb.toString());
9573                        Bundle bundle = intents.get(i).getExtras();
9574                        if (bundle != null) {
9575                            pw.print("      ");
9576                            pw.println(bundle.toString());
9577                        }
9578                    }
9579                } else {
9580                    pw.println("");
9581                }
9582            }
9583            needSep = true;
9584        }
9585
9586        if (dumpAll) {
9587            pw.println();
9588            for (BroadcastQueue queue : mBroadcastQueues) {
9589                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9590                        + queue.mBroadcastsScheduled);
9591            }
9592            pw.println("  mHandler:");
9593            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9594            needSep = true;
9595        }
9596
9597        return needSep;
9598    }
9599
9600    /**
9601     * Prints a list of ServiceRecords (dumpsys activity services)
9602     */
9603    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9604            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9605        boolean needSep = false;
9606
9607        ItemMatcher matcher = new ItemMatcher();
9608        matcher.build(args, opti);
9609
9610        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9611        try {
9612            List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9613            for (UserInfo user : users) {
9614                if (mServiceMap.getAllServices(user.id).size() > 0) {
9615                    boolean printed = false;
9616                    long nowReal = SystemClock.elapsedRealtime();
9617                    Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9618                            user.id).iterator();
9619                    needSep = false;
9620                    while (it.hasNext()) {
9621                        ServiceRecord r = it.next();
9622                        if (!matcher.match(r, r.name)) {
9623                            continue;
9624                        }
9625                        if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9626                            continue;
9627                        }
9628                        if (!printed) {
9629                            pw.println("  Active services:");
9630                            printed = true;
9631                        }
9632                        if (needSep) {
9633                            pw.println();
9634                        }
9635                        pw.print("  * ");
9636                        pw.println(r);
9637                        if (dumpAll) {
9638                            r.dump(pw, "    ");
9639                            needSep = true;
9640                        } else {
9641                            pw.print("    app=");
9642                            pw.println(r.app);
9643                            pw.print("    created=");
9644                            TimeUtils.formatDuration(r.createTime, nowReal, pw);
9645                            pw.print(" started=");
9646                            pw.print(r.startRequested);
9647                            pw.print(" connections=");
9648                            pw.println(r.connections.size());
9649                            if (r.connections.size() > 0) {
9650                                pw.println("    Connections:");
9651                                for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9652                                    for (int i = 0; i < clist.size(); i++) {
9653                                        ConnectionRecord conn = clist.get(i);
9654                                        pw.print("      ");
9655                                        pw.print(conn.binding.intent.intent.getIntent()
9656                                                .toShortString(false, false, false, false));
9657                                        pw.print(" -> ");
9658                                        ProcessRecord proc = conn.binding.client;
9659                                        pw.println(proc != null ? proc.toShortString() : "null");
9660                                    }
9661                                }
9662                            }
9663                        }
9664                        if (dumpClient && r.app != null && r.app.thread != null) {
9665                            pw.println("    Client:");
9666                            pw.flush();
9667                            try {
9668                                TransferPipe tp = new TransferPipe();
9669                                try {
9670                                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
9671                                            r, args);
9672                                    tp.setBufferPrefix("      ");
9673                                    // Short timeout, since blocking here can
9674                                    // deadlock with the application.
9675                                    tp.go(fd, 2000);
9676                                } finally {
9677                                    tp.kill();
9678                                }
9679                            } catch (IOException e) {
9680                                pw.println("      Failure while dumping the service: " + e);
9681                            } catch (RemoteException e) {
9682                                pw.println("      Got a RemoteException while dumping the service");
9683                            }
9684                            needSep = true;
9685                        }
9686                    }
9687                    needSep = printed;
9688                }
9689            }
9690        } catch (RemoteException re) {
9691
9692        }
9693
9694        if (mPendingServices.size() > 0) {
9695            boolean printed = false;
9696            for (int i=0; i<mPendingServices.size(); i++) {
9697                ServiceRecord r = mPendingServices.get(i);
9698                if (!matcher.match(r, r.name)) {
9699                    continue;
9700                }
9701                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9702                    continue;
9703                }
9704                if (!printed) {
9705                    if (needSep) pw.println(" ");
9706                    needSep = true;
9707                    pw.println("  Pending services:");
9708                    printed = true;
9709                }
9710                pw.print("  * Pending "); pw.println(r);
9711                r.dump(pw, "    ");
9712            }
9713            needSep = true;
9714        }
9715
9716        if (mRestartingServices.size() > 0) {
9717            boolean printed = false;
9718            for (int i=0; i<mRestartingServices.size(); i++) {
9719                ServiceRecord r = mRestartingServices.get(i);
9720                if (!matcher.match(r, r.name)) {
9721                    continue;
9722                }
9723                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9724                    continue;
9725                }
9726                if (!printed) {
9727                    if (needSep) pw.println(" ");
9728                    needSep = true;
9729                    pw.println("  Restarting services:");
9730                    printed = true;
9731                }
9732                pw.print("  * Restarting "); pw.println(r);
9733                r.dump(pw, "    ");
9734            }
9735            needSep = true;
9736        }
9737
9738        if (mStoppingServices.size() > 0) {
9739            boolean printed = false;
9740            for (int i=0; i<mStoppingServices.size(); i++) {
9741                ServiceRecord r = mStoppingServices.get(i);
9742                if (!matcher.match(r, r.name)) {
9743                    continue;
9744                }
9745                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9746                    continue;
9747                }
9748                if (!printed) {
9749                    if (needSep) pw.println(" ");
9750                    needSep = true;
9751                    pw.println("  Stopping services:");
9752                    printed = true;
9753                }
9754                pw.print("  * Stopping "); pw.println(r);
9755                r.dump(pw, "    ");
9756            }
9757            needSep = true;
9758        }
9759
9760        if (dumpAll) {
9761            if (mServiceConnections.size() > 0) {
9762                boolean printed = false;
9763                Iterator<ArrayList<ConnectionRecord>> it
9764                        = mServiceConnections.values().iterator();
9765                while (it.hasNext()) {
9766                    ArrayList<ConnectionRecord> r = it.next();
9767                    for (int i=0; i<r.size(); i++) {
9768                        ConnectionRecord cr = r.get(i);
9769                        if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9770                            continue;
9771                        }
9772                        if (dumpPackage != null && (cr.binding.client == null
9773                                || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9774                            continue;
9775                        }
9776                        if (!printed) {
9777                            if (needSep) pw.println(" ");
9778                            needSep = true;
9779                            pw.println("  Connection bindings to services:");
9780                            printed = true;
9781                        }
9782                        pw.print("  * "); pw.println(cr);
9783                        cr.dump(pw, "    ");
9784                    }
9785                }
9786                needSep = true;
9787            }
9788        }
9789
9790        return needSep;
9791    }
9792
9793    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9794            int opti, boolean dumpAll, String dumpPackage) {
9795        boolean needSep = true;
9796
9797        ItemMatcher matcher = new ItemMatcher();
9798        matcher.build(args, opti);
9799
9800        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9801
9802        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9803
9804        if (mLaunchingProviders.size() > 0) {
9805            boolean printed = false;
9806            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9807                ContentProviderRecord r = mLaunchingProviders.get(i);
9808                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9809                    continue;
9810                }
9811                if (!printed) {
9812                    if (needSep) pw.println(" ");
9813                    needSep = true;
9814                    pw.println("  Launching content providers:");
9815                    printed = true;
9816                }
9817                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9818                        pw.println(r);
9819            }
9820        }
9821
9822        if (mGrantedUriPermissions.size() > 0) {
9823            if (needSep) pw.println();
9824            needSep = true;
9825            pw.println("Granted Uri Permissions:");
9826            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9827                int uid = mGrantedUriPermissions.keyAt(i);
9828                HashMap<Uri, UriPermission> perms
9829                        = mGrantedUriPermissions.valueAt(i);
9830                pw.print("  * UID "); pw.print(uid);
9831                        pw.println(" holds:");
9832                for (UriPermission perm : perms.values()) {
9833                    pw.print("    "); pw.println(perm);
9834                    if (dumpAll) {
9835                        perm.dump(pw, "      ");
9836                    }
9837                }
9838            }
9839            needSep = true;
9840        }
9841
9842        return needSep;
9843    }
9844
9845    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9846            int opti, boolean dumpAll, String dumpPackage) {
9847        boolean needSep = false;
9848
9849        if (mIntentSenderRecords.size() > 0) {
9850            boolean printed = false;
9851            Iterator<WeakReference<PendingIntentRecord>> it
9852                    = mIntentSenderRecords.values().iterator();
9853            while (it.hasNext()) {
9854                WeakReference<PendingIntentRecord> ref = it.next();
9855                PendingIntentRecord rec = ref != null ? ref.get(): null;
9856                if (dumpPackage != null && (rec == null
9857                        || !dumpPackage.equals(rec.key.packageName))) {
9858                    continue;
9859                }
9860                if (!printed) {
9861                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9862                    printed = true;
9863                }
9864                needSep = true;
9865                if (rec != null) {
9866                    pw.print("  * "); pw.println(rec);
9867                    if (dumpAll) {
9868                        rec.dump(pw, "    ");
9869                    }
9870                } else {
9871                    pw.print("  * "); pw.println(ref);
9872                }
9873            }
9874        }
9875
9876        return needSep;
9877    }
9878
9879    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9880            String prefix, String label, boolean complete, boolean brief, boolean client,
9881            String dumpPackage) {
9882        TaskRecord lastTask = null;
9883        boolean needNL = false;
9884        final String innerPrefix = prefix + "      ";
9885        final String[] args = new String[0];
9886        for (int i=list.size()-1; i>=0; i--) {
9887            final ActivityRecord r = (ActivityRecord)list.get(i);
9888            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9889                continue;
9890            }
9891            final boolean full = !brief && (complete || !r.isInHistory());
9892            if (needNL) {
9893                pw.println(" ");
9894                needNL = false;
9895            }
9896            if (lastTask != r.task) {
9897                lastTask = r.task;
9898                pw.print(prefix);
9899                pw.print(full ? "* " : "  ");
9900                pw.println(lastTask);
9901                if (full) {
9902                    lastTask.dump(pw, prefix + "  ");
9903                } else if (complete) {
9904                    // Complete + brief == give a summary.  Isn't that obvious?!?
9905                    if (lastTask.intent != null) {
9906                        pw.print(prefix); pw.print("  ");
9907                                pw.println(lastTask.intent.toInsecureStringWithClip());
9908                    }
9909                }
9910            }
9911            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9912            pw.print(" #"); pw.print(i); pw.print(": ");
9913            pw.println(r);
9914            if (full) {
9915                r.dump(pw, innerPrefix);
9916            } else if (complete) {
9917                // Complete + brief == give a summary.  Isn't that obvious?!?
9918                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9919                if (r.app != null) {
9920                    pw.print(innerPrefix); pw.println(r.app);
9921                }
9922            }
9923            if (client && r.app != null && r.app.thread != null) {
9924                // flush anything that is already in the PrintWriter since the thread is going
9925                // to write to the file descriptor directly
9926                pw.flush();
9927                try {
9928                    TransferPipe tp = new TransferPipe();
9929                    try {
9930                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9931                                r.appToken, innerPrefix, args);
9932                        // Short timeout, since blocking here can
9933                        // deadlock with the application.
9934                        tp.go(fd, 2000);
9935                    } finally {
9936                        tp.kill();
9937                    }
9938                } catch (IOException e) {
9939                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9940                } catch (RemoteException e) {
9941                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9942                }
9943                needNL = true;
9944            }
9945        }
9946    }
9947
9948    private static String buildOomTag(String prefix, String space, int val, int base) {
9949        if (val == base) {
9950            if (space == null) return prefix;
9951            return prefix + "  ";
9952        }
9953        return prefix + "+" + Integer.toString(val-base);
9954    }
9955
9956    private static final int dumpProcessList(PrintWriter pw,
9957            ActivityManagerService service, List list,
9958            String prefix, String normalLabel, String persistentLabel,
9959            String dumpPackage) {
9960        int numPers = 0;
9961        final int N = list.size()-1;
9962        for (int i=N; i>=0; i--) {
9963            ProcessRecord r = (ProcessRecord)list.get(i);
9964            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9965                continue;
9966            }
9967            pw.println(String.format("%s%s #%2d: %s",
9968                    prefix, (r.persistent ? persistentLabel : normalLabel),
9969                    i, r.toString()));
9970            if (r.persistent) {
9971                numPers++;
9972            }
9973        }
9974        return numPers;
9975    }
9976
9977    private static final boolean dumpProcessOomList(PrintWriter pw,
9978            ActivityManagerService service, List<ProcessRecord> origList,
9979            String prefix, String normalLabel, String persistentLabel,
9980            boolean inclDetails, String dumpPackage) {
9981
9982        ArrayList<Pair<ProcessRecord, Integer>> list
9983                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9984        for (int i=0; i<origList.size(); i++) {
9985            ProcessRecord r = origList.get(i);
9986            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9987                continue;
9988            }
9989            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9990        }
9991
9992        if (list.size() <= 0) {
9993            return false;
9994        }
9995
9996        Comparator<Pair<ProcessRecord, Integer>> comparator
9997                = new Comparator<Pair<ProcessRecord, Integer>>() {
9998            @Override
9999            public int compare(Pair<ProcessRecord, Integer> object1,
10000                    Pair<ProcessRecord, Integer> object2) {
10001                if (object1.first.setAdj != object2.first.setAdj) {
10002                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10003                }
10004                if (object1.second.intValue() != object2.second.intValue()) {
10005                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10006                }
10007                return 0;
10008            }
10009        };
10010
10011        Collections.sort(list, comparator);
10012
10013        final long curRealtime = SystemClock.elapsedRealtime();
10014        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10015        final long curUptime = SystemClock.uptimeMillis();
10016        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10017
10018        for (int i=list.size()-1; i>=0; i--) {
10019            ProcessRecord r = list.get(i).first;
10020            String oomAdj;
10021            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10022                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10023            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10024                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10025            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10026                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10027            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10028                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10029            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10030                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10031            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10032                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10033            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10034                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10035            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10036                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10037            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10038                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10039            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10040                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10041            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10042                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10043            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10044                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10045            } else {
10046                oomAdj = Integer.toString(r.setAdj);
10047            }
10048            String schedGroup;
10049            switch (r.setSchedGroup) {
10050                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10051                    schedGroup = "B";
10052                    break;
10053                case Process.THREAD_GROUP_DEFAULT:
10054                    schedGroup = "F";
10055                    break;
10056                default:
10057                    schedGroup = Integer.toString(r.setSchedGroup);
10058                    break;
10059            }
10060            String foreground;
10061            if (r.foregroundActivities) {
10062                foreground = "A";
10063            } else if (r.foregroundServices) {
10064                foreground = "S";
10065            } else {
10066                foreground = " ";
10067            }
10068            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10069                    prefix, (r.persistent ? persistentLabel : normalLabel),
10070                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10071                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10072            if (r.adjSource != null || r.adjTarget != null) {
10073                pw.print(prefix);
10074                pw.print("    ");
10075                if (r.adjTarget instanceof ComponentName) {
10076                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10077                } else if (r.adjTarget != null) {
10078                    pw.print(r.adjTarget.toString());
10079                } else {
10080                    pw.print("{null}");
10081                }
10082                pw.print("<=");
10083                if (r.adjSource instanceof ProcessRecord) {
10084                    pw.print("Proc{");
10085                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10086                    pw.println("}");
10087                } else if (r.adjSource != null) {
10088                    pw.println(r.adjSource.toString());
10089                } else {
10090                    pw.println("{null}");
10091                }
10092            }
10093            if (inclDetails) {
10094                pw.print(prefix);
10095                pw.print("    ");
10096                pw.print("oom: max="); pw.print(r.maxAdj);
10097                pw.print(" hidden="); pw.print(r.hiddenAdj);
10098                pw.print(" curRaw="); pw.print(r.curRawAdj);
10099                pw.print(" setRaw="); pw.print(r.setRawAdj);
10100                pw.print(" cur="); pw.print(r.curAdj);
10101                pw.print(" set="); pw.println(r.setAdj);
10102                pw.print(prefix);
10103                pw.print("    ");
10104                pw.print("keeping="); pw.print(r.keeping);
10105                pw.print(" hidden="); pw.print(r.hidden);
10106                pw.print(" empty="); pw.print(r.empty);
10107                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10108
10109                if (!r.keeping) {
10110                    if (r.lastWakeTime != 0) {
10111                        long wtime;
10112                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10113                        synchronized (stats) {
10114                            wtime = stats.getProcessWakeTime(r.info.uid,
10115                                    r.pid, curRealtime);
10116                        }
10117                        long timeUsed = wtime - r.lastWakeTime;
10118                        pw.print(prefix);
10119                        pw.print("    ");
10120                        pw.print("keep awake over ");
10121                        TimeUtils.formatDuration(realtimeSince, pw);
10122                        pw.print(" used ");
10123                        TimeUtils.formatDuration(timeUsed, pw);
10124                        pw.print(" (");
10125                        pw.print((timeUsed*100)/realtimeSince);
10126                        pw.println("%)");
10127                    }
10128                    if (r.lastCpuTime != 0) {
10129                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10130                        pw.print(prefix);
10131                        pw.print("    ");
10132                        pw.print("run cpu over ");
10133                        TimeUtils.formatDuration(uptimeSince, pw);
10134                        pw.print(" used ");
10135                        TimeUtils.formatDuration(timeUsed, pw);
10136                        pw.print(" (");
10137                        pw.print((timeUsed*100)/uptimeSince);
10138                        pw.println("%)");
10139                    }
10140                }
10141            }
10142        }
10143        return true;
10144    }
10145
10146    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10147        ArrayList<ProcessRecord> procs;
10148        synchronized (this) {
10149            if (args != null && args.length > start
10150                    && args[start].charAt(0) != '-') {
10151                procs = new ArrayList<ProcessRecord>();
10152                int pid = -1;
10153                try {
10154                    pid = Integer.parseInt(args[start]);
10155                } catch (NumberFormatException e) {
10156
10157                }
10158                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10159                    ProcessRecord proc = mLruProcesses.get(i);
10160                    if (proc.pid == pid) {
10161                        procs.add(proc);
10162                    } else if (proc.processName.equals(args[start])) {
10163                        procs.add(proc);
10164                    }
10165                }
10166                if (procs.size() <= 0) {
10167                    pw.println("No process found for: " + args[start]);
10168                    return null;
10169                }
10170            } else {
10171                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10172            }
10173        }
10174        return procs;
10175    }
10176
10177    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10178            PrintWriter pw, String[] args) {
10179        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10180        if (procs == null) {
10181            return;
10182        }
10183
10184        long uptime = SystemClock.uptimeMillis();
10185        long realtime = SystemClock.elapsedRealtime();
10186        pw.println("Applications Graphics Acceleration Info:");
10187        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10188
10189        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10190            ProcessRecord r = procs.get(i);
10191            if (r.thread != null) {
10192                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10193                pw.flush();
10194                try {
10195                    TransferPipe tp = new TransferPipe();
10196                    try {
10197                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10198                        tp.go(fd);
10199                    } finally {
10200                        tp.kill();
10201                    }
10202                } catch (IOException e) {
10203                    pw.println("Failure while dumping the app: " + r);
10204                    pw.flush();
10205                } catch (RemoteException e) {
10206                    pw.println("Got a RemoteException while dumping the app " + r);
10207                    pw.flush();
10208                }
10209            }
10210        }
10211    }
10212
10213    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10214        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10215        if (procs == null) {
10216            return;
10217        }
10218
10219        pw.println("Applications Database Info:");
10220
10221        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10222            ProcessRecord r = procs.get(i);
10223            if (r.thread != null) {
10224                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10225                pw.flush();
10226                try {
10227                    TransferPipe tp = new TransferPipe();
10228                    try {
10229                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10230                        tp.go(fd);
10231                    } finally {
10232                        tp.kill();
10233                    }
10234                } catch (IOException e) {
10235                    pw.println("Failure while dumping the app: " + r);
10236                    pw.flush();
10237                } catch (RemoteException e) {
10238                    pw.println("Got a RemoteException while dumping the app " + r);
10239                    pw.flush();
10240                }
10241            }
10242        }
10243    }
10244
10245    final static class MemItem {
10246        final String label;
10247        final String shortLabel;
10248        final long pss;
10249        final int id;
10250        ArrayList<MemItem> subitems;
10251
10252        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10253            label = _label;
10254            shortLabel = _shortLabel;
10255            pss = _pss;
10256            id = _id;
10257        }
10258    }
10259
10260    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10261            boolean sort) {
10262        if (sort) {
10263            Collections.sort(items, new Comparator<MemItem>() {
10264                @Override
10265                public int compare(MemItem lhs, MemItem rhs) {
10266                    if (lhs.pss < rhs.pss) {
10267                        return 1;
10268                    } else if (lhs.pss > rhs.pss) {
10269                        return -1;
10270                    }
10271                    return 0;
10272                }
10273            });
10274        }
10275
10276        for (int i=0; i<items.size(); i++) {
10277            MemItem mi = items.get(i);
10278            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10279            if (mi.subitems != null) {
10280                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10281            }
10282        }
10283    }
10284
10285    // These are in KB.
10286    static final long[] DUMP_MEM_BUCKETS = new long[] {
10287        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10288        120*1024, 160*1024, 200*1024,
10289        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10290        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10291    };
10292
10293    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10294            boolean stackLike) {
10295        int start = label.lastIndexOf('.');
10296        if (start >= 0) start++;
10297        else start = 0;
10298        int end = label.length();
10299        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10300            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10301                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10302                out.append(bucket);
10303                out.append(stackLike ? "MB." : "MB ");
10304                out.append(label, start, end);
10305                return;
10306            }
10307        }
10308        out.append(memKB/1024);
10309        out.append(stackLike ? "MB." : "MB ");
10310        out.append(label, start, end);
10311    }
10312
10313    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10314            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10315            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10316            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10317            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10318    };
10319    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10320            "System", "Persistent", "Foreground",
10321            "Visible", "Perceptible", "Heavy Weight",
10322            "Backup", "A Services", "Home", "Previous",
10323            "B Services", "Background"
10324    };
10325
10326    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10327            PrintWriter pw, String prefix, String[] args, boolean brief,
10328            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10329        boolean dumpAll = false;
10330        boolean oomOnly = false;
10331
10332        int opti = 0;
10333        while (opti < args.length) {
10334            String opt = args[opti];
10335            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10336                break;
10337            }
10338            opti++;
10339            if ("-a".equals(opt)) {
10340                dumpAll = true;
10341            } else if ("--oom".equals(opt)) {
10342                oomOnly = true;
10343            } else if ("-h".equals(opt)) {
10344                pw.println("meminfo dump options: [-a] [--oom] [process]");
10345                pw.println("  -a: include all available information for each process.");
10346                pw.println("  --oom: only show processes organized by oom adj.");
10347                pw.println("If [process] is specified it can be the name or ");
10348                pw.println("pid of a specific process to dump.");
10349                return;
10350            } else {
10351                pw.println("Unknown argument: " + opt + "; use -h for help");
10352            }
10353        }
10354
10355        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10356        if (procs == null) {
10357            return;
10358        }
10359
10360        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10361        long uptime = SystemClock.uptimeMillis();
10362        long realtime = SystemClock.elapsedRealtime();
10363
10364        if (procs.size() == 1 || isCheckinRequest) {
10365            dumpAll = true;
10366        }
10367
10368        if (isCheckinRequest) {
10369            // short checkin version
10370            pw.println(uptime + "," + realtime);
10371            pw.flush();
10372        } else {
10373            pw.println("Applications Memory Usage (kB):");
10374            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10375        }
10376
10377        String[] innerArgs = new String[args.length-opti];
10378        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10379
10380        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10381        long nativePss=0, dalvikPss=0, otherPss=0;
10382        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10383
10384        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10385        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10386                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10387
10388        long totalPss = 0;
10389
10390        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10391            ProcessRecord r = procs.get(i);
10392            if (r.thread != null) {
10393                if (!isCheckinRequest && dumpAll) {
10394                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10395                    pw.flush();
10396                }
10397                Debug.MemoryInfo mi = null;
10398                if (dumpAll) {
10399                    try {
10400                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10401                    } catch (RemoteException e) {
10402                        if (!isCheckinRequest) {
10403                            pw.println("Got RemoteException!");
10404                            pw.flush();
10405                        }
10406                    }
10407                } else {
10408                    mi = new Debug.MemoryInfo();
10409                    Debug.getMemoryInfo(r.pid, mi);
10410                }
10411
10412                if (!isCheckinRequest && mi != null) {
10413                    long myTotalPss = mi.getTotalPss();
10414                    totalPss += myTotalPss;
10415                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10416                            r.processName, myTotalPss, 0);
10417                    procMems.add(pssItem);
10418
10419                    nativePss += mi.nativePss;
10420                    dalvikPss += mi.dalvikPss;
10421                    otherPss += mi.otherPss;
10422                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10423                        long mem = mi.getOtherPss(j);
10424                        miscPss[j] += mem;
10425                        otherPss -= mem;
10426                    }
10427
10428                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10429                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10430                                || oomIndex == (oomPss.length-1)) {
10431                            oomPss[oomIndex] += myTotalPss;
10432                            if (oomProcs[oomIndex] == null) {
10433                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10434                            }
10435                            oomProcs[oomIndex].add(pssItem);
10436                            break;
10437                        }
10438                    }
10439                }
10440            }
10441        }
10442
10443        if (!isCheckinRequest && procs.size() > 1) {
10444            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10445
10446            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10447            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10448            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10449            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10450                String label = Debug.MemoryInfo.getOtherLabel(j);
10451                catMems.add(new MemItem(label, label, miscPss[j], j));
10452            }
10453
10454            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10455            for (int j=0; j<oomPss.length; j++) {
10456                if (oomPss[j] != 0) {
10457                    String label = DUMP_MEM_OOM_LABEL[j];
10458                    MemItem item = new MemItem(label, label, oomPss[j],
10459                            DUMP_MEM_OOM_ADJ[j]);
10460                    item.subitems = oomProcs[j];
10461                    oomMems.add(item);
10462                }
10463            }
10464
10465            if (outTag != null || outStack != null) {
10466                if (outTag != null) {
10467                    appendMemBucket(outTag, totalPss, "total", false);
10468                }
10469                if (outStack != null) {
10470                    appendMemBucket(outStack, totalPss, "total", true);
10471                }
10472                boolean firstLine = true;
10473                for (int i=0; i<oomMems.size(); i++) {
10474                    MemItem miCat = oomMems.get(i);
10475                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10476                        continue;
10477                    }
10478                    if (miCat.id < ProcessList.SERVICE_ADJ
10479                            || miCat.id == ProcessList.HOME_APP_ADJ
10480                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10481                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10482                            outTag.append(" / ");
10483                        }
10484                        if (outStack != null) {
10485                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10486                                if (firstLine) {
10487                                    outStack.append(":");
10488                                    firstLine = false;
10489                                }
10490                                outStack.append("\n\t at ");
10491                            } else {
10492                                outStack.append("$");
10493                            }
10494                        }
10495                        for (int j=0; j<miCat.subitems.size(); j++) {
10496                            MemItem mi = miCat.subitems.get(j);
10497                            if (j > 0) {
10498                                if (outTag != null) {
10499                                    outTag.append(" ");
10500                                }
10501                                if (outStack != null) {
10502                                    outStack.append("$");
10503                                }
10504                            }
10505                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10506                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10507                            }
10508                            if (outStack != null) {
10509                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10510                            }
10511                        }
10512                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10513                            outStack.append("(");
10514                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10515                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10516                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10517                                    outStack.append(":");
10518                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10519                                }
10520                            }
10521                            outStack.append(")");
10522                        }
10523                    }
10524                }
10525            }
10526
10527            if (!brief && !oomOnly) {
10528                pw.println();
10529                pw.println("Total PSS by process:");
10530                dumpMemItems(pw, "  ", procMems, true);
10531                pw.println();
10532            }
10533            pw.println("Total PSS by OOM adjustment:");
10534            dumpMemItems(pw, "  ", oomMems, false);
10535            if (!oomOnly) {
10536                PrintWriter out = categoryPw != null ? categoryPw : pw;
10537                out.println();
10538                out.println("Total PSS by category:");
10539                dumpMemItems(out, "  ", catMems, true);
10540            }
10541            pw.println();
10542            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10543            final int[] SINGLE_LONG_FORMAT = new int[] {
10544                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10545            };
10546            long[] longOut = new long[1];
10547            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10548                    SINGLE_LONG_FORMAT, null, longOut, null);
10549            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10550            longOut[0] = 0;
10551            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10552                    SINGLE_LONG_FORMAT, null, longOut, null);
10553            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10554            longOut[0] = 0;
10555            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10556                    SINGLE_LONG_FORMAT, null, longOut, null);
10557            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10558            longOut[0] = 0;
10559            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10560                    SINGLE_LONG_FORMAT, null, longOut, null);
10561            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10562            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10563                    pw.print(shared); pw.println(" kB");
10564            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10565                    pw.print(voltile); pw.println(" kB volatile");
10566        }
10567    }
10568
10569    /**
10570     * Searches array of arguments for the specified string
10571     * @param args array of argument strings
10572     * @param value value to search for
10573     * @return true if the value is contained in the array
10574     */
10575    private static boolean scanArgs(String[] args, String value) {
10576        if (args != null) {
10577            for (String arg : args) {
10578                if (value.equals(arg)) {
10579                    return true;
10580                }
10581            }
10582        }
10583        return false;
10584    }
10585
10586    private final void killServicesLocked(ProcessRecord app,
10587            boolean allowRestart) {
10588        // Report disconnected services.
10589        if (false) {
10590            // XXX we are letting the client link to the service for
10591            // death notifications.
10592            if (app.services.size() > 0) {
10593                Iterator<ServiceRecord> it = app.services.iterator();
10594                while (it.hasNext()) {
10595                    ServiceRecord r = it.next();
10596                    if (r.connections.size() > 0) {
10597                        Iterator<ArrayList<ConnectionRecord>> jt
10598                                = r.connections.values().iterator();
10599                        while (jt.hasNext()) {
10600                            ArrayList<ConnectionRecord> cl = jt.next();
10601                            for (int i=0; i<cl.size(); i++) {
10602                                ConnectionRecord c = cl.get(i);
10603                                if (c.binding.client != app) {
10604                                    try {
10605                                        //c.conn.connected(r.className, null);
10606                                    } catch (Exception e) {
10607                                        // todo: this should be asynchronous!
10608                                        Slog.w(TAG, "Exception thrown disconnected servce "
10609                                              + r.shortName
10610                                              + " from app " + app.processName, e);
10611                                    }
10612                                }
10613                            }
10614                        }
10615                    }
10616                }
10617            }
10618        }
10619
10620        // Clean up any connections this application has to other services.
10621        if (app.connections.size() > 0) {
10622            Iterator<ConnectionRecord> it = app.connections.iterator();
10623            while (it.hasNext()) {
10624                ConnectionRecord r = it.next();
10625                removeConnectionLocked(r, app, null);
10626            }
10627        }
10628        app.connections.clear();
10629
10630        if (app.services.size() != 0) {
10631            // Any services running in the application need to be placed
10632            // back in the pending list.
10633            Iterator<ServiceRecord> it = app.services.iterator();
10634            while (it.hasNext()) {
10635                ServiceRecord sr = it.next();
10636                synchronized (sr.stats.getBatteryStats()) {
10637                    sr.stats.stopLaunchedLocked();
10638                }
10639                sr.app = null;
10640                sr.isolatedProc = null;
10641                sr.executeNesting = 0;
10642                if (mStoppingServices.remove(sr)) {
10643                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10644                }
10645
10646                boolean hasClients = sr.bindings.size() > 0;
10647                if (hasClients) {
10648                    Iterator<IntentBindRecord> bindings
10649                            = sr.bindings.values().iterator();
10650                    while (bindings.hasNext()) {
10651                        IntentBindRecord b = bindings.next();
10652                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
10653                                + ": shouldUnbind=" + b.hasBound);
10654                        b.binder = null;
10655                        b.requested = b.received = b.hasBound = false;
10656                    }
10657                }
10658
10659                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10660                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
10661                    Slog.w(TAG, "Service crashed " + sr.crashCount
10662                            + " times, stopping: " + sr);
10663                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
10664                            sr.crashCount, sr.shortName, app.pid);
10665                    bringDownServiceLocked(sr, true);
10666                } else if (!allowRestart) {
10667                    bringDownServiceLocked(sr, true);
10668                } else {
10669                    boolean canceled = scheduleServiceRestartLocked(sr, true);
10670
10671                    // Should the service remain running?  Note that in the
10672                    // extreme case of so many attempts to deliver a command
10673                    // that it failed we also will stop it here.
10674                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10675                        if (sr.pendingStarts.size() == 0) {
10676                            sr.startRequested = false;
10677                            if (!hasClients) {
10678                                // Whoops, no reason to restart!
10679                                bringDownServiceLocked(sr, true);
10680                            }
10681                        }
10682                    }
10683                }
10684            }
10685
10686            if (!allowRestart) {
10687                app.services.clear();
10688            }
10689        }
10690
10691        // Make sure we have no more records on the stopping list.
10692        int i = mStoppingServices.size();
10693        while (i > 0) {
10694            i--;
10695            ServiceRecord sr = mStoppingServices.get(i);
10696            if (sr.app == app) {
10697                mStoppingServices.remove(i);
10698                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10699            }
10700        }
10701
10702        app.executingServices.clear();
10703    }
10704
10705    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10706            ContentProviderRecord cpr, boolean always) {
10707        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10708
10709        if (!inLaunching || always) {
10710            synchronized (cpr) {
10711                cpr.launchingApp = null;
10712                cpr.notifyAll();
10713            }
10714            mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10715            String names[] = cpr.info.authority.split(";");
10716            for (int j = 0; j < names.length; j++) {
10717                mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10718            }
10719        }
10720
10721        for (int i=0; i<cpr.connections.size(); i++) {
10722            ContentProviderConnection conn = cpr.connections.get(i);
10723            if (conn.waiting) {
10724                // If this connection is waiting for the provider, then we don't
10725                // need to mess with its process unless we are always removing
10726                // or for some reason the provider is not currently launching.
10727                if (inLaunching && !always) {
10728                    continue;
10729                }
10730            }
10731            ProcessRecord capp = conn.client;
10732            conn.dead = true;
10733            if (conn.stableCount > 0) {
10734                if (!capp.persistent && capp.thread != null
10735                        && capp.pid != 0
10736                        && capp.pid != MY_PID) {
10737                    Slog.i(TAG, "Kill " + capp.processName
10738                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10739                            + " in dying process " + (proc != null ? proc.processName : "??"));
10740                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10741                            capp.processName, capp.setAdj, "dying provider "
10742                                    + cpr.name.toShortString());
10743                    Process.killProcessQuiet(capp.pid);
10744                }
10745            } else if (capp.thread != null && conn.provider.provider != null) {
10746                try {
10747                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10748                } catch (RemoteException e) {
10749                }
10750                // In the protocol here, we don't expect the client to correctly
10751                // clean up this connection, we'll just remove it.
10752                cpr.connections.remove(i);
10753                conn.client.conProviders.remove(conn);
10754            }
10755        }
10756
10757        if (inLaunching && always) {
10758            mLaunchingProviders.remove(cpr);
10759        }
10760        return inLaunching;
10761    }
10762
10763    /**
10764     * Main code for cleaning up a process when it has gone away.  This is
10765     * called both as a result of the process dying, or directly when stopping
10766     * a process when running in single process mode.
10767     */
10768    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10769            boolean restarting, boolean allowRestart, int index) {
10770        if (index >= 0) {
10771            mLruProcesses.remove(index);
10772        }
10773
10774        mProcessesToGc.remove(app);
10775
10776        // Dismiss any open dialogs.
10777        if (app.crashDialog != null) {
10778            app.crashDialog.dismiss();
10779            app.crashDialog = null;
10780        }
10781        if (app.anrDialog != null) {
10782            app.anrDialog.dismiss();
10783            app.anrDialog = null;
10784        }
10785        if (app.waitDialog != null) {
10786            app.waitDialog.dismiss();
10787            app.waitDialog = null;
10788        }
10789
10790        app.crashing = false;
10791        app.notResponding = false;
10792
10793        app.resetPackageList();
10794        app.unlinkDeathRecipient();
10795        app.thread = null;
10796        app.forcingToForeground = null;
10797        app.foregroundServices = false;
10798        app.foregroundActivities = false;
10799        app.hasShownUi = false;
10800        app.hasAboveClient = false;
10801
10802        killServicesLocked(app, allowRestart);
10803
10804        boolean restart = false;
10805
10806        // Remove published content providers.
10807        if (!app.pubProviders.isEmpty()) {
10808            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10809            while (it.hasNext()) {
10810                ContentProviderRecord cpr = it.next();
10811
10812                final boolean always = app.bad || !allowRestart;
10813                if (removeDyingProviderLocked(app, cpr, always) || always) {
10814                    // We left the provider in the launching list, need to
10815                    // restart it.
10816                    restart = true;
10817                }
10818
10819                cpr.provider = null;
10820                cpr.proc = null;
10821            }
10822            app.pubProviders.clear();
10823        }
10824
10825        // Take care of any launching providers waiting for this process.
10826        if (checkAppInLaunchingProvidersLocked(app, false)) {
10827            restart = true;
10828        }
10829
10830        // Unregister from connected content providers.
10831        if (!app.conProviders.isEmpty()) {
10832            for (int i=0; i<app.conProviders.size(); i++) {
10833                ContentProviderConnection conn = app.conProviders.get(i);
10834                conn.provider.connections.remove(conn);
10835            }
10836            app.conProviders.clear();
10837        }
10838
10839        // At this point there may be remaining entries in mLaunchingProviders
10840        // where we were the only one waiting, so they are no longer of use.
10841        // Look for these and clean up if found.
10842        // XXX Commented out for now.  Trying to figure out a way to reproduce
10843        // the actual situation to identify what is actually going on.
10844        if (false) {
10845            for (int i=0; i<mLaunchingProviders.size(); i++) {
10846                ContentProviderRecord cpr = (ContentProviderRecord)
10847                        mLaunchingProviders.get(i);
10848                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10849                    synchronized (cpr) {
10850                        cpr.launchingApp = null;
10851                        cpr.notifyAll();
10852                    }
10853                }
10854            }
10855        }
10856
10857        skipCurrentReceiverLocked(app);
10858
10859        // Unregister any receivers.
10860        if (app.receivers.size() > 0) {
10861            Iterator<ReceiverList> it = app.receivers.iterator();
10862            while (it.hasNext()) {
10863                removeReceiverLocked(it.next());
10864            }
10865            app.receivers.clear();
10866        }
10867
10868        // If the app is undergoing backup, tell the backup manager about it
10869        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10870            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10871            try {
10872                IBackupManager bm = IBackupManager.Stub.asInterface(
10873                        ServiceManager.getService(Context.BACKUP_SERVICE));
10874                bm.agentDisconnected(app.info.packageName);
10875            } catch (RemoteException e) {
10876                // can't happen; backup manager is local
10877            }
10878        }
10879
10880        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10881            ProcessChangeItem item = mPendingProcessChanges.get(i);
10882            if (item.pid == app.pid) {
10883                mPendingProcessChanges.remove(i);
10884                mAvailProcessChanges.add(item);
10885            }
10886        }
10887        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10888
10889        // If the caller is restarting this app, then leave it in its
10890        // current lists and let the caller take care of it.
10891        if (restarting) {
10892            return;
10893        }
10894
10895        if (!app.persistent || app.isolated) {
10896            if (DEBUG_PROCESSES) Slog.v(TAG,
10897                    "Removing non-persistent process during cleanup: " + app);
10898            mProcessNames.remove(app.processName, app.uid);
10899            mIsolatedProcesses.remove(app.uid);
10900            if (mHeavyWeightProcess == app) {
10901                mHeavyWeightProcess = null;
10902                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10903            }
10904        } else if (!app.removed) {
10905            // This app is persistent, so we need to keep its record around.
10906            // If it is not already on the pending app list, add it there
10907            // and start a new process for it.
10908            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10909                mPersistentStartingProcesses.add(app);
10910                restart = true;
10911            }
10912        }
10913        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10914                "Clean-up removing on hold: " + app);
10915        mProcessesOnHold.remove(app);
10916
10917        if (app == mHomeProcess) {
10918            mHomeProcess = null;
10919        }
10920        if (app == mPreviousProcess) {
10921            mPreviousProcess = null;
10922        }
10923
10924        if (restart && !app.isolated) {
10925            // We have components that still need to be running in the
10926            // process, so re-launch it.
10927            mProcessNames.put(app.processName, app.uid, app);
10928            startProcessLocked(app, "restart", app.processName);
10929        } else if (app.pid > 0 && app.pid != MY_PID) {
10930            // Goodbye!
10931            synchronized (mPidsSelfLocked) {
10932                mPidsSelfLocked.remove(app.pid);
10933                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10934            }
10935            app.setPid(0);
10936        }
10937    }
10938
10939    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10940        // Look through the content providers we are waiting to have launched,
10941        // and if any run in this process then either schedule a restart of
10942        // the process or kill the client waiting for it if this process has
10943        // gone bad.
10944        int NL = mLaunchingProviders.size();
10945        boolean restart = false;
10946        for (int i=0; i<NL; i++) {
10947            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10948            if (cpr.launchingApp == app) {
10949                if (!alwaysBad && !app.bad) {
10950                    restart = true;
10951                } else {
10952                    removeDyingProviderLocked(app, cpr, true);
10953                    // cpr should have been removed from mLaunchingProviders
10954                    NL = mLaunchingProviders.size();
10955                    i--;
10956                }
10957            }
10958        }
10959        return restart;
10960    }
10961
10962    // =========================================================
10963    // SERVICES
10964    // =========================================================
10965
10966    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10967        ActivityManager.RunningServiceInfo info =
10968            new ActivityManager.RunningServiceInfo();
10969        info.service = r.name;
10970        if (r.app != null) {
10971            info.pid = r.app.pid;
10972        }
10973        info.uid = r.appInfo.uid;
10974        info.process = r.processName;
10975        info.foreground = r.isForeground;
10976        info.activeSince = r.createTime;
10977        info.started = r.startRequested;
10978        info.clientCount = r.connections.size();
10979        info.crashCount = r.crashCount;
10980        info.lastActivityTime = r.lastActivity;
10981        if (r.isForeground) {
10982            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10983        }
10984        if (r.startRequested) {
10985            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10986        }
10987        if (r.app != null && r.app.pid == MY_PID) {
10988            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10989        }
10990        if (r.app != null && r.app.persistent) {
10991            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10992        }
10993
10994        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10995            for (int i=0; i<connl.size(); i++) {
10996                ConnectionRecord conn = connl.get(i);
10997                if (conn.clientLabel != 0) {
10998                    info.clientPackage = conn.binding.client.info.packageName;
10999                    info.clientLabel = conn.clientLabel;
11000                    return info;
11001                }
11002            }
11003        }
11004        return info;
11005    }
11006
11007    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11008            int flags) {
11009        enforceNotIsolatedCaller("getServices");
11010        synchronized (this) {
11011            ArrayList<ActivityManager.RunningServiceInfo> res
11012                    = new ArrayList<ActivityManager.RunningServiceInfo>();
11013
11014            int userId = UserId.getUserId(Binder.getCallingUid());
11015            if (mServiceMap.getAllServices(userId).size() > 0) {
11016                Iterator<ServiceRecord> it
11017                        = mServiceMap.getAllServices(userId).iterator();
11018                while (it.hasNext() && res.size() < maxNum) {
11019                    res.add(makeRunningServiceInfoLocked(it.next()));
11020                }
11021            }
11022
11023            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11024                ServiceRecord r = mRestartingServices.get(i);
11025                ActivityManager.RunningServiceInfo info =
11026                        makeRunningServiceInfoLocked(r);
11027                info.restarting = r.nextRestartTime;
11028                res.add(info);
11029            }
11030
11031            return res;
11032        }
11033    }
11034
11035    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
11036        enforceNotIsolatedCaller("getRunningServiceControlPanel");
11037        synchronized (this) {
11038            int userId = UserId.getUserId(Binder.getCallingUid());
11039            ServiceRecord r = mServiceMap.getServiceByName(name, userId);
11040            if (r != null) {
11041                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11042                    for (int i=0; i<conn.size(); i++) {
11043                        if (conn.get(i).clientIntent != null) {
11044                            return conn.get(i).clientIntent;
11045                        }
11046                    }
11047                }
11048            }
11049        }
11050        return null;
11051    }
11052
11053    private final ServiceRecord findServiceLocked(ComponentName name,
11054            IBinder token) {
11055        ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
11056        return r == token ? r : null;
11057    }
11058
11059    private final class ServiceLookupResult {
11060        final ServiceRecord record;
11061        final String permission;
11062
11063        ServiceLookupResult(ServiceRecord _record, String _permission) {
11064            record = _record;
11065            permission = _permission;
11066        }
11067    };
11068
11069    private ServiceLookupResult findServiceLocked(Intent service,
11070            String resolvedType, int userId) {
11071        ServiceRecord r = null;
11072        if (service.getComponent() != null) {
11073            r = mServiceMap.getServiceByName(service.getComponent(), userId);
11074        }
11075        if (r == null) {
11076            Intent.FilterComparison filter = new Intent.FilterComparison(service);
11077            r = mServiceMap.getServiceByIntent(filter, userId);
11078        }
11079
11080        if (r == null) {
11081            try {
11082                ResolveInfo rInfo =
11083                    AppGlobals.getPackageManager().resolveService(
11084                                service, resolvedType, 0, userId);
11085                ServiceInfo sInfo =
11086                    rInfo != null ? rInfo.serviceInfo : null;
11087                if (sInfo == null) {
11088                    return null;
11089                }
11090
11091                ComponentName name = new ComponentName(
11092                        sInfo.applicationInfo.packageName, sInfo.name);
11093                r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
11094            } catch (RemoteException ex) {
11095                // pm is in same process, this will never happen.
11096            }
11097        }
11098        if (r != null) {
11099            int callingPid = Binder.getCallingPid();
11100            int callingUid = Binder.getCallingUid();
11101            if (checkComponentPermission(r.permission,
11102                    callingPid, callingUid, r.appInfo.uid, r.exported)
11103                    != PackageManager.PERMISSION_GRANTED) {
11104                if (!r.exported) {
11105                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11106                            + " from pid=" + callingPid
11107                            + ", uid=" + callingUid
11108                            + " that is not exported from uid " + r.appInfo.uid);
11109                    return new ServiceLookupResult(null, "not exported from uid "
11110                            + r.appInfo.uid);
11111                }
11112                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11113                        + " from pid=" + callingPid
11114                        + ", uid=" + callingUid
11115                        + " requires " + r.permission);
11116                return new ServiceLookupResult(null, r.permission);
11117            }
11118            return new ServiceLookupResult(r, null);
11119        }
11120        return null;
11121    }
11122
11123    private class ServiceRestarter implements Runnable {
11124        private ServiceRecord mService;
11125
11126        void setService(ServiceRecord service) {
11127            mService = service;
11128        }
11129
11130        public void run() {
11131            synchronized(ActivityManagerService.this) {
11132                performServiceRestartLocked(mService);
11133            }
11134        }
11135    }
11136
11137    private ServiceLookupResult retrieveServiceLocked(Intent service,
11138            String resolvedType, int callingPid, int callingUid, int userId) {
11139        ServiceRecord r = null;
11140        if (DEBUG_SERVICE)
11141            Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
11142                    + " callingUid=" + callingUid);
11143
11144        if (service.getComponent() != null) {
11145            r = mServiceMap.getServiceByName(service.getComponent(), userId);
11146        }
11147        if (r == null) {
11148            Intent.FilterComparison filter = new Intent.FilterComparison(service);
11149            r = mServiceMap.getServiceByIntent(filter, userId);
11150        }
11151        if (r == null) {
11152            try {
11153                ResolveInfo rInfo =
11154                    AppGlobals.getPackageManager().resolveService(
11155                                service, resolvedType, STOCK_PM_FLAGS, userId);
11156                ServiceInfo sInfo =
11157                    rInfo != null ? rInfo.serviceInfo : null;
11158                if (sInfo == null) {
11159                    Slog.w(TAG, "Unable to start service " + service +
11160                          ": not found");
11161                    return null;
11162                }
11163                if (userId > 0) {
11164                    if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
11165                        userId = 0;
11166                    }
11167                    sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
11168                }
11169                ComponentName name = new ComponentName(
11170                        sInfo.applicationInfo.packageName, sInfo.name);
11171                r = mServiceMap.getServiceByName(name, userId);
11172                if (r == null) {
11173                    Intent.FilterComparison filter = new Intent.FilterComparison(
11174                            service.cloneFilter());
11175                    ServiceRestarter res = new ServiceRestarter();
11176                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11177                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11178                    synchronized (stats) {
11179                        ss = stats.getServiceStatsLocked(
11180                                sInfo.applicationInfo.uid, sInfo.packageName,
11181                                sInfo.name);
11182                    }
11183                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
11184                    res.setService(r);
11185                    mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11186                    mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
11187
11188                    // Make sure this component isn't in the pending list.
11189                    int N = mPendingServices.size();
11190                    for (int i=0; i<N; i++) {
11191                        ServiceRecord pr = mPendingServices.get(i);
11192                        if (pr.name.equals(name)) {
11193                            mPendingServices.remove(i);
11194                            i--;
11195                            N--;
11196                        }
11197                    }
11198                }
11199            } catch (RemoteException ex) {
11200                // pm is in same process, this will never happen.
11201            }
11202        }
11203        if (r != null) {
11204            if (checkComponentPermission(r.permission,
11205                    callingPid, callingUid, r.appInfo.uid, r.exported)
11206                    != PackageManager.PERMISSION_GRANTED) {
11207                if (!r.exported) {
11208                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11209                            + " from pid=" + callingPid
11210                            + ", uid=" + callingUid
11211                            + " that is not exported from uid " + r.appInfo.uid);
11212                    return new ServiceLookupResult(null, "not exported from uid "
11213                            + r.appInfo.uid);
11214                }
11215                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11216                        + " from pid=" + callingPid
11217                        + ", uid=" + callingUid
11218                        + " requires " + r.permission);
11219                return new ServiceLookupResult(null, r.permission);
11220            }
11221            return new ServiceLookupResult(r, null);
11222        }
11223        return null;
11224    }
11225
11226    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11227        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11228                + why + " of " + r + " in app " + r.app);
11229        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11230                + why + " of " + r.shortName);
11231        long now = SystemClock.uptimeMillis();
11232        if (r.executeNesting == 0 && r.app != null) {
11233            if (r.app.executingServices.size() == 0) {
11234                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11235                msg.obj = r.app;
11236                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11237            }
11238            r.app.executingServices.add(r);
11239        }
11240        r.executeNesting++;
11241        r.executingStart = now;
11242    }
11243
11244    private final void sendServiceArgsLocked(ServiceRecord r,
11245            boolean oomAdjusted) {
11246        final int N = r.pendingStarts.size();
11247        if (N == 0) {
11248            return;
11249        }
11250
11251        while (r.pendingStarts.size() > 0) {
11252            try {
11253                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
11254                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11255                        + r + " " + r.intent + " args=" + si.intent);
11256                if (si.intent == null && N > 1) {
11257                    // If somehow we got a dummy null intent in the middle,
11258                    // then skip it.  DO NOT skip a null intent when it is
11259                    // the only one in the list -- this is to support the
11260                    // onStartCommand(null) case.
11261                    continue;
11262                }
11263                si.deliveredTime = SystemClock.uptimeMillis();
11264                r.deliveredStarts.add(si);
11265                si.deliveryCount++;
11266                if (si.neededGrants != null) {
11267                    grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
11268                            si.getUriPermissionsLocked());
11269                }
11270                bumpServiceExecutingLocked(r, "start");
11271                if (!oomAdjusted) {
11272                    oomAdjusted = true;
11273                    updateOomAdjLocked(r.app);
11274                }
11275                int flags = 0;
11276                if (si.deliveryCount > 1) {
11277                    flags |= Service.START_FLAG_RETRY;
11278                }
11279                if (si.doneExecutingCount > 0) {
11280                    flags |= Service.START_FLAG_REDELIVERY;
11281                }
11282                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
11283            } catch (RemoteException e) {
11284                // Remote process gone...  we'll let the normal cleanup take
11285                // care of this.
11286                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
11287                break;
11288            } catch (Exception e) {
11289                Slog.w(TAG, "Unexpected exception", e);
11290                break;
11291            }
11292        }
11293    }
11294
11295    private final boolean requestServiceBindingLocked(ServiceRecord r,
11296            IntentBindRecord i, boolean rebind) {
11297        if (r.app == null || r.app.thread == null) {
11298            // If service is not currently running, can't yet bind.
11299            return false;
11300        }
11301        if ((!i.requested || rebind) && i.apps.size() > 0) {
11302            try {
11303                bumpServiceExecutingLocked(r, "bind");
11304                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11305                if (!rebind) {
11306                    i.requested = true;
11307                }
11308                i.hasBound = true;
11309                i.doRebind = false;
11310            } catch (RemoteException e) {
11311                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
11312                return false;
11313            }
11314        }
11315        return true;
11316    }
11317
11318    private final void requestServiceBindingsLocked(ServiceRecord r) {
11319        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11320        while (bindings.hasNext()) {
11321            IntentBindRecord i = bindings.next();
11322            if (!requestServiceBindingLocked(r, i, false)) {
11323                break;
11324            }
11325        }
11326    }
11327
11328    private final void realStartServiceLocked(ServiceRecord r,
11329            ProcessRecord app) throws RemoteException {
11330        if (app.thread == null) {
11331            throw new RemoteException();
11332        }
11333        if (DEBUG_MU)
11334            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
11335                    + ", ProcessRecord.uid = " + app.uid);
11336        r.app = app;
11337        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
11338
11339        app.services.add(r);
11340        bumpServiceExecutingLocked(r, "create");
11341        updateLruProcessLocked(app, true, true);
11342
11343        boolean created = false;
11344        try {
11345            mStringBuilder.setLength(0);
11346            r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false);
11347            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
11348                    System.identityHashCode(r), r.shortName,
11349                    mStringBuilder.toString(), r.app.pid);
11350            synchronized (r.stats.getBatteryStats()) {
11351                r.stats.startLaunchedLocked();
11352            }
11353            ensurePackageDexOpt(r.serviceInfo.packageName);
11354            app.thread.scheduleCreateService(r, r.serviceInfo,
11355                    compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
11356            r.postNotification();
11357            created = true;
11358        } finally {
11359            if (!created) {
11360                app.services.remove(r);
11361                scheduleServiceRestartLocked(r, false);
11362            }
11363        }
11364
11365        requestServiceBindingsLocked(r);
11366
11367        // If the service is in the started state, and there are no
11368        // pending arguments, then fake up one so its onStartCommand() will
11369        // be called.
11370        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
11371            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11372                    null, null));
11373        }
11374
11375        sendServiceArgsLocked(r, true);
11376    }
11377
11378    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11379            boolean allowCancel) {
11380        boolean canceled = false;
11381
11382        final long now = SystemClock.uptimeMillis();
11383        long minDuration = SERVICE_RESTART_DURATION;
11384        long resetTime = SERVICE_RESET_RUN_DURATION;
11385
11386        if ((r.serviceInfo.applicationInfo.flags
11387                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11388            minDuration /= 4;
11389        }
11390
11391        // Any delivered but not yet finished starts should be put back
11392        // on the pending list.
11393        final int N = r.deliveredStarts.size();
11394        if (N > 0) {
11395            for (int i=N-1; i>=0; i--) {
11396                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
11397                si.removeUriPermissionsLocked();
11398                if (si.intent == null) {
11399                    // We'll generate this again if needed.
11400                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11401                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11402                    r.pendingStarts.add(0, si);
11403                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11404                    dur *= 2;
11405                    if (minDuration < dur) minDuration = dur;
11406                    if (resetTime < dur) resetTime = dur;
11407                } else {
11408                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
11409                            + r.name);
11410                    canceled = true;
11411                }
11412            }
11413            r.deliveredStarts.clear();
11414        }
11415
11416        r.totalRestartCount++;
11417        if (r.restartDelay == 0) {
11418            r.restartCount++;
11419            r.restartDelay = minDuration;
11420        } else {
11421            // If it has been a "reasonably long time" since the service
11422            // was started, then reset our restart duration back to
11423            // the beginning, so we don't infinitely increase the duration
11424            // on a service that just occasionally gets killed (which is
11425            // a normal case, due to process being killed to reclaim memory).
11426            if (now > (r.restartTime+resetTime)) {
11427                r.restartCount = 1;
11428                r.restartDelay = minDuration;
11429            } else {
11430                if ((r.serviceInfo.applicationInfo.flags
11431                        &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11432                    // Services in peristent processes will restart much more
11433                    // quickly, since they are pretty important.  (Think SystemUI).
11434                    r.restartDelay += minDuration/2;
11435                } else {
11436                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11437                    if (r.restartDelay < minDuration) {
11438                        r.restartDelay = minDuration;
11439                    }
11440                }
11441            }
11442        }
11443
11444        r.nextRestartTime = now + r.restartDelay;
11445
11446        // Make sure that we don't end up restarting a bunch of services
11447        // all at the same time.
11448        boolean repeat;
11449        do {
11450            repeat = false;
11451            for (int i=mRestartingServices.size()-1; i>=0; i--) {
11452                ServiceRecord r2 = mRestartingServices.get(i);
11453                if (r2 != r && r.nextRestartTime
11454                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11455                        && r.nextRestartTime
11456                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11457                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11458                    r.restartDelay = r.nextRestartTime - now;
11459                    repeat = true;
11460                    break;
11461                }
11462            }
11463        } while (repeat);
11464
11465        if (!mRestartingServices.contains(r)) {
11466            mRestartingServices.add(r);
11467        }
11468
11469        r.cancelNotification();
11470
11471        mHandler.removeCallbacks(r.restarter);
11472        mHandler.postAtTime(r.restarter, r.nextRestartTime);
11473        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
11474        Slog.w(TAG, "Scheduling restart of crashed service "
11475                + r.shortName + " in " + r.restartDelay + "ms");
11476        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
11477                r.shortName, r.restartDelay);
11478
11479        return canceled;
11480    }
11481
11482    final void performServiceRestartLocked(ServiceRecord r) {
11483        if (!mRestartingServices.contains(r)) {
11484            return;
11485        }
11486        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11487    }
11488
11489    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11490        if (r.restartDelay == 0) {
11491            return false;
11492        }
11493        r.resetRestartCounter();
11494        mRestartingServices.remove(r);
11495        mHandler.removeCallbacks(r.restarter);
11496        return true;
11497    }
11498
11499    private final boolean bringUpServiceLocked(ServiceRecord r,
11500            int intentFlags, boolean whileRestarting) {
11501        //Slog.i(TAG, "Bring up service:");
11502        //r.dump("  ");
11503
11504        if (r.app != null && r.app.thread != null) {
11505            sendServiceArgsLocked(r, false);
11506            return true;
11507        }
11508
11509        if (!whileRestarting && r.restartDelay > 0) {
11510            // If waiting for a restart, then do nothing.
11511            return true;
11512        }
11513
11514        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
11515
11516        // We are now bringing the service up, so no longer in the
11517        // restarting state.
11518        mRestartingServices.remove(r);
11519
11520        // Service is now being launched, its package can't be stopped.
11521        try {
11522            AppGlobals.getPackageManager().setPackageStoppedState(
11523                    r.packageName, false, r.userId);
11524        } catch (RemoteException e) {
11525        } catch (IllegalArgumentException e) {
11526            Slog.w(TAG, "Failed trying to unstop package "
11527                    + r.packageName + ": " + e);
11528        }
11529
11530        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
11531        final String appName = r.processName;
11532        ProcessRecord app;
11533
11534        if (!isolated) {
11535            app = getProcessRecordLocked(appName, r.appInfo.uid);
11536            if (DEBUG_MU)
11537                Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11538            if (app != null && app.thread != null) {
11539                try {
11540                    app.addPackage(r.appInfo.packageName);
11541                    realStartServiceLocked(r, app);
11542                    return true;
11543                } catch (RemoteException e) {
11544                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11545                }
11546
11547                // If a dead object exception was thrown -- fall through to
11548                // restart the application.
11549            }
11550        } else {
11551            // If this service runs in an isolated process, then each time
11552            // we call startProcessLocked() we will get a new isolated
11553            // process, starting another process if we are currently waiting
11554            // for a previous process to come up.  To deal with this, we store
11555            // in the service any current isolated process it is running in or
11556            // waiting to have come up.
11557            app = r.isolatedProc;
11558        }
11559
11560        // Not running -- get it started, and enqueue this service record
11561        // to be executed when the app comes up.
11562        if (app == null) {
11563            if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11564                    "service", r.name, false, isolated)) == null) {
11565                Slog.w(TAG, "Unable to launch app "
11566                        + r.appInfo.packageName + "/"
11567                        + r.appInfo.uid + " for service "
11568                        + r.intent.getIntent() + ": process is bad");
11569                bringDownServiceLocked(r, true);
11570                return false;
11571            }
11572            if (isolated) {
11573                r.isolatedProc = app;
11574            }
11575        }
11576
11577        if (!mPendingServices.contains(r)) {
11578            mPendingServices.add(r);
11579        }
11580
11581        return true;
11582    }
11583
11584    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
11585        //Slog.i(TAG, "Bring down service:");
11586        //r.dump("  ");
11587
11588        // Does it still need to run?
11589        if (!force && r.startRequested) {
11590            return;
11591        }
11592        if (r.connections.size() > 0) {
11593            if (!force) {
11594                // XXX should probably keep a count of the number of auto-create
11595                // connections directly in the service.
11596                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11597                while (it.hasNext()) {
11598                    ArrayList<ConnectionRecord> cr = it.next();
11599                    for (int i=0; i<cr.size(); i++) {
11600                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11601                            return;
11602                        }
11603                    }
11604                }
11605            }
11606
11607            // Report to all of the connections that the service is no longer
11608            // available.
11609            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11610            while (it.hasNext()) {
11611                ArrayList<ConnectionRecord> c = it.next();
11612                for (int i=0; i<c.size(); i++) {
11613                    ConnectionRecord cr = c.get(i);
11614                    // There is still a connection to the service that is
11615                    // being brought down.  Mark it as dead.
11616                    cr.serviceDead = true;
11617                    try {
11618                        cr.conn.connected(r.name, null);
11619                    } catch (Exception e) {
11620                        Slog.w(TAG, "Failure disconnecting service " + r.name +
11621                              " to connection " + c.get(i).conn.asBinder() +
11622                              " (in " + c.get(i).binding.client.processName + ")", e);
11623                    }
11624                }
11625            }
11626        }
11627
11628        // Tell the service that it has been unbound.
11629        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11630            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11631            while (it.hasNext()) {
11632                IntentBindRecord ibr = it.next();
11633                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
11634                        + ": hasBound=" + ibr.hasBound);
11635                if (r.app != null && r.app.thread != null && ibr.hasBound) {
11636                    try {
11637                        bumpServiceExecutingLocked(r, "bring down unbind");
11638                        updateOomAdjLocked(r.app);
11639                        ibr.hasBound = false;
11640                        r.app.thread.scheduleUnbindService(r,
11641                                ibr.intent.getIntent());
11642                    } catch (Exception e) {
11643                        Slog.w(TAG, "Exception when unbinding service "
11644                                + r.shortName, e);
11645                        serviceDoneExecutingLocked(r, true);
11646                    }
11647                }
11648            }
11649        }
11650
11651        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
11652        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
11653                System.identityHashCode(r), r.shortName,
11654                (r.app != null) ? r.app.pid : -1);
11655
11656        mServiceMap.removeServiceByName(r.name, r.userId);
11657        mServiceMap.removeServiceByIntent(r.intent, r.userId);
11658        r.totalRestartCount = 0;
11659        unscheduleServiceRestartLocked(r);
11660
11661        // Also make sure it is not on the pending list.
11662        int N = mPendingServices.size();
11663        for (int i=0; i<N; i++) {
11664            if (mPendingServices.get(i) == r) {
11665                mPendingServices.remove(i);
11666                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
11667                i--;
11668                N--;
11669            }
11670        }
11671
11672        r.cancelNotification();
11673        r.isForeground = false;
11674        r.foregroundId = 0;
11675        r.foregroundNoti = null;
11676
11677        // Clear start entries.
11678        r.clearDeliveredStartsLocked();
11679        r.pendingStarts.clear();
11680
11681        if (r.app != null) {
11682            synchronized (r.stats.getBatteryStats()) {
11683                r.stats.stopLaunchedLocked();
11684            }
11685            r.app.services.remove(r);
11686            if (r.app.thread != null) {
11687                try {
11688                    bumpServiceExecutingLocked(r, "stop");
11689                    mStoppingServices.add(r);
11690                    updateOomAdjLocked(r.app);
11691                    r.app.thread.scheduleStopService(r);
11692                } catch (Exception e) {
11693                    Slog.w(TAG, "Exception when stopping service "
11694                            + r.shortName, e);
11695                    serviceDoneExecutingLocked(r, true);
11696                }
11697                updateServiceForegroundLocked(r.app, false);
11698            } else {
11699                if (DEBUG_SERVICE) Slog.v(
11700                    TAG, "Removed service that has no process: " + r);
11701            }
11702        } else {
11703            if (DEBUG_SERVICE) Slog.v(
11704                TAG, "Removed service that is not running: " + r);
11705        }
11706
11707        if (r.bindings.size() > 0) {
11708            r.bindings.clear();
11709        }
11710
11711        if (r.restarter instanceof ServiceRestarter) {
11712           ((ServiceRestarter)r.restarter).setService(null);
11713        }
11714    }
11715
11716    ComponentName startServiceLocked(IApplicationThread caller,
11717            Intent service, String resolvedType,
11718            int callingPid, int callingUid) {
11719        synchronized(this) {
11720            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
11721                    + " type=" + resolvedType + " args=" + service.getExtras());
11722
11723            if (caller != null) {
11724                final ProcessRecord callerApp = getRecordForAppLocked(caller);
11725                if (callerApp == null) {
11726                    throw new SecurityException(
11727                            "Unable to find app for caller " + caller
11728                            + " (pid=" + Binder.getCallingPid()
11729                            + ") when starting service " + service);
11730                }
11731            }
11732
11733            ServiceLookupResult res =
11734                retrieveServiceLocked(service, resolvedType,
11735                        callingPid, callingUid, UserId.getUserId(callingUid));
11736            if (res == null) {
11737                return null;
11738            }
11739            if (res.record == null) {
11740                return new ComponentName("!", res.permission != null
11741                        ? res.permission : "private to package");
11742            }
11743            ServiceRecord r = res.record;
11744            NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked(
11745                    callingUid, r.packageName, service, service.getFlags(), null);
11746            if (unscheduleServiceRestartLocked(r)) {
11747                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
11748            }
11749            r.startRequested = true;
11750            r.callStart = false;
11751            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11752                    service, neededGrants));
11753            r.lastActivity = SystemClock.uptimeMillis();
11754            synchronized (r.stats.getBatteryStats()) {
11755                r.stats.startRunningLocked();
11756            }
11757            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11758                return new ComponentName("!", "Service process is bad");
11759            }
11760            return r.name;
11761        }
11762    }
11763
11764    public ComponentName startService(IApplicationThread caller, Intent service,
11765            String resolvedType) {
11766        enforceNotIsolatedCaller("startService");
11767        // Refuse possible leaked file descriptors
11768        if (service != null && service.hasFileDescriptors() == true) {
11769            throw new IllegalArgumentException("File descriptors passed in Intent");
11770        }
11771
11772        if (DEBUG_SERVICE)
11773            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
11774        synchronized(this) {
11775            final int callingPid = Binder.getCallingPid();
11776            final int callingUid = Binder.getCallingUid();
11777            final long origId = Binder.clearCallingIdentity();
11778            ComponentName res = startServiceLocked(caller, service,
11779                    resolvedType, callingPid, callingUid);
11780            Binder.restoreCallingIdentity(origId);
11781            return res;
11782        }
11783    }
11784
11785    ComponentName startServiceInPackage(int uid,
11786            Intent service, String resolvedType) {
11787        synchronized(this) {
11788            if (DEBUG_SERVICE)
11789                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
11790            final long origId = Binder.clearCallingIdentity();
11791            ComponentName res = startServiceLocked(null, service,
11792                    resolvedType, -1, uid);
11793            Binder.restoreCallingIdentity(origId);
11794            return res;
11795        }
11796    }
11797
11798    private void stopServiceLocked(ServiceRecord service) {
11799        synchronized (service.stats.getBatteryStats()) {
11800            service.stats.stopRunningLocked();
11801        }
11802        service.startRequested = false;
11803        service.callStart = false;
11804        bringDownServiceLocked(service, false);
11805    }
11806
11807    public int stopService(IApplicationThread caller, Intent service,
11808            String resolvedType) {
11809        enforceNotIsolatedCaller("stopService");
11810        // Refuse possible leaked file descriptors
11811        if (service != null && service.hasFileDescriptors() == true) {
11812            throw new IllegalArgumentException("File descriptors passed in Intent");
11813        }
11814
11815        synchronized(this) {
11816            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
11817                    + " type=" + resolvedType);
11818
11819            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11820            if (caller != null && callerApp == null) {
11821                throw new SecurityException(
11822                        "Unable to find app for caller " + caller
11823                        + " (pid=" + Binder.getCallingPid()
11824                        + ") when stopping service " + service);
11825            }
11826
11827            // If this service is active, make sure it is stopped.
11828            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11829                    callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
11830            if (r != null) {
11831                if (r.record != null) {
11832                    final long origId = Binder.clearCallingIdentity();
11833                    try {
11834                        stopServiceLocked(r.record);
11835                    } finally {
11836                        Binder.restoreCallingIdentity(origId);
11837                    }
11838                    return 1;
11839                }
11840                return -1;
11841            }
11842        }
11843
11844        return 0;
11845    }
11846
11847    public IBinder peekService(Intent service, String resolvedType) {
11848        enforceNotIsolatedCaller("peekService");
11849        // Refuse possible leaked file descriptors
11850        if (service != null && service.hasFileDescriptors() == true) {
11851            throw new IllegalArgumentException("File descriptors passed in Intent");
11852        }
11853
11854        IBinder ret = null;
11855
11856        synchronized(this) {
11857            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11858                    UserId.getCallingUserId());
11859
11860            if (r != null) {
11861                // r.record is null if findServiceLocked() failed the caller permission check
11862                if (r.record == null) {
11863                    throw new SecurityException(
11864                            "Permission Denial: Accessing service " + r.record.name
11865                            + " from pid=" + Binder.getCallingPid()
11866                            + ", uid=" + Binder.getCallingUid()
11867                            + " requires " + r.permission);
11868                }
11869                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11870                if (ib != null) {
11871                    ret = ib.binder;
11872                }
11873            }
11874        }
11875
11876        return ret;
11877    }
11878
11879    public boolean stopServiceToken(ComponentName className, IBinder token,
11880            int startId) {
11881        synchronized(this) {
11882            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
11883                    + " " + token + " startId=" + startId);
11884            ServiceRecord r = findServiceLocked(className, token);
11885            if (r != null) {
11886                if (startId >= 0) {
11887                    // Asked to only stop if done with all work.  Note that
11888                    // to avoid leaks, we will take this as dropping all
11889                    // start items up to and including this one.
11890                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11891                    if (si != null) {
11892                        while (r.deliveredStarts.size() > 0) {
11893                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11894                            cur.removeUriPermissionsLocked();
11895                            if (cur == si) {
11896                                break;
11897                            }
11898                        }
11899                    }
11900
11901                    if (r.getLastStartId() != startId) {
11902                        return false;
11903                    }
11904
11905                    if (r.deliveredStarts.size() > 0) {
11906                        Slog.w(TAG, "stopServiceToken startId " + startId
11907                                + " is last, but have " + r.deliveredStarts.size()
11908                                + " remaining args");
11909                    }
11910                }
11911
11912                synchronized (r.stats.getBatteryStats()) {
11913                    r.stats.stopRunningLocked();
11914                    r.startRequested = false;
11915                    r.callStart = false;
11916                }
11917                final long origId = Binder.clearCallingIdentity();
11918                bringDownServiceLocked(r, false);
11919                Binder.restoreCallingIdentity(origId);
11920                return true;
11921            }
11922        }
11923        return false;
11924    }
11925
11926    public void setServiceForeground(ComponentName className, IBinder token,
11927            int id, Notification notification, boolean removeNotification) {
11928        final long origId = Binder.clearCallingIdentity();
11929        try {
11930        synchronized(this) {
11931            ServiceRecord r = findServiceLocked(className, token);
11932            if (r != null) {
11933                if (id != 0) {
11934                    if (notification == null) {
11935                        throw new IllegalArgumentException("null notification");
11936                    }
11937                    if (r.foregroundId != id) {
11938                        r.cancelNotification();
11939                        r.foregroundId = id;
11940                    }
11941                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11942                    r.foregroundNoti = notification;
11943                    r.isForeground = true;
11944                    r.postNotification();
11945                    if (r.app != null) {
11946                        updateServiceForegroundLocked(r.app, true);
11947                    }
11948                } else {
11949                    if (r.isForeground) {
11950                        r.isForeground = false;
11951                        if (r.app != null) {
11952                            updateLruProcessLocked(r.app, false, true);
11953                            updateServiceForegroundLocked(r.app, true);
11954                        }
11955                    }
11956                    if (removeNotification) {
11957                        r.cancelNotification();
11958                        r.foregroundId = 0;
11959                        r.foregroundNoti = null;
11960                    }
11961                }
11962            }
11963        }
11964        } finally {
11965            Binder.restoreCallingIdentity(origId);
11966        }
11967    }
11968
11969    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11970        boolean anyForeground = false;
11971        for (ServiceRecord sr : proc.services) {
11972            if (sr.isForeground) {
11973                anyForeground = true;
11974                break;
11975            }
11976        }
11977        if (anyForeground != proc.foregroundServices) {
11978            proc.foregroundServices = anyForeground;
11979            if (oomAdj) {
11980                updateOomAdjLocked();
11981            }
11982        }
11983    }
11984
11985    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) {
11986        boolean result = false;
11987        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11988            result = false;
11989        } else if (componentProcessName == aInfo.packageName) {
11990            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11991        } else if ("system".equals(componentProcessName)) {
11992            result = true;
11993        }
11994        if (DEBUG_MU) {
11995            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result);
11996        }
11997        return result;
11998    }
11999
12000    public int bindService(IApplicationThread caller, IBinder token,
12001            Intent service, String resolvedType,
12002            IServiceConnection connection, int flags, int userId) {
12003        enforceNotIsolatedCaller("bindService");
12004        // Refuse possible leaked file descriptors
12005        if (service != null && service.hasFileDescriptors() == true) {
12006            throw new IllegalArgumentException("File descriptors passed in Intent");
12007        }
12008
12009        checkValidCaller(Binder.getCallingUid(), userId);
12010
12011        synchronized(this) {
12012            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
12013                    + " type=" + resolvedType + " conn=" + connection.asBinder()
12014                    + " flags=0x" + Integer.toHexString(flags));
12015            if (DEBUG_MU)
12016                Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12017                        + Binder.getOrigCallingUid());
12018            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12019            if (callerApp == null) {
12020                throw new SecurityException(
12021                        "Unable to find app for caller " + caller
12022                        + " (pid=" + Binder.getCallingPid()
12023                        + ") when binding service " + service);
12024            }
12025
12026            ActivityRecord activity = null;
12027            if (token != null) {
12028                activity = mMainStack.isInStackLocked(token);
12029                if (activity == null) {
12030                    Slog.w(TAG, "Binding with unknown activity: " + token);
12031                    return 0;
12032                }
12033            }
12034
12035            int clientLabel = 0;
12036            PendingIntent clientIntent = null;
12037
12038            if (callerApp.info.uid == Process.SYSTEM_UID) {
12039                // Hacky kind of thing -- allow system stuff to tell us
12040                // what they are, so we can report this elsewhere for
12041                // others to know why certain services are running.
12042                try {
12043                    clientIntent = (PendingIntent)service.getParcelableExtra(
12044                            Intent.EXTRA_CLIENT_INTENT);
12045                } catch (RuntimeException e) {
12046                }
12047                if (clientIntent != null) {
12048                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12049                    if (clientLabel != 0) {
12050                        // There are no useful extras in the intent, trash them.
12051                        // System code calling with this stuff just needs to know
12052                        // this will happen.
12053                        service = service.cloneFilter();
12054                    }
12055                }
12056            }
12057
12058            ServiceLookupResult res =
12059                retrieveServiceLocked(service, resolvedType,
12060                        Binder.getCallingPid(), Binder.getCallingUid(), userId);
12061            if (res == null) {
12062                return 0;
12063            }
12064            if (res.record == null) {
12065                return -1;
12066            }
12067            if (isSingleton(res.record.processName, res.record.appInfo)) {
12068                userId = 0;
12069                res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
12070                        Binder.getCallingUid(), 0);
12071            }
12072            ServiceRecord s = res.record;
12073
12074            final long origId = Binder.clearCallingIdentity();
12075
12076            if (unscheduleServiceRestartLocked(s)) {
12077                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
12078                        + s);
12079            }
12080
12081            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12082            ConnectionRecord c = new ConnectionRecord(b, activity,
12083                    connection, flags, clientLabel, clientIntent);
12084
12085            IBinder binder = connection.asBinder();
12086            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12087            if (clist == null) {
12088                clist = new ArrayList<ConnectionRecord>();
12089                s.connections.put(binder, clist);
12090            }
12091            clist.add(c);
12092            b.connections.add(c);
12093            if (activity != null) {
12094                if (activity.connections == null) {
12095                    activity.connections = new HashSet<ConnectionRecord>();
12096                }
12097                activity.connections.add(c);
12098            }
12099            b.client.connections.add(c);
12100            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12101                b.client.hasAboveClient = true;
12102            }
12103            clist = mServiceConnections.get(binder);
12104            if (clist == null) {
12105                clist = new ArrayList<ConnectionRecord>();
12106                mServiceConnections.put(binder, clist);
12107            }
12108            clist.add(c);
12109
12110            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12111                s.lastActivity = SystemClock.uptimeMillis();
12112                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12113                    return 0;
12114                }
12115            }
12116
12117            if (s.app != null) {
12118                // This could have made the service more important.
12119                updateOomAdjLocked(s.app);
12120            }
12121
12122            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
12123                    + ": received=" + b.intent.received
12124                    + " apps=" + b.intent.apps.size()
12125                    + " doRebind=" + b.intent.doRebind);
12126
12127            if (s.app != null && b.intent.received) {
12128                // Service is already running, so we can immediately
12129                // publish the connection.
12130                try {
12131                    c.conn.connected(s.name, b.intent.binder);
12132                } catch (Exception e) {
12133                    Slog.w(TAG, "Failure sending service " + s.shortName
12134                            + " to connection " + c.conn.asBinder()
12135                            + " (in " + c.binding.client.processName + ")", e);
12136                }
12137
12138                // If this is the first app connected back to this binding,
12139                // and the service had previously asked to be told when
12140                // rebound, then do so.
12141                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12142                    requestServiceBindingLocked(s, b.intent, true);
12143                }
12144            } else if (!b.intent.requested) {
12145                requestServiceBindingLocked(s, b.intent, false);
12146            }
12147
12148            Binder.restoreCallingIdentity(origId);
12149        }
12150
12151        return 1;
12152    }
12153
12154    void removeConnectionLocked(
12155        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
12156        IBinder binder = c.conn.asBinder();
12157        AppBindRecord b = c.binding;
12158        ServiceRecord s = b.service;
12159        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12160        if (clist != null) {
12161            clist.remove(c);
12162            if (clist.size() == 0) {
12163                s.connections.remove(binder);
12164            }
12165        }
12166        b.connections.remove(c);
12167        if (c.activity != null && c.activity != skipAct) {
12168            if (c.activity.connections != null) {
12169                c.activity.connections.remove(c);
12170            }
12171        }
12172        if (b.client != skipApp) {
12173            b.client.connections.remove(c);
12174            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12175                b.client.updateHasAboveClientLocked();
12176            }
12177        }
12178        clist = mServiceConnections.get(binder);
12179        if (clist != null) {
12180            clist.remove(c);
12181            if (clist.size() == 0) {
12182                mServiceConnections.remove(binder);
12183            }
12184        }
12185
12186        if (b.connections.size() == 0) {
12187            b.intent.apps.remove(b.client);
12188        }
12189
12190        if (!c.serviceDead) {
12191            if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12192                    + ": shouldUnbind=" + b.intent.hasBound);
12193            if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12194                    && b.intent.hasBound) {
12195                try {
12196                    bumpServiceExecutingLocked(s, "unbind");
12197                    updateOomAdjLocked(s.app);
12198                    b.intent.hasBound = false;
12199                    // Assume the client doesn't want to know about a rebind;
12200                    // we will deal with that later if it asks for one.
12201                    b.intent.doRebind = false;
12202                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12203                } catch (Exception e) {
12204                    Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12205                    serviceDoneExecutingLocked(s, true);
12206                }
12207            }
12208
12209            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12210                bringDownServiceLocked(s, false);
12211            }
12212        }
12213    }
12214
12215    public boolean unbindService(IServiceConnection connection) {
12216        synchronized (this) {
12217            IBinder binder = connection.asBinder();
12218            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
12219            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12220            if (clist == null) {
12221                Slog.w(TAG, "Unbind failed: could not find connection for "
12222                      + connection.asBinder());
12223                return false;
12224            }
12225
12226            final long origId = Binder.clearCallingIdentity();
12227
12228            while (clist.size() > 0) {
12229                ConnectionRecord r = clist.get(0);
12230                removeConnectionLocked(r, null, null);
12231
12232                if (r.binding.service.app != null) {
12233                    // This could have made the service less important.
12234                    updateOomAdjLocked(r.binding.service.app);
12235                }
12236            }
12237
12238            Binder.restoreCallingIdentity(origId);
12239        }
12240
12241        return true;
12242    }
12243
12244    public void publishService(IBinder token, Intent intent, IBinder service) {
12245        // Refuse possible leaked file descriptors
12246        if (intent != null && intent.hasFileDescriptors() == true) {
12247            throw new IllegalArgumentException("File descriptors passed in Intent");
12248        }
12249
12250        synchronized(this) {
12251            if (!(token instanceof ServiceRecord)) {
12252                throw new IllegalArgumentException("Invalid service token");
12253            }
12254            ServiceRecord r = (ServiceRecord)token;
12255
12256            final long origId = Binder.clearCallingIdentity();
12257
12258            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
12259                    + " " + intent + ": " + service);
12260            if (r != null) {
12261                Intent.FilterComparison filter
12262                        = new Intent.FilterComparison(intent);
12263                IntentBindRecord b = r.bindings.get(filter);
12264                if (b != null && !b.received) {
12265                    b.binder = service;
12266                    b.requested = true;
12267                    b.received = true;
12268                    if (r.connections.size() > 0) {
12269                        Iterator<ArrayList<ConnectionRecord>> it
12270                                = r.connections.values().iterator();
12271                        while (it.hasNext()) {
12272                            ArrayList<ConnectionRecord> clist = it.next();
12273                            for (int i=0; i<clist.size(); i++) {
12274                                ConnectionRecord c = clist.get(i);
12275                                if (!filter.equals(c.binding.intent.intent)) {
12276                                    if (DEBUG_SERVICE) Slog.v(
12277                                            TAG, "Not publishing to: " + c);
12278                                    if (DEBUG_SERVICE) Slog.v(
12279                                            TAG, "Bound intent: " + c.binding.intent.intent);
12280                                    if (DEBUG_SERVICE) Slog.v(
12281                                            TAG, "Published intent: " + intent);
12282                                    continue;
12283                                }
12284                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12285                                try {
12286                                    c.conn.connected(r.name, service);
12287                                } catch (Exception e) {
12288                                    Slog.w(TAG, "Failure sending service " + r.name +
12289                                          " to connection " + c.conn.asBinder() +
12290                                          " (in " + c.binding.client.processName + ")", e);
12291                                }
12292                            }
12293                        }
12294                    }
12295                }
12296
12297                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12298
12299                Binder.restoreCallingIdentity(origId);
12300            }
12301        }
12302    }
12303
12304    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12305        // Refuse possible leaked file descriptors
12306        if (intent != null && intent.hasFileDescriptors() == true) {
12307            throw new IllegalArgumentException("File descriptors passed in Intent");
12308        }
12309
12310        synchronized(this) {
12311            if (!(token instanceof ServiceRecord)) {
12312                throw new IllegalArgumentException("Invalid service token");
12313            }
12314            ServiceRecord r = (ServiceRecord)token;
12315
12316            final long origId = Binder.clearCallingIdentity();
12317
12318            if (r != null) {
12319                Intent.FilterComparison filter
12320                        = new Intent.FilterComparison(intent);
12321                IntentBindRecord b = r.bindings.get(filter);
12322                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
12323                        + " at " + b + ": apps="
12324                        + (b != null ? b.apps.size() : 0));
12325
12326                boolean inStopping = mStoppingServices.contains(r);
12327                if (b != null) {
12328                    if (b.apps.size() > 0 && !inStopping) {
12329                        // Applications have already bound since the last
12330                        // unbind, so just rebind right here.
12331                        requestServiceBindingLocked(r, b, true);
12332                    } else {
12333                        // Note to tell the service the next time there is
12334                        // a new client.
12335                        b.doRebind = true;
12336                    }
12337                }
12338
12339                serviceDoneExecutingLocked(r, inStopping);
12340
12341                Binder.restoreCallingIdentity(origId);
12342            }
12343        }
12344    }
12345
12346    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12347        synchronized(this) {
12348            if (!(token instanceof ServiceRecord)) {
12349                throw new IllegalArgumentException("Invalid service token");
12350            }
12351            ServiceRecord r = (ServiceRecord)token;
12352            boolean inStopping = mStoppingServices.contains(token);
12353            if (r != null) {
12354                if (r != token) {
12355                    Slog.w(TAG, "Done executing service " + r.name
12356                          + " with incorrect token: given " + token
12357                          + ", expected " + r);
12358                    return;
12359                }
12360
12361                if (type == 1) {
12362                    // This is a call from a service start...  take care of
12363                    // book-keeping.
12364                    r.callStart = true;
12365                    switch (res) {
12366                        case Service.START_STICKY_COMPATIBILITY:
12367                        case Service.START_STICKY: {
12368                            // We are done with the associated start arguments.
12369                            r.findDeliveredStart(startId, true);
12370                            // Don't stop if killed.
12371                            r.stopIfKilled = false;
12372                            break;
12373                        }
12374                        case Service.START_NOT_STICKY: {
12375                            // We are done with the associated start arguments.
12376                            r.findDeliveredStart(startId, true);
12377                            if (r.getLastStartId() == startId) {
12378                                // There is no more work, and this service
12379                                // doesn't want to hang around if killed.
12380                                r.stopIfKilled = true;
12381                            }
12382                            break;
12383                        }
12384                        case Service.START_REDELIVER_INTENT: {
12385                            // We'll keep this item until they explicitly
12386                            // call stop for it, but keep track of the fact
12387                            // that it was delivered.
12388                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12389                            if (si != null) {
12390                                si.deliveryCount = 0;
12391                                si.doneExecutingCount++;
12392                                // Don't stop if killed.
12393                                r.stopIfKilled = true;
12394                            }
12395                            break;
12396                        }
12397                        case Service.START_TASK_REMOVED_COMPLETE: {
12398                            // Special processing for onTaskRemoved().  Don't
12399                            // impact normal onStartCommand() processing.
12400                            r.findDeliveredStart(startId, true);
12401                            break;
12402                        }
12403                        default:
12404                            throw new IllegalArgumentException(
12405                                    "Unknown service start result: " + res);
12406                    }
12407                    if (res == Service.START_STICKY_COMPATIBILITY) {
12408                        r.callStart = false;
12409                    }
12410                }
12411                if (DEBUG_MU)
12412                    Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12413                            + Binder.getOrigCallingUid());
12414                final long origId = Binder.clearCallingIdentity();
12415                serviceDoneExecutingLocked(r, inStopping);
12416                Binder.restoreCallingIdentity(origId);
12417            } else {
12418                Slog.w(TAG, "Done executing unknown service from pid "
12419                        + Binder.getCallingPid());
12420            }
12421        }
12422    }
12423
12424    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
12425        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12426                + ": nesting=" + r.executeNesting
12427                + ", inStopping=" + inStopping + ", app=" + r.app);
12428        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
12429        r.executeNesting--;
12430        if (r.executeNesting <= 0 && r.app != null) {
12431            if (DEBUG_SERVICE) Slog.v(TAG,
12432                    "Nesting at 0 of " + r.shortName);
12433            r.app.executingServices.remove(r);
12434            if (r.app.executingServices.size() == 0) {
12435                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12436                        "No more executingServices of " + r.shortName);
12437                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12438            }
12439            if (inStopping) {
12440                if (DEBUG_SERVICE) Slog.v(TAG,
12441                        "doneExecuting remove stopping " + r);
12442                mStoppingServices.remove(r);
12443                r.bindings.clear();
12444            }
12445            updateOomAdjLocked(r.app);
12446        }
12447    }
12448
12449    void serviceTimeout(ProcessRecord proc) {
12450        String anrMessage = null;
12451
12452        synchronized(this) {
12453            if (proc.executingServices.size() == 0 || proc.thread == null) {
12454                return;
12455            }
12456            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12457            Iterator<ServiceRecord> it = proc.executingServices.iterator();
12458            ServiceRecord timeout = null;
12459            long nextTime = 0;
12460            while (it.hasNext()) {
12461                ServiceRecord sr = it.next();
12462                if (sr.executingStart < maxTime) {
12463                    timeout = sr;
12464                    break;
12465                }
12466                if (sr.executingStart > nextTime) {
12467                    nextTime = sr.executingStart;
12468                }
12469            }
12470            if (timeout != null && mLruProcesses.contains(proc)) {
12471                Slog.w(TAG, "Timeout executing service: " + timeout);
12472                anrMessage = "Executing service " + timeout.shortName;
12473            } else {
12474                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12475                msg.obj = proc;
12476                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12477            }
12478        }
12479
12480        if (anrMessage != null) {
12481            appNotResponding(proc, null, null, anrMessage);
12482        }
12483    }
12484
12485    // =========================================================
12486    // BACKUP AND RESTORE
12487    // =========================================================
12488
12489    // Cause the target app to be launched if necessary and its backup agent
12490    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12491    // activity manager to announce its creation.
12492    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12493        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
12494        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12495
12496        synchronized(this) {
12497            // !!! TODO: currently no check here that we're already bound
12498            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12499            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12500            synchronized (stats) {
12501                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12502            }
12503
12504            // Backup agent is now in use, its package can't be stopped.
12505            try {
12506                AppGlobals.getPackageManager().setPackageStoppedState(
12507                        app.packageName, false, UserId.getUserId(app.uid));
12508            } catch (RemoteException e) {
12509            } catch (IllegalArgumentException e) {
12510                Slog.w(TAG, "Failed trying to unstop package "
12511                        + app.packageName + ": " + e);
12512            }
12513
12514            BackupRecord r = new BackupRecord(ss, app, backupMode);
12515            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12516                    ? new ComponentName(app.packageName, app.backupAgentName)
12517                    : new ComponentName("android", "FullBackupAgent");
12518            // startProcessLocked() returns existing proc's record if it's already running
12519            ProcessRecord proc = startProcessLocked(app.processName, app,
12520                    false, 0, "backup", hostingName, false, false);
12521            if (proc == null) {
12522                Slog.e(TAG, "Unable to start backup agent process " + r);
12523                return false;
12524            }
12525
12526            r.app = proc;
12527            mBackupTarget = r;
12528            mBackupAppName = app.packageName;
12529
12530            // Try not to kill the process during backup
12531            updateOomAdjLocked(proc);
12532
12533            // If the process is already attached, schedule the creation of the backup agent now.
12534            // If it is not yet live, this will be done when it attaches to the framework.
12535            if (proc.thread != null) {
12536                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12537                try {
12538                    proc.thread.scheduleCreateBackupAgent(app,
12539                            compatibilityInfoForPackageLocked(app), backupMode);
12540                } catch (RemoteException e) {
12541                    // Will time out on the backup manager side
12542                }
12543            } else {
12544                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12545            }
12546            // Invariants: at this point, the target app process exists and the application
12547            // is either already running or in the process of coming up.  mBackupTarget and
12548            // mBackupAppName describe the app, so that when it binds back to the AM we
12549            // know that it's scheduled for a backup-agent operation.
12550        }
12551
12552        return true;
12553    }
12554
12555    // A backup agent has just come up
12556    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12557        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12558                + " = " + agent);
12559
12560        synchronized(this) {
12561            if (!agentPackageName.equals(mBackupAppName)) {
12562                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12563                return;
12564            }
12565        }
12566
12567        long oldIdent = Binder.clearCallingIdentity();
12568        try {
12569            IBackupManager bm = IBackupManager.Stub.asInterface(
12570                    ServiceManager.getService(Context.BACKUP_SERVICE));
12571            bm.agentConnected(agentPackageName, agent);
12572        } catch (RemoteException e) {
12573            // can't happen; the backup manager service is local
12574        } catch (Exception e) {
12575            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12576            e.printStackTrace();
12577        } finally {
12578            Binder.restoreCallingIdentity(oldIdent);
12579        }
12580    }
12581
12582    // done with this agent
12583    public void unbindBackupAgent(ApplicationInfo appInfo) {
12584        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12585        if (appInfo == null) {
12586            Slog.w(TAG, "unbind backup agent for null app");
12587            return;
12588        }
12589
12590        synchronized(this) {
12591            if (mBackupAppName == null) {
12592                Slog.w(TAG, "Unbinding backup agent with no active backup");
12593                return;
12594            }
12595
12596            if (!mBackupAppName.equals(appInfo.packageName)) {
12597                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12598                return;
12599            }
12600
12601            ProcessRecord proc = mBackupTarget.app;
12602            mBackupTarget = null;
12603            mBackupAppName = null;
12604
12605            // Not backing this app up any more; reset its OOM adjustment
12606            updateOomAdjLocked(proc);
12607
12608            // If the app crashed during backup, 'thread' will be null here
12609            if (proc.thread != null) {
12610                try {
12611                    proc.thread.scheduleDestroyBackupAgent(appInfo,
12612                            compatibilityInfoForPackageLocked(appInfo));
12613                } catch (Exception e) {
12614                    Slog.e(TAG, "Exception when unbinding backup agent:");
12615                    e.printStackTrace();
12616                }
12617            }
12618        }
12619    }
12620    // =========================================================
12621    // BROADCASTS
12622    // =========================================================
12623
12624    private final List getStickiesLocked(String action, IntentFilter filter,
12625            List cur) {
12626        final ContentResolver resolver = mContext.getContentResolver();
12627        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12628        if (list == null) {
12629            return cur;
12630        }
12631        int N = list.size();
12632        for (int i=0; i<N; i++) {
12633            Intent intent = list.get(i);
12634            if (filter.match(resolver, intent, true, TAG) >= 0) {
12635                if (cur == null) {
12636                    cur = new ArrayList<Intent>();
12637                }
12638                cur.add(intent);
12639            }
12640        }
12641        return cur;
12642    }
12643
12644    boolean isPendingBroadcastProcessLocked(int pid) {
12645        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12646                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12647    }
12648
12649    void skipPendingBroadcastLocked(int pid) {
12650            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12651            for (BroadcastQueue queue : mBroadcastQueues) {
12652                queue.skipPendingBroadcastLocked(pid);
12653            }
12654    }
12655
12656    // The app just attached; send any pending broadcasts that it should receive
12657    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12658        boolean didSomething = false;
12659        for (BroadcastQueue queue : mBroadcastQueues) {
12660            didSomething |= queue.sendPendingBroadcastsLocked(app);
12661        }
12662        return didSomething;
12663    }
12664
12665    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12666            IIntentReceiver receiver, IntentFilter filter, String permission) {
12667        enforceNotIsolatedCaller("registerReceiver");
12668        synchronized(this) {
12669            ProcessRecord callerApp = null;
12670            if (caller != null) {
12671                callerApp = getRecordForAppLocked(caller);
12672                if (callerApp == null) {
12673                    throw new SecurityException(
12674                            "Unable to find app for caller " + caller
12675                            + " (pid=" + Binder.getCallingPid()
12676                            + ") when registering receiver " + receiver);
12677                }
12678                if (callerApp.info.uid != Process.SYSTEM_UID &&
12679                        !callerApp.pkgList.contains(callerPackage)) {
12680                    throw new SecurityException("Given caller package " + callerPackage
12681                            + " is not running in process " + callerApp);
12682                }
12683            } else {
12684                callerPackage = null;
12685            }
12686
12687            List allSticky = null;
12688
12689            // Look for any matching sticky broadcasts...
12690            Iterator actions = filter.actionsIterator();
12691            if (actions != null) {
12692                while (actions.hasNext()) {
12693                    String action = (String)actions.next();
12694                    allSticky = getStickiesLocked(action, filter, allSticky);
12695                }
12696            } else {
12697                allSticky = getStickiesLocked(null, filter, allSticky);
12698            }
12699
12700            // The first sticky in the list is returned directly back to
12701            // the client.
12702            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12703
12704            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12705                    + ": " + sticky);
12706
12707            if (receiver == null) {
12708                return sticky;
12709            }
12710
12711            ReceiverList rl
12712                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12713            if (rl == null) {
12714                rl = new ReceiverList(this, callerApp,
12715                        Binder.getCallingPid(),
12716                        Binder.getCallingUid(), receiver);
12717                if (rl.app != null) {
12718                    rl.app.receivers.add(rl);
12719                } else {
12720                    try {
12721                        receiver.asBinder().linkToDeath(rl, 0);
12722                    } catch (RemoteException e) {
12723                        return sticky;
12724                    }
12725                    rl.linkedToDeath = true;
12726                }
12727                mRegisteredReceivers.put(receiver.asBinder(), rl);
12728            }
12729            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
12730            rl.add(bf);
12731            if (!bf.debugCheck()) {
12732                Slog.w(TAG, "==> For Dynamic broadast");
12733            }
12734            mReceiverResolver.addFilter(bf);
12735
12736            // Enqueue broadcasts for all existing stickies that match
12737            // this filter.
12738            if (allSticky != null) {
12739                ArrayList receivers = new ArrayList();
12740                receivers.add(bf);
12741
12742                int N = allSticky.size();
12743                for (int i=0; i<N; i++) {
12744                    Intent intent = (Intent)allSticky.get(i);
12745                    BroadcastQueue queue = broadcastQueueForIntent(intent);
12746                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
12747                            null, -1, -1, null, receivers, null, 0, null, null,
12748                            false, true, true);
12749                    queue.enqueueParallelBroadcastLocked(r);
12750                    queue.scheduleBroadcastsLocked();
12751                }
12752            }
12753
12754            return sticky;
12755        }
12756    }
12757
12758    public void unregisterReceiver(IIntentReceiver receiver) {
12759        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
12760
12761        final long origId = Binder.clearCallingIdentity();
12762        try {
12763            boolean doTrim = false;
12764
12765            synchronized(this) {
12766                ReceiverList rl
12767                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12768                if (rl != null) {
12769                    if (rl.curBroadcast != null) {
12770                        BroadcastRecord r = rl.curBroadcast;
12771                        final boolean doNext = finishReceiverLocked(
12772                                receiver.asBinder(), r.resultCode, r.resultData,
12773                                r.resultExtras, r.resultAbort, true);
12774                        if (doNext) {
12775                            doTrim = true;
12776                            r.queue.processNextBroadcast(false);
12777                        }
12778                    }
12779
12780                    if (rl.app != null) {
12781                        rl.app.receivers.remove(rl);
12782                    }
12783                    removeReceiverLocked(rl);
12784                    if (rl.linkedToDeath) {
12785                        rl.linkedToDeath = false;
12786                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
12787                    }
12788                }
12789            }
12790
12791            // If we actually concluded any broadcasts, we might now be able
12792            // to trim the recipients' apps from our working set
12793            if (doTrim) {
12794                trimApplications();
12795                return;
12796            }
12797
12798        } finally {
12799            Binder.restoreCallingIdentity(origId);
12800        }
12801    }
12802
12803    void removeReceiverLocked(ReceiverList rl) {
12804        mRegisteredReceivers.remove(rl.receiver.asBinder());
12805        int N = rl.size();
12806        for (int i=0; i<N; i++) {
12807            mReceiverResolver.removeFilter(rl.get(i));
12808        }
12809    }
12810
12811    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12812        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12813            ProcessRecord r = mLruProcesses.get(i);
12814            if (r.thread != null) {
12815                try {
12816                    r.thread.dispatchPackageBroadcast(cmd, packages);
12817                } catch (RemoteException ex) {
12818                }
12819            }
12820        }
12821    }
12822
12823    private final int broadcastIntentLocked(ProcessRecord callerApp,
12824            String callerPackage, Intent intent, String resolvedType,
12825            IIntentReceiver resultTo, int resultCode, String resultData,
12826            Bundle map, String requiredPermission,
12827            boolean ordered, boolean sticky, int callingPid, int callingUid,
12828            int userId) {
12829        intent = new Intent(intent);
12830
12831        // By default broadcasts do not go to stopped apps.
12832        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12833
12834        if (DEBUG_BROADCAST_LIGHT) Slog.v(
12835            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12836            + " ordered=" + ordered + " userid=" + userId);
12837        if ((resultTo != null) && !ordered) {
12838            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
12839        }
12840
12841        // Handle special intents: if this broadcast is from the package
12842        // manager about a package being removed, we need to remove all of
12843        // its activities from the history stack.
12844        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
12845                intent.getAction());
12846        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12847                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
12848                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
12849                || uidRemoved) {
12850            if (checkComponentPermission(
12851                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
12852                    callingPid, callingUid, -1, true)
12853                    == PackageManager.PERMISSION_GRANTED) {
12854                if (uidRemoved) {
12855                    final Bundle intentExtras = intent.getExtras();
12856                    final int uid = intentExtras != null
12857                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12858                    if (uid >= 0) {
12859                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12860                        synchronized (bs) {
12861                            bs.removeUidStatsLocked(uid);
12862                        }
12863                    }
12864                } else {
12865                    // If resources are unvailble just force stop all
12866                    // those packages and flush the attribute cache as well.
12867                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
12868                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12869                        if (list != null && (list.length > 0)) {
12870                            for (String pkg : list) {
12871                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
12872                            }
12873                            sendPackageBroadcastLocked(
12874                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
12875                        }
12876                    } else {
12877                        Uri data = intent.getData();
12878                        String ssp;
12879                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12880                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12881                                forceStopPackageLocked(ssp,
12882                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
12883                                        false, userId);
12884                            }
12885                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
12886                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12887                                        new String[] {ssp});
12888                            }
12889                        }
12890                    }
12891                }
12892            } else {
12893                String msg = "Permission Denial: " + intent.getAction()
12894                        + " broadcast from " + callerPackage + " (pid=" + callingPid
12895                        + ", uid=" + callingUid + ")"
12896                        + " requires "
12897                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
12898                Slog.w(TAG, msg);
12899                throw new SecurityException(msg);
12900            }
12901
12902        // Special case for adding a package: by default turn on compatibility
12903        // mode.
12904        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12905            Uri data = intent.getData();
12906            String ssp;
12907            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12908                mCompatModePackages.handlePackageAddedLocked(ssp,
12909                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
12910            }
12911        }
12912
12913        /*
12914         * If this is the time zone changed action, queue up a message that will reset the timezone
12915         * of all currently running processes. This message will get queued up before the broadcast
12916         * happens.
12917         */
12918        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12919            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12920        }
12921
12922        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12923            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12924        }
12925
12926        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12927            ProxyProperties proxy = intent.getParcelableExtra("proxy");
12928            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12929        }
12930
12931        /*
12932         * Prevent non-system code (defined here to be non-persistent
12933         * processes) from sending protected broadcasts.
12934         */
12935        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12936                || callingUid == Process.SHELL_UID || callingUid == 0) {
12937            // Always okay.
12938        } else if (callerApp == null || !callerApp.persistent) {
12939            try {
12940                if (AppGlobals.getPackageManager().isProtectedBroadcast(
12941                        intent.getAction())) {
12942                    String msg = "Permission Denial: not allowed to send broadcast "
12943                            + intent.getAction() + " from pid="
12944                            + callingPid + ", uid=" + callingUid;
12945                    Slog.w(TAG, msg);
12946                    throw new SecurityException(msg);
12947                }
12948            } catch (RemoteException e) {
12949                Slog.w(TAG, "Remote exception", e);
12950                return ActivityManager.BROADCAST_SUCCESS;
12951            }
12952        }
12953
12954        // Add to the sticky list if requested.
12955        if (sticky) {
12956            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12957                    callingPid, callingUid)
12958                    != PackageManager.PERMISSION_GRANTED) {
12959                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12960                        + callingPid + ", uid=" + callingUid
12961                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12962                Slog.w(TAG, msg);
12963                throw new SecurityException(msg);
12964            }
12965            if (requiredPermission != null) {
12966                Slog.w(TAG, "Can't broadcast sticky intent " + intent
12967                        + " and enforce permission " + requiredPermission);
12968                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12969            }
12970            if (intent.getComponent() != null) {
12971                throw new SecurityException(
12972                        "Sticky broadcasts can't target a specific component");
12973            }
12974            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12975            if (list == null) {
12976                list = new ArrayList<Intent>();
12977                mStickyBroadcasts.put(intent.getAction(), list);
12978            }
12979            int N = list.size();
12980            int i;
12981            for (i=0; i<N; i++) {
12982                if (intent.filterEquals(list.get(i))) {
12983                    // This sticky already exists, replace it.
12984                    list.set(i, new Intent(intent));
12985                    break;
12986                }
12987            }
12988            if (i >= N) {
12989                list.add(new Intent(intent));
12990            }
12991        }
12992
12993        // Figure out who all will receive this broadcast.
12994        List receivers = null;
12995        List<BroadcastFilter> registeredReceivers = null;
12996        try {
12997            if (intent.getComponent() != null) {
12998                // Broadcast is going to one specific receiver class...
12999                ActivityInfo ai = AppGlobals.getPackageManager().
13000                        getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId);
13001                if (ai != null) {
13002                    receivers = new ArrayList();
13003                    ResolveInfo ri = new ResolveInfo();
13004                    if (isSingleton(ai.processName, ai.applicationInfo)) {
13005                        ri.activityInfo = getActivityInfoForUser(ai, 0);
13006                    } else {
13007                        ri.activityInfo = getActivityInfoForUser(ai, userId);
13008                    }
13009                    receivers.add(ri);
13010                }
13011            } else {
13012                // Need to resolve the intent to interested receivers...
13013                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13014                         == 0) {
13015                    receivers =
13016                        AppGlobals.getPackageManager().queryIntentReceivers(
13017                                    intent, resolvedType, STOCK_PM_FLAGS, userId);
13018                }
13019                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false,
13020                        userId);
13021            }
13022        } catch (RemoteException ex) {
13023            // pm is in same process, this will never happen.
13024        }
13025
13026        final boolean replacePending =
13027                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13028
13029        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13030                + " replacePending=" + replacePending);
13031
13032        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13033        if (!ordered && NR > 0) {
13034            // If we are not serializing this broadcast, then send the
13035            // registered receivers separately so they don't wait for the
13036            // components to be launched.
13037            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13038            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13039                    callerPackage, callingPid, callingUid, requiredPermission,
13040                    registeredReceivers, resultTo, resultCode, resultData, map,
13041                    ordered, sticky, false);
13042            if (DEBUG_BROADCAST) Slog.v(
13043                    TAG, "Enqueueing parallel broadcast " + r);
13044            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13045            if (!replaced) {
13046                queue.enqueueParallelBroadcastLocked(r);
13047                queue.scheduleBroadcastsLocked();
13048            }
13049            registeredReceivers = null;
13050            NR = 0;
13051        }
13052
13053        // Merge into one list.
13054        int ir = 0;
13055        if (receivers != null) {
13056            // A special case for PACKAGE_ADDED: do not allow the package
13057            // being added to see this broadcast.  This prevents them from
13058            // using this as a back door to get run as soon as they are
13059            // installed.  Maybe in the future we want to have a special install
13060            // broadcast or such for apps, but we'd like to deliberately make
13061            // this decision.
13062            String skipPackages[] = null;
13063            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13064                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13065                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13066                Uri data = intent.getData();
13067                if (data != null) {
13068                    String pkgName = data.getSchemeSpecificPart();
13069                    if (pkgName != null) {
13070                        skipPackages = new String[] { pkgName };
13071                    }
13072                }
13073            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13074                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13075            }
13076            if (skipPackages != null && (skipPackages.length > 0)) {
13077                for (String skipPackage : skipPackages) {
13078                    if (skipPackage != null) {
13079                        int NT = receivers.size();
13080                        for (int it=0; it<NT; it++) {
13081                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13082                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13083                                receivers.remove(it);
13084                                it--;
13085                                NT--;
13086                            }
13087                        }
13088                    }
13089                }
13090            }
13091
13092            int NT = receivers != null ? receivers.size() : 0;
13093            int it = 0;
13094            ResolveInfo curt = null;
13095            BroadcastFilter curr = null;
13096            while (it < NT && ir < NR) {
13097                if (curt == null) {
13098                    curt = (ResolveInfo)receivers.get(it);
13099                }
13100                if (curr == null) {
13101                    curr = registeredReceivers.get(ir);
13102                }
13103                if (curr.getPriority() >= curt.priority) {
13104                    // Insert this broadcast record into the final list.
13105                    receivers.add(it, curr);
13106                    ir++;
13107                    curr = null;
13108                    it++;
13109                    NT++;
13110                } else {
13111                    // Skip to the next ResolveInfo in the final list.
13112                    it++;
13113                    curt = null;
13114                }
13115            }
13116        }
13117        while (ir < NR) {
13118            if (receivers == null) {
13119                receivers = new ArrayList();
13120            }
13121            receivers.add(registeredReceivers.get(ir));
13122            ir++;
13123        }
13124
13125        if ((receivers != null && receivers.size() > 0)
13126                || resultTo != null) {
13127            BroadcastQueue queue = broadcastQueueForIntent(intent);
13128            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13129                    callerPackage, callingPid, callingUid, requiredPermission,
13130                    receivers, resultTo, resultCode, resultData, map, ordered,
13131                    sticky, false);
13132            if (DEBUG_BROADCAST) Slog.v(
13133                    TAG, "Enqueueing ordered broadcast " + r
13134                    + ": prev had " + queue.mOrderedBroadcasts.size());
13135            if (DEBUG_BROADCAST) {
13136                int seq = r.intent.getIntExtra("seq", -1);
13137                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13138            }
13139            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13140            if (!replaced) {
13141                queue.enqueueOrderedBroadcastLocked(r);
13142                queue.scheduleBroadcastsLocked();
13143            }
13144        }
13145
13146        return ActivityManager.BROADCAST_SUCCESS;
13147    }
13148
13149    final Intent verifyBroadcastLocked(Intent intent) {
13150        // Refuse possible leaked file descriptors
13151        if (intent != null && intent.hasFileDescriptors() == true) {
13152            throw new IllegalArgumentException("File descriptors passed in Intent");
13153        }
13154
13155        int flags = intent.getFlags();
13156
13157        if (!mProcessesReady) {
13158            // if the caller really truly claims to know what they're doing, go
13159            // ahead and allow the broadcast without launching any receivers
13160            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13161                intent = new Intent(intent);
13162                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13163            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13164                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13165                        + " before boot completion");
13166                throw new IllegalStateException("Cannot broadcast before boot completed");
13167            }
13168        }
13169
13170        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13171            throw new IllegalArgumentException(
13172                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13173        }
13174
13175        return intent;
13176    }
13177
13178    public final int broadcastIntent(IApplicationThread caller,
13179            Intent intent, String resolvedType, IIntentReceiver resultTo,
13180            int resultCode, String resultData, Bundle map,
13181            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13182        enforceNotIsolatedCaller("broadcastIntent");
13183        synchronized(this) {
13184            intent = verifyBroadcastLocked(intent);
13185
13186            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13187            final int callingPid = Binder.getCallingPid();
13188            final int callingUid = Binder.getCallingUid();
13189            final long origId = Binder.clearCallingIdentity();
13190            int res = broadcastIntentLocked(callerApp,
13191                    callerApp != null ? callerApp.info.packageName : null,
13192                    intent, resolvedType, resultTo,
13193                    resultCode, resultData, map, requiredPermission, serialized, sticky,
13194                    callingPid, callingUid, userId);
13195            Binder.restoreCallingIdentity(origId);
13196            return res;
13197        }
13198    }
13199
13200    int broadcastIntentInPackage(String packageName, int uid,
13201            Intent intent, String resolvedType, IIntentReceiver resultTo,
13202            int resultCode, String resultData, Bundle map,
13203            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13204        synchronized(this) {
13205            intent = verifyBroadcastLocked(intent);
13206
13207            final long origId = Binder.clearCallingIdentity();
13208            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13209                    resultTo, resultCode, resultData, map, requiredPermission,
13210                    serialized, sticky, -1, uid, userId);
13211            Binder.restoreCallingIdentity(origId);
13212            return res;
13213        }
13214    }
13215
13216    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13217    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13218        // Refuse possible leaked file descriptors
13219        if (intent != null && intent.hasFileDescriptors() == true) {
13220            throw new IllegalArgumentException("File descriptors passed in Intent");
13221        }
13222
13223        synchronized(this) {
13224            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13225                    != PackageManager.PERMISSION_GRANTED) {
13226                String msg = "Permission Denial: unbroadcastIntent() from pid="
13227                        + Binder.getCallingPid()
13228                        + ", uid=" + Binder.getCallingUid()
13229                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13230                Slog.w(TAG, msg);
13231                throw new SecurityException(msg);
13232            }
13233            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13234            if (list != null) {
13235                int N = list.size();
13236                int i;
13237                for (i=0; i<N; i++) {
13238                    if (intent.filterEquals(list.get(i))) {
13239                        list.remove(i);
13240                        break;
13241                    }
13242                }
13243            }
13244        }
13245    }
13246
13247    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13248            String resultData, Bundle resultExtras, boolean resultAbort,
13249            boolean explicit) {
13250        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13251        if (r == null) {
13252            Slog.w(TAG, "finishReceiver called but not found on queue");
13253            return false;
13254        }
13255
13256        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13257                explicit);
13258    }
13259
13260    public void finishReceiver(IBinder who, int resultCode, String resultData,
13261            Bundle resultExtras, boolean resultAbort) {
13262        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13263
13264        // Refuse possible leaked file descriptors
13265        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13266            throw new IllegalArgumentException("File descriptors passed in Bundle");
13267        }
13268
13269        final long origId = Binder.clearCallingIdentity();
13270        try {
13271            boolean doNext = false;
13272            BroadcastRecord r = null;
13273
13274            synchronized(this) {
13275                r = broadcastRecordForReceiverLocked(who);
13276                if (r != null) {
13277                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13278                        resultData, resultExtras, resultAbort, true);
13279                }
13280            }
13281
13282            if (doNext) {
13283                r.queue.processNextBroadcast(false);
13284            }
13285            trimApplications();
13286        } finally {
13287            Binder.restoreCallingIdentity(origId);
13288        }
13289    }
13290
13291    // =========================================================
13292    // INSTRUMENTATION
13293    // =========================================================
13294
13295    public boolean startInstrumentation(ComponentName className,
13296            String profileFile, int flags, Bundle arguments,
13297            IInstrumentationWatcher watcher) {
13298        enforceNotIsolatedCaller("startInstrumentation");
13299        // Refuse possible leaked file descriptors
13300        if (arguments != null && arguments.hasFileDescriptors()) {
13301            throw new IllegalArgumentException("File descriptors passed in Bundle");
13302        }
13303
13304        synchronized(this) {
13305            InstrumentationInfo ii = null;
13306            ApplicationInfo ai = null;
13307            try {
13308                ii = mContext.getPackageManager().getInstrumentationInfo(
13309                    className, STOCK_PM_FLAGS);
13310                ai = mContext.getPackageManager().getApplicationInfo(
13311                        ii.targetPackage, STOCK_PM_FLAGS);
13312            } catch (PackageManager.NameNotFoundException e) {
13313            }
13314            if (ii == null) {
13315                reportStartInstrumentationFailure(watcher, className,
13316                        "Unable to find instrumentation info for: " + className);
13317                return false;
13318            }
13319            if (ai == null) {
13320                reportStartInstrumentationFailure(watcher, className,
13321                        "Unable to find instrumentation target package: " + ii.targetPackage);
13322                return false;
13323            }
13324
13325            int match = mContext.getPackageManager().checkSignatures(
13326                    ii.targetPackage, ii.packageName);
13327            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13328                String msg = "Permission Denial: starting instrumentation "
13329                        + className + " from pid="
13330                        + Binder.getCallingPid()
13331                        + ", uid=" + Binder.getCallingPid()
13332                        + " not allowed because package " + ii.packageName
13333                        + " does not have a signature matching the target "
13334                        + ii.targetPackage;
13335                reportStartInstrumentationFailure(watcher, className, msg);
13336                throw new SecurityException(msg);
13337            }
13338
13339            int userId = UserId.getCallingUserId();
13340            final long origId = Binder.clearCallingIdentity();
13341            // Instrumentation can kill and relaunch even persistent processes
13342            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
13343            ProcessRecord app = addAppLocked(ai, false);
13344            app.instrumentationClass = className;
13345            app.instrumentationInfo = ai;
13346            app.instrumentationProfileFile = profileFile;
13347            app.instrumentationArguments = arguments;
13348            app.instrumentationWatcher = watcher;
13349            app.instrumentationResultClass = className;
13350            Binder.restoreCallingIdentity(origId);
13351        }
13352
13353        return true;
13354    }
13355
13356    /**
13357     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13358     * error to the logs, but if somebody is watching, send the report there too.  This enables
13359     * the "am" command to report errors with more information.
13360     *
13361     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13362     * @param cn The component name of the instrumentation.
13363     * @param report The error report.
13364     */
13365    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13366            ComponentName cn, String report) {
13367        Slog.w(TAG, report);
13368        try {
13369            if (watcher != null) {
13370                Bundle results = new Bundle();
13371                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13372                results.putString("Error", report);
13373                watcher.instrumentationStatus(cn, -1, results);
13374            }
13375        } catch (RemoteException e) {
13376            Slog.w(TAG, e);
13377        }
13378    }
13379
13380    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13381        if (app.instrumentationWatcher != null) {
13382            try {
13383                // NOTE:  IInstrumentationWatcher *must* be oneway here
13384                app.instrumentationWatcher.instrumentationFinished(
13385                    app.instrumentationClass,
13386                    resultCode,
13387                    results);
13388            } catch (RemoteException e) {
13389            }
13390        }
13391        app.instrumentationWatcher = null;
13392        app.instrumentationClass = null;
13393        app.instrumentationInfo = null;
13394        app.instrumentationProfileFile = null;
13395        app.instrumentationArguments = null;
13396
13397        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
13398    }
13399
13400    public void finishInstrumentation(IApplicationThread target,
13401            int resultCode, Bundle results) {
13402        int userId = UserId.getCallingUserId();
13403        // Refuse possible leaked file descriptors
13404        if (results != null && results.hasFileDescriptors()) {
13405            throw new IllegalArgumentException("File descriptors passed in Intent");
13406        }
13407
13408        synchronized(this) {
13409            ProcessRecord app = getRecordForAppLocked(target);
13410            if (app == null) {
13411                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13412                return;
13413            }
13414            final long origId = Binder.clearCallingIdentity();
13415            finishInstrumentationLocked(app, resultCode, results);
13416            Binder.restoreCallingIdentity(origId);
13417        }
13418    }
13419
13420    // =========================================================
13421    // CONFIGURATION
13422    // =========================================================
13423
13424    public ConfigurationInfo getDeviceConfigurationInfo() {
13425        ConfigurationInfo config = new ConfigurationInfo();
13426        synchronized (this) {
13427            config.reqTouchScreen = mConfiguration.touchscreen;
13428            config.reqKeyboardType = mConfiguration.keyboard;
13429            config.reqNavigation = mConfiguration.navigation;
13430            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13431                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13432                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13433            }
13434            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13435                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13436                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13437            }
13438            config.reqGlEsVersion = GL_ES_VERSION;
13439        }
13440        return config;
13441    }
13442
13443    public Configuration getConfiguration() {
13444        Configuration ci;
13445        synchronized(this) {
13446            ci = new Configuration(mConfiguration);
13447        }
13448        return ci;
13449    }
13450
13451    public void updatePersistentConfiguration(Configuration values) {
13452        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13453                "updateConfiguration()");
13454        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13455                "updateConfiguration()");
13456        if (values == null) {
13457            throw new NullPointerException("Configuration must not be null");
13458        }
13459
13460        synchronized(this) {
13461            final long origId = Binder.clearCallingIdentity();
13462            updateConfigurationLocked(values, null, true, false);
13463            Binder.restoreCallingIdentity(origId);
13464        }
13465    }
13466
13467    public void updateConfiguration(Configuration values) {
13468        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13469                "updateConfiguration()");
13470
13471        synchronized(this) {
13472            if (values == null && mWindowManager != null) {
13473                // sentinel: fetch the current configuration from the window manager
13474                values = mWindowManager.computeNewConfiguration();
13475            }
13476
13477            if (mWindowManager != null) {
13478                mProcessList.applyDisplaySize(mWindowManager);
13479            }
13480
13481            final long origId = Binder.clearCallingIdentity();
13482            if (values != null) {
13483                Settings.System.clearConfiguration(values);
13484            }
13485            updateConfigurationLocked(values, null, false, false);
13486            Binder.restoreCallingIdentity(origId);
13487        }
13488    }
13489
13490    /**
13491     * Do either or both things: (1) change the current configuration, and (2)
13492     * make sure the given activity is running with the (now) current
13493     * configuration.  Returns true if the activity has been left running, or
13494     * false if <var>starting</var> is being destroyed to match the new
13495     * configuration.
13496     * @param persistent TODO
13497     */
13498    boolean updateConfigurationLocked(Configuration values,
13499            ActivityRecord starting, boolean persistent, boolean initLocale) {
13500        // do nothing if we are headless
13501        if (mHeadless) return true;
13502
13503        int changes = 0;
13504
13505        boolean kept = true;
13506
13507        if (values != null) {
13508            Configuration newConfig = new Configuration(mConfiguration);
13509            changes = newConfig.updateFrom(values);
13510            if (changes != 0) {
13511                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13512                    Slog.i(TAG, "Updating configuration to: " + values);
13513                }
13514
13515                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13516
13517                if (values.locale != null && !initLocale) {
13518                    saveLocaleLocked(values.locale,
13519                                     !values.locale.equals(mConfiguration.locale),
13520                                     values.userSetLocale);
13521                }
13522
13523                mConfigurationSeq++;
13524                if (mConfigurationSeq <= 0) {
13525                    mConfigurationSeq = 1;
13526                }
13527                newConfig.seq = mConfigurationSeq;
13528                mConfiguration = newConfig;
13529                Slog.i(TAG, "Config changed: " + newConfig);
13530
13531                final Configuration configCopy = new Configuration(mConfiguration);
13532
13533                // TODO: If our config changes, should we auto dismiss any currently
13534                // showing dialogs?
13535                mShowDialogs = shouldShowDialogs(newConfig);
13536
13537                AttributeCache ac = AttributeCache.instance();
13538                if (ac != null) {
13539                    ac.updateConfiguration(configCopy);
13540                }
13541
13542                // Make sure all resources in our process are updated
13543                // right now, so that anyone who is going to retrieve
13544                // resource values after we return will be sure to get
13545                // the new ones.  This is especially important during
13546                // boot, where the first config change needs to guarantee
13547                // all resources have that config before following boot
13548                // code is executed.
13549                mSystemThread.applyConfigurationToResources(configCopy);
13550
13551                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13552                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13553                    msg.obj = new Configuration(configCopy);
13554                    mHandler.sendMessage(msg);
13555                }
13556
13557                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13558                    ProcessRecord app = mLruProcesses.get(i);
13559                    try {
13560                        if (app.thread != null) {
13561                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13562                                    + app.processName + " new config " + mConfiguration);
13563                            app.thread.scheduleConfigurationChanged(configCopy);
13564                        }
13565                    } catch (Exception e) {
13566                    }
13567                }
13568                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13569                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13570                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13571                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13572                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13573                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13574                    broadcastIntentLocked(null, null,
13575                            new Intent(Intent.ACTION_LOCALE_CHANGED),
13576                            null, null, 0, null, null,
13577                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13578                }
13579            }
13580        }
13581
13582        if (changes != 0 && starting == null) {
13583            // If the configuration changed, and the caller is not already
13584            // in the process of starting an activity, then find the top
13585            // activity to check if its configuration needs to change.
13586            starting = mMainStack.topRunningActivityLocked(null);
13587        }
13588
13589        if (starting != null) {
13590            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
13591            // And we need to make sure at this point that all other activities
13592            // are made visible with the correct configuration.
13593            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
13594        }
13595
13596        if (values != null && mWindowManager != null) {
13597            mWindowManager.setNewConfiguration(mConfiguration);
13598        }
13599
13600        return kept;
13601    }
13602
13603    /**
13604     * Decide based on the configuration whether we should shouw the ANR,
13605     * crash, etc dialogs.  The idea is that if there is no affordnace to
13606     * press the on-screen buttons, we shouldn't show the dialog.
13607     *
13608     * A thought: SystemUI might also want to get told about this, the Power
13609     * dialog / global actions also might want different behaviors.
13610     */
13611    private static final boolean shouldShowDialogs(Configuration config) {
13612        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
13613                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
13614    }
13615
13616    /**
13617     * Save the locale.  You must be inside a synchronized (this) block.
13618     */
13619    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13620        if(isDiff) {
13621            SystemProperties.set("user.language", l.getLanguage());
13622            SystemProperties.set("user.region", l.getCountry());
13623        }
13624
13625        if(isPersist) {
13626            SystemProperties.set("persist.sys.language", l.getLanguage());
13627            SystemProperties.set("persist.sys.country", l.getCountry());
13628            SystemProperties.set("persist.sys.localevar", l.getVariant());
13629        }
13630    }
13631
13632    @Override
13633    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
13634        ActivityRecord srec = ActivityRecord.forToken(token);
13635        return srec != null && srec.task.affinity != null &&
13636                srec.task.affinity.equals(destAffinity);
13637    }
13638
13639    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
13640            Intent resultData) {
13641        ComponentName dest = destIntent.getComponent();
13642
13643        synchronized (this) {
13644            ActivityRecord srec = ActivityRecord.forToken(token);
13645            if (srec == null) {
13646                return false;
13647            }
13648            ArrayList<ActivityRecord> history = srec.stack.mHistory;
13649            final int start = history.indexOf(srec);
13650            if (start < 0) {
13651                // Current activity is not in history stack; do nothing.
13652                return false;
13653            }
13654            int finishTo = start - 1;
13655            ActivityRecord parent = null;
13656            boolean foundParentInTask = false;
13657            if (dest != null) {
13658                TaskRecord tr = srec.task;
13659                for (int i = start - 1; i >= 0; i--) {
13660                    ActivityRecord r = history.get(i);
13661                    if (tr != r.task) {
13662                        // Couldn't find parent in the same task; stop at the one above this.
13663                        // (Root of current task; in-app "home" behavior)
13664                        // Always at least finish the current activity.
13665                        finishTo = Math.min(start - 1, i + 1);
13666                        parent = history.get(finishTo);
13667                        break;
13668                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
13669                            r.info.name.equals(dest.getClassName())) {
13670                        finishTo = i;
13671                        parent = r;
13672                        foundParentInTask = true;
13673                        break;
13674                    }
13675                }
13676            }
13677
13678            if (mController != null) {
13679                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
13680                if (next != null) {
13681                    // ask watcher if this is allowed
13682                    boolean resumeOK = true;
13683                    try {
13684                        resumeOK = mController.activityResuming(next.packageName);
13685                    } catch (RemoteException e) {
13686                        mController = null;
13687                    }
13688
13689                    if (!resumeOK) {
13690                        return false;
13691                    }
13692                }
13693            }
13694            final long origId = Binder.clearCallingIdentity();
13695            for (int i = start; i > finishTo; i--) {
13696                ActivityRecord r = history.get(i);
13697                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
13698                        "navigate-up");
13699                // Only return the supplied result for the first activity finished
13700                resultCode = Activity.RESULT_CANCELED;
13701                resultData = null;
13702            }
13703
13704            if (parent != null && foundParentInTask) {
13705                final int parentLaunchMode = parent.info.launchMode;
13706                final int destIntentFlags = destIntent.getFlags();
13707                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
13708                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
13709                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
13710                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
13711                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
13712                } else {
13713                    try {
13714                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
13715                                destIntent.getComponent(), 0, UserId.getCallingUserId());
13716                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
13717                                null, aInfo, parent.appToken, null,
13718                                0, -1, parent.launchedFromUid, 0, null, true, null);
13719                        foundParentInTask = res == ActivityManager.START_SUCCESS;
13720                    } catch (RemoteException e) {
13721                        foundParentInTask = false;
13722                    }
13723                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
13724                            resultData, "navigate-up");
13725                }
13726            }
13727            Binder.restoreCallingIdentity(origId);
13728            return foundParentInTask;
13729        }
13730    }
13731
13732    public int getLaunchedFromUid(IBinder activityToken) {
13733        ActivityRecord srec = ActivityRecord.forToken(activityToken);
13734        if (srec == null) {
13735            return -1;
13736        }
13737        return srec.launchedFromUid;
13738    }
13739
13740    // =========================================================
13741    // LIFETIME MANAGEMENT
13742    // =========================================================
13743
13744    // Returns which broadcast queue the app is the current [or imminent] receiver
13745    // on, or 'null' if the app is not an active broadcast recipient.
13746    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
13747        BroadcastRecord r = app.curReceiver;
13748        if (r != null) {
13749            return r.queue;
13750        }
13751
13752        // It's not the current receiver, but it might be starting up to become one
13753        synchronized (this) {
13754            for (BroadcastQueue queue : mBroadcastQueues) {
13755                r = queue.mPendingBroadcast;
13756                if (r != null && r.curApp == app) {
13757                    // found it; report which queue it's in
13758                    return queue;
13759                }
13760            }
13761        }
13762
13763        return null;
13764    }
13765
13766    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
13767            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
13768        if (mAdjSeq == app.adjSeq) {
13769            // This adjustment has already been computed.  If we are calling
13770            // from the top, we may have already computed our adjustment with
13771            // an earlier hidden adjustment that isn't really for us... if
13772            // so, use the new hidden adjustment.
13773            if (!recursed && app.hidden) {
13774                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
13775            }
13776            return app.curRawAdj;
13777        }
13778
13779        if (app.thread == null) {
13780            app.adjSeq = mAdjSeq;
13781            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13782            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
13783        }
13784
13785        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13786        app.adjSource = null;
13787        app.adjTarget = null;
13788        app.empty = false;
13789        app.hidden = false;
13790
13791        final int activitiesSize = app.activities.size();
13792
13793        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13794            // The max adjustment doesn't allow this app to be anything
13795            // below foreground, so it is not worth doing work for it.
13796            app.adjType = "fixed";
13797            app.adjSeq = mAdjSeq;
13798            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
13799            app.foregroundActivities = false;
13800            app.keeping = true;
13801            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13802            // System process can do UI, and when they do we want to have
13803            // them trim their memory after the user leaves the UI.  To
13804            // facilitate this, here we need to determine whether or not it
13805            // is currently showing UI.
13806            app.systemNoUi = true;
13807            if (app == TOP_APP) {
13808                app.systemNoUi = false;
13809            } else if (activitiesSize > 0) {
13810                for (int j = 0; j < activitiesSize; j++) {
13811                    final ActivityRecord r = app.activities.get(j);
13812                    if (r.visible) {
13813                        app.systemNoUi = false;
13814                        break;
13815                    }
13816                }
13817            }
13818            return (app.curAdj=app.maxAdj);
13819        }
13820
13821        app.keeping = false;
13822        app.systemNoUi = false;
13823
13824        // Determine the importance of the process, starting with most
13825        // important to least, and assign an appropriate OOM adjustment.
13826        int adj;
13827        int schedGroup;
13828        boolean foregroundActivities = false;
13829        boolean interesting = false;
13830        BroadcastQueue queue;
13831        if (app == TOP_APP) {
13832            // The last app on the list is the foreground app.
13833            adj = ProcessList.FOREGROUND_APP_ADJ;
13834            schedGroup = Process.THREAD_GROUP_DEFAULT;
13835            app.adjType = "top-activity";
13836            foregroundActivities = true;
13837            interesting = true;
13838        } else if (app.instrumentationClass != null) {
13839            // Don't want to kill running instrumentation.
13840            adj = ProcessList.FOREGROUND_APP_ADJ;
13841            schedGroup = Process.THREAD_GROUP_DEFAULT;
13842            app.adjType = "instrumentation";
13843            interesting = true;
13844        } else if ((queue = isReceivingBroadcast(app)) != null) {
13845            // An app that is currently receiving a broadcast also
13846            // counts as being in the foreground for OOM killer purposes.
13847            // It's placed in a sched group based on the nature of the
13848            // broadcast as reflected by which queue it's active in.
13849            adj = ProcessList.FOREGROUND_APP_ADJ;
13850            schedGroup = (queue == mFgBroadcastQueue)
13851                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
13852            app.adjType = "broadcast";
13853        } else if (app.executingServices.size() > 0) {
13854            // An app that is currently executing a service callback also
13855            // counts as being in the foreground.
13856            adj = ProcessList.FOREGROUND_APP_ADJ;
13857            schedGroup = Process.THREAD_GROUP_DEFAULT;
13858            app.adjType = "exec-service";
13859        } else if (activitiesSize > 0) {
13860            // This app is in the background with paused activities.
13861            // We inspect activities to potentially upgrade adjustment further below.
13862            adj = hiddenAdj;
13863            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13864            app.hidden = true;
13865            app.adjType = "bg-activities";
13866        } else {
13867            // A very not-needed process.  If this is lower in the lru list,
13868            // we will push it in to the empty bucket.
13869            adj = hiddenAdj;
13870            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13871            app.hidden = true;
13872            app.empty = true;
13873            app.adjType = "bg-empty";
13874        }
13875
13876        boolean hasStoppingActivities = false;
13877
13878        // Examine all activities if not already foreground.
13879        if (!foregroundActivities && activitiesSize > 0) {
13880            for (int j = 0; j < activitiesSize; j++) {
13881                final ActivityRecord r = app.activities.get(j);
13882                if (r.visible) {
13883                    // App has a visible activity; only upgrade adjustment.
13884                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
13885                        adj = ProcessList.VISIBLE_APP_ADJ;
13886                        app.adjType = "visible";
13887                    }
13888                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13889                    app.hidden = false;
13890                    foregroundActivities = true;
13891                    break;
13892                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
13893                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13894                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13895                        app.adjType = "pausing";
13896                    }
13897                    app.hidden = false;
13898                    foregroundActivities = true;
13899                } else if (r.state == ActivityState.STOPPING) {
13900                    // We will apply the actual adjustment later, because
13901                    // we want to allow this process to immediately go through
13902                    // any memory trimming that is in effect.
13903                    app.hidden = false;
13904                    foregroundActivities = true;
13905                    hasStoppingActivities = true;
13906                }
13907            }
13908        }
13909
13910        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13911            if (app.foregroundServices) {
13912                // The user is aware of this app, so make it visible.
13913                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13914                app.hidden = false;
13915                app.adjType = "foreground-service";
13916                schedGroup = Process.THREAD_GROUP_DEFAULT;
13917            } else if (app.forcingToForeground != null) {
13918                // The user is aware of this app, so make it visible.
13919                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13920                app.hidden = false;
13921                app.adjType = "force-foreground";
13922                app.adjSource = app.forcingToForeground;
13923                schedGroup = Process.THREAD_GROUP_DEFAULT;
13924            }
13925        }
13926
13927        if (app.foregroundServices) {
13928            interesting = true;
13929        }
13930
13931        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
13932            // We don't want to kill the current heavy-weight process.
13933            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
13934            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13935            app.hidden = false;
13936            app.adjType = "heavy";
13937        }
13938
13939        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
13940            // This process is hosting what we currently consider to be the
13941            // home app, so we don't want to let it go into the background.
13942            adj = ProcessList.HOME_APP_ADJ;
13943            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13944            app.hidden = false;
13945            app.adjType = "home";
13946        }
13947
13948        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13949                && app.activities.size() > 0) {
13950            // This was the previous process that showed UI to the user.
13951            // We want to try to keep it around more aggressively, to give
13952            // a good experience around switching between two apps.
13953            adj = ProcessList.PREVIOUS_APP_ADJ;
13954            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13955            app.hidden = false;
13956            app.adjType = "previous";
13957        }
13958
13959        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13960                + " reason=" + app.adjType);
13961
13962        // By default, we use the computed adjustment.  It may be changed if
13963        // there are applications dependent on our services or providers, but
13964        // this gives us a baseline and makes sure we don't get into an
13965        // infinite recursion.
13966        app.adjSeq = mAdjSeq;
13967        app.curRawAdj = app.nonStoppingAdj = adj;
13968
13969        if (mBackupTarget != null && app == mBackupTarget.app) {
13970            // If possible we want to avoid killing apps while they're being backed up
13971            if (adj > ProcessList.BACKUP_APP_ADJ) {
13972                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13973                adj = ProcessList.BACKUP_APP_ADJ;
13974                app.adjType = "backup";
13975                app.hidden = false;
13976            }
13977        }
13978
13979        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13980                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13981            final long now = SystemClock.uptimeMillis();
13982            // This process is more important if the top activity is
13983            // bound to the service.
13984            Iterator<ServiceRecord> jt = app.services.iterator();
13985            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13986                ServiceRecord s = jt.next();
13987                if (s.startRequested) {
13988                    if (app.hasShownUi && app != mHomeProcess) {
13989                        // If this process has shown some UI, let it immediately
13990                        // go to the LRU list because it may be pretty heavy with
13991                        // UI stuff.  We'll tag it with a label just to help
13992                        // debug and understand what is going on.
13993                        if (adj > ProcessList.SERVICE_ADJ) {
13994                            app.adjType = "started-bg-ui-services";
13995                        }
13996                    } else {
13997                        if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13998                            // This service has seen some activity within
13999                            // recent memory, so we will keep its process ahead
14000                            // of the background processes.
14001                            if (adj > ProcessList.SERVICE_ADJ) {
14002                                adj = ProcessList.SERVICE_ADJ;
14003                                app.adjType = "started-services";
14004                                app.hidden = false;
14005                            }
14006                        }
14007                        // If we have let the service slide into the background
14008                        // state, still have some text describing what it is doing
14009                        // even though the service no longer has an impact.
14010                        if (adj > ProcessList.SERVICE_ADJ) {
14011                            app.adjType = "started-bg-services";
14012                        }
14013                    }
14014                    // Don't kill this process because it is doing work; it
14015                    // has said it is doing work.
14016                    app.keeping = true;
14017                }
14018                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14019                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14020                    Iterator<ArrayList<ConnectionRecord>> kt
14021                            = s.connections.values().iterator();
14022                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
14023                        ArrayList<ConnectionRecord> clist = kt.next();
14024                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
14025                            // XXX should compute this based on the max of
14026                            // all connected clients.
14027                            ConnectionRecord cr = clist.get(i);
14028                            if (cr.binding.client == app) {
14029                                // Binding to ourself is not interesting.
14030                                continue;
14031                            }
14032                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14033                                ProcessRecord client = cr.binding.client;
14034                                int clientAdj = adj;
14035                                int myHiddenAdj = hiddenAdj;
14036                                if (myHiddenAdj > client.hiddenAdj) {
14037                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
14038                                        myHiddenAdj = client.hiddenAdj;
14039                                    } else {
14040                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
14041                                    }
14042                                }
14043                                clientAdj = computeOomAdjLocked(
14044                                    client, myHiddenAdj, TOP_APP, true, doingAll);
14045                                String adjType = null;
14046                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14047                                    // Not doing bind OOM management, so treat
14048                                    // this guy more like a started service.
14049                                    if (app.hasShownUi && app != mHomeProcess) {
14050                                        // If this process has shown some UI, let it immediately
14051                                        // go to the LRU list because it may be pretty heavy with
14052                                        // UI stuff.  We'll tag it with a label just to help
14053                                        // debug and understand what is going on.
14054                                        if (adj > clientAdj) {
14055                                            adjType = "bound-bg-ui-services";
14056                                        }
14057                                        app.hidden = false;
14058                                        clientAdj = adj;
14059                                    } else {
14060                                        if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14061                                            // This service has not seen activity within
14062                                            // recent memory, so allow it to drop to the
14063                                            // LRU list if there is no other reason to keep
14064                                            // it around.  We'll also tag it with a label just
14065                                            // to help debug and undertand what is going on.
14066                                            if (adj > clientAdj) {
14067                                                adjType = "bound-bg-services";
14068                                            }
14069                                            clientAdj = adj;
14070                                        }
14071                                    }
14072                                }
14073                                if (adj > clientAdj) {
14074                                    // If this process has recently shown UI, and
14075                                    // the process that is binding to it is less
14076                                    // important than being visible, then we don't
14077                                    // care about the binding as much as we care
14078                                    // about letting this process get into the LRU
14079                                    // list to be killed and restarted if needed for
14080                                    // memory.
14081                                    if (app.hasShownUi && app != mHomeProcess
14082                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14083                                        adjType = "bound-bg-ui-services";
14084                                    } else {
14085                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14086                                                |Context.BIND_IMPORTANT)) != 0) {
14087                                            adj = clientAdj;
14088                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14089                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14090                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14091                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14092                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14093                                            adj = clientAdj;
14094                                        } else {
14095                                            app.pendingUiClean = true;
14096                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
14097                                                adj = ProcessList.VISIBLE_APP_ADJ;
14098                                            }
14099                                        }
14100                                        if (!client.hidden) {
14101                                            app.hidden = false;
14102                                        }
14103                                        if (client.keeping) {
14104                                            app.keeping = true;
14105                                        }
14106                                        adjType = "service";
14107                                    }
14108                                }
14109                                if (adjType != null) {
14110                                    app.adjType = adjType;
14111                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14112                                            .REASON_SERVICE_IN_USE;
14113                                    app.adjSource = cr.binding.client;
14114                                    app.adjSourceOom = clientAdj;
14115                                    app.adjTarget = s.name;
14116                                }
14117                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14118                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14119                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14120                                    }
14121                                }
14122                            }
14123                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14124                                ActivityRecord a = cr.activity;
14125                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14126                                        (a.visible || a.state == ActivityState.RESUMED
14127                                         || a.state == ActivityState.PAUSING)) {
14128                                    adj = ProcessList.FOREGROUND_APP_ADJ;
14129                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14130                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14131                                    }
14132                                    app.hidden = false;
14133                                    app.adjType = "service";
14134                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14135                                            .REASON_SERVICE_IN_USE;
14136                                    app.adjSource = a;
14137                                    app.adjSourceOom = adj;
14138                                    app.adjTarget = s.name;
14139                                }
14140                            }
14141                        }
14142                    }
14143                }
14144            }
14145
14146            // Finally, if this process has active services running in it, we
14147            // would like to avoid killing it unless it would prevent the current
14148            // application from running.  By default we put the process in
14149            // with the rest of the background processes; as we scan through
14150            // its services we may bump it up from there.
14151            if (adj > hiddenAdj) {
14152                adj = hiddenAdj;
14153                app.hidden = false;
14154                app.adjType = "bg-services";
14155            }
14156        }
14157
14158        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14159                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14160            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
14161            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
14162                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14163                ContentProviderRecord cpr = jt.next();
14164                for (int i = cpr.connections.size()-1;
14165                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14166                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
14167                        i--) {
14168                    ContentProviderConnection conn = cpr.connections.get(i);
14169                    ProcessRecord client = conn.client;
14170                    if (client == app) {
14171                        // Being our own client is not interesting.
14172                        continue;
14173                    }
14174                    int myHiddenAdj = hiddenAdj;
14175                    if (myHiddenAdj > client.hiddenAdj) {
14176                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
14177                            myHiddenAdj = client.hiddenAdj;
14178                        } else {
14179                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
14180                        }
14181                    }
14182                    int clientAdj = computeOomAdjLocked(
14183                        client, myHiddenAdj, TOP_APP, true, doingAll);
14184                    if (adj > clientAdj) {
14185                        if (app.hasShownUi && app != mHomeProcess
14186                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14187                            app.adjType = "bg-ui-provider";
14188                        } else {
14189                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14190                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14191                            app.adjType = "provider";
14192                        }
14193                        if (!client.hidden) {
14194                            app.hidden = false;
14195                        }
14196                        if (client.keeping) {
14197                            app.keeping = true;
14198                        }
14199                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14200                                .REASON_PROVIDER_IN_USE;
14201                        app.adjSource = client;
14202                        app.adjSourceOom = clientAdj;
14203                        app.adjTarget = cpr.name;
14204                    }
14205                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14206                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14207                    }
14208                }
14209                // If the provider has external (non-framework) process
14210                // dependencies, ensure that its adjustment is at least
14211                // FOREGROUND_APP_ADJ.
14212                if (cpr.hasExternalProcessHandles()) {
14213                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14214                        adj = ProcessList.FOREGROUND_APP_ADJ;
14215                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14216                        app.hidden = false;
14217                        app.keeping = true;
14218                        app.adjType = "provider";
14219                        app.adjTarget = cpr.name;
14220                    }
14221                }
14222            }
14223        }
14224
14225        if (adj == ProcessList.SERVICE_ADJ) {
14226            if (doingAll) {
14227                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14228                mNewNumServiceProcs++;
14229            }
14230            if (app.serviceb) {
14231                adj = ProcessList.SERVICE_B_ADJ;
14232            }
14233        } else {
14234            app.serviceb = false;
14235        }
14236
14237        app.nonStoppingAdj = adj;
14238
14239        if (hasStoppingActivities) {
14240            // Only upgrade adjustment.
14241            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14242                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14243                app.adjType = "stopping";
14244            }
14245        }
14246
14247        app.curRawAdj = adj;
14248
14249        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14250        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14251        if (adj > app.maxAdj) {
14252            adj = app.maxAdj;
14253            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14254                schedGroup = Process.THREAD_GROUP_DEFAULT;
14255            }
14256        }
14257        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14258            app.keeping = true;
14259        }
14260
14261        if (app.hasAboveClient) {
14262            // If this process has bound to any services with BIND_ABOVE_CLIENT,
14263            // then we need to drop its adjustment to be lower than the service's
14264            // in order to honor the request.  We want to drop it by one adjustment
14265            // level...  but there is special meaning applied to various levels so
14266            // we will skip some of them.
14267            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
14268                // System process will not get dropped, ever
14269            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14270                adj = ProcessList.VISIBLE_APP_ADJ;
14271            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14272                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14273            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14274                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
14275            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
14276                adj++;
14277            }
14278        }
14279
14280        int importance = app.memImportance;
14281        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14282            app.curAdj = adj;
14283            app.curSchedGroup = schedGroup;
14284            if (!interesting) {
14285                // For this reporting, if there is not something explicitly
14286                // interesting in this process then we will push it to the
14287                // background importance.
14288                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14289            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14290                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14291            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14292                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14293            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14294                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14295            } else if (adj >= ProcessList.SERVICE_ADJ) {
14296                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14297            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14298                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14299            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14300                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14301            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14302                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14303            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14304                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14305            } else {
14306                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14307            }
14308        }
14309
14310        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14311        if (foregroundActivities != app.foregroundActivities) {
14312            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14313        }
14314        if (changes != 0) {
14315            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14316            app.memImportance = importance;
14317            app.foregroundActivities = foregroundActivities;
14318            int i = mPendingProcessChanges.size()-1;
14319            ProcessChangeItem item = null;
14320            while (i >= 0) {
14321                item = mPendingProcessChanges.get(i);
14322                if (item.pid == app.pid) {
14323                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14324                    break;
14325                }
14326                i--;
14327            }
14328            if (i < 0) {
14329                // No existing item in pending changes; need a new one.
14330                final int NA = mAvailProcessChanges.size();
14331                if (NA > 0) {
14332                    item = mAvailProcessChanges.remove(NA-1);
14333                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14334                } else {
14335                    item = new ProcessChangeItem();
14336                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14337                }
14338                item.changes = 0;
14339                item.pid = app.pid;
14340                item.uid = app.info.uid;
14341                if (mPendingProcessChanges.size() == 0) {
14342                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14343                            "*** Enqueueing dispatch processes changed!");
14344                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14345                }
14346                mPendingProcessChanges.add(item);
14347            }
14348            item.changes |= changes;
14349            item.importance = importance;
14350            item.foregroundActivities = foregroundActivities;
14351            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14352                    + Integer.toHexString(System.identityHashCode(item))
14353                    + " " + app.toShortString() + ": changes=" + item.changes
14354                    + " importance=" + item.importance
14355                    + " foreground=" + item.foregroundActivities
14356                    + " type=" + app.adjType + " source=" + app.adjSource
14357                    + " target=" + app.adjTarget);
14358        }
14359
14360        return app.curRawAdj;
14361    }
14362
14363    /**
14364     * Ask a given process to GC right now.
14365     */
14366    final void performAppGcLocked(ProcessRecord app) {
14367        try {
14368            app.lastRequestedGc = SystemClock.uptimeMillis();
14369            if (app.thread != null) {
14370                if (app.reportLowMemory) {
14371                    app.reportLowMemory = false;
14372                    app.thread.scheduleLowMemory();
14373                } else {
14374                    app.thread.processInBackground();
14375                }
14376            }
14377        } catch (Exception e) {
14378            // whatever.
14379        }
14380    }
14381
14382    /**
14383     * Returns true if things are idle enough to perform GCs.
14384     */
14385    private final boolean canGcNowLocked() {
14386        boolean processingBroadcasts = false;
14387        for (BroadcastQueue q : mBroadcastQueues) {
14388            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14389                processingBroadcasts = true;
14390            }
14391        }
14392        return !processingBroadcasts
14393                && (mSleeping || (mMainStack.mResumedActivity != null &&
14394                        mMainStack.mResumedActivity.idle));
14395    }
14396
14397    /**
14398     * Perform GCs on all processes that are waiting for it, but only
14399     * if things are idle.
14400     */
14401    final void performAppGcsLocked() {
14402        final int N = mProcessesToGc.size();
14403        if (N <= 0) {
14404            return;
14405        }
14406        if (canGcNowLocked()) {
14407            while (mProcessesToGc.size() > 0) {
14408                ProcessRecord proc = mProcessesToGc.remove(0);
14409                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14410                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14411                            <= SystemClock.uptimeMillis()) {
14412                        // To avoid spamming the system, we will GC processes one
14413                        // at a time, waiting a few seconds between each.
14414                        performAppGcLocked(proc);
14415                        scheduleAppGcsLocked();
14416                        return;
14417                    } else {
14418                        // It hasn't been long enough since we last GCed this
14419                        // process...  put it in the list to wait for its time.
14420                        addProcessToGcListLocked(proc);
14421                        break;
14422                    }
14423                }
14424            }
14425
14426            scheduleAppGcsLocked();
14427        }
14428    }
14429
14430    /**
14431     * If all looks good, perform GCs on all processes waiting for them.
14432     */
14433    final void performAppGcsIfAppropriateLocked() {
14434        if (canGcNowLocked()) {
14435            performAppGcsLocked();
14436            return;
14437        }
14438        // Still not idle, wait some more.
14439        scheduleAppGcsLocked();
14440    }
14441
14442    /**
14443     * Schedule the execution of all pending app GCs.
14444     */
14445    final void scheduleAppGcsLocked() {
14446        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14447
14448        if (mProcessesToGc.size() > 0) {
14449            // Schedule a GC for the time to the next process.
14450            ProcessRecord proc = mProcessesToGc.get(0);
14451            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14452
14453            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14454            long now = SystemClock.uptimeMillis();
14455            if (when < (now+GC_TIMEOUT)) {
14456                when = now + GC_TIMEOUT;
14457            }
14458            mHandler.sendMessageAtTime(msg, when);
14459        }
14460    }
14461
14462    /**
14463     * Add a process to the array of processes waiting to be GCed.  Keeps the
14464     * list in sorted order by the last GC time.  The process can't already be
14465     * on the list.
14466     */
14467    final void addProcessToGcListLocked(ProcessRecord proc) {
14468        boolean added = false;
14469        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14470            if (mProcessesToGc.get(i).lastRequestedGc <
14471                    proc.lastRequestedGc) {
14472                added = true;
14473                mProcessesToGc.add(i+1, proc);
14474                break;
14475            }
14476        }
14477        if (!added) {
14478            mProcessesToGc.add(0, proc);
14479        }
14480    }
14481
14482    /**
14483     * Set up to ask a process to GC itself.  This will either do it
14484     * immediately, or put it on the list of processes to gc the next
14485     * time things are idle.
14486     */
14487    final void scheduleAppGcLocked(ProcessRecord app) {
14488        long now = SystemClock.uptimeMillis();
14489        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
14490            return;
14491        }
14492        if (!mProcessesToGc.contains(app)) {
14493            addProcessToGcListLocked(app);
14494            scheduleAppGcsLocked();
14495        }
14496    }
14497
14498    final void checkExcessivePowerUsageLocked(boolean doKills) {
14499        updateCpuStatsNow();
14500
14501        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14502        boolean doWakeKills = doKills;
14503        boolean doCpuKills = doKills;
14504        if (mLastPowerCheckRealtime == 0) {
14505            doWakeKills = false;
14506        }
14507        if (mLastPowerCheckUptime == 0) {
14508            doCpuKills = false;
14509        }
14510        if (stats.isScreenOn()) {
14511            doWakeKills = false;
14512        }
14513        final long curRealtime = SystemClock.elapsedRealtime();
14514        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14515        final long curUptime = SystemClock.uptimeMillis();
14516        final long uptimeSince = curUptime - mLastPowerCheckUptime;
14517        mLastPowerCheckRealtime = curRealtime;
14518        mLastPowerCheckUptime = curUptime;
14519        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14520            doWakeKills = false;
14521        }
14522        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14523            doCpuKills = false;
14524        }
14525        int i = mLruProcesses.size();
14526        while (i > 0) {
14527            i--;
14528            ProcessRecord app = mLruProcesses.get(i);
14529            if (!app.keeping) {
14530                long wtime;
14531                synchronized (stats) {
14532                    wtime = stats.getProcessWakeTime(app.info.uid,
14533                            app.pid, curRealtime);
14534                }
14535                long wtimeUsed = wtime - app.lastWakeTime;
14536                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14537                if (DEBUG_POWER) {
14538                    StringBuilder sb = new StringBuilder(128);
14539                    sb.append("Wake for ");
14540                    app.toShortString(sb);
14541                    sb.append(": over ");
14542                    TimeUtils.formatDuration(realtimeSince, sb);
14543                    sb.append(" used ");
14544                    TimeUtils.formatDuration(wtimeUsed, sb);
14545                    sb.append(" (");
14546                    sb.append((wtimeUsed*100)/realtimeSince);
14547                    sb.append("%)");
14548                    Slog.i(TAG, sb.toString());
14549                    sb.setLength(0);
14550                    sb.append("CPU for ");
14551                    app.toShortString(sb);
14552                    sb.append(": over ");
14553                    TimeUtils.formatDuration(uptimeSince, sb);
14554                    sb.append(" used ");
14555                    TimeUtils.formatDuration(cputimeUsed, sb);
14556                    sb.append(" (");
14557                    sb.append((cputimeUsed*100)/uptimeSince);
14558                    sb.append("%)");
14559                    Slog.i(TAG, sb.toString());
14560                }
14561                // If a process has held a wake lock for more
14562                // than 50% of the time during this period,
14563                // that sounds bad.  Kill!
14564                if (doWakeKills && realtimeSince > 0
14565                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
14566                    synchronized (stats) {
14567                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14568                                realtimeSince, wtimeUsed);
14569                    }
14570                    Slog.w(TAG, "Excessive wake lock in " + app.processName
14571                            + " (pid " + app.pid + "): held " + wtimeUsed
14572                            + " during " + realtimeSince);
14573                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14574                            app.processName, app.setAdj, "excessive wake lock");
14575                    Process.killProcessQuiet(app.pid);
14576                } else if (doCpuKills && uptimeSince > 0
14577                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
14578                    synchronized (stats) {
14579                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14580                                uptimeSince, cputimeUsed);
14581                    }
14582                    Slog.w(TAG, "Excessive CPU in " + app.processName
14583                            + " (pid " + app.pid + "): used " + cputimeUsed
14584                            + " during " + uptimeSince);
14585                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14586                            app.processName, app.setAdj, "excessive cpu");
14587                    Process.killProcessQuiet(app.pid);
14588                } else {
14589                    app.lastWakeTime = wtime;
14590                    app.lastCpuTime = app.curCpuTime;
14591                }
14592            }
14593        }
14594    }
14595
14596    private final boolean updateOomAdjLocked(
14597            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
14598        app.hiddenAdj = hiddenAdj;
14599
14600        if (app.thread == null) {
14601            return false;
14602        }
14603
14604        final boolean wasKeeping = app.keeping;
14605
14606        boolean success = true;
14607
14608        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
14609
14610        if (app.curRawAdj != app.setRawAdj) {
14611            if (wasKeeping && !app.keeping) {
14612                // This app is no longer something we want to keep.  Note
14613                // its current wake lock time to later know to kill it if
14614                // it is not behaving well.
14615                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14616                synchronized (stats) {
14617                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14618                            app.pid, SystemClock.elapsedRealtime());
14619                }
14620                app.lastCpuTime = app.curCpuTime;
14621            }
14622
14623            app.setRawAdj = app.curRawAdj;
14624        }
14625
14626        if (app.curAdj != app.setAdj) {
14627            if (Process.setOomAdj(app.pid, app.curAdj)) {
14628                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14629                    TAG, "Set " + app.pid + " " + app.processName +
14630                    " adj " + app.curAdj + ": " + app.adjType);
14631                app.setAdj = app.curAdj;
14632            } else {
14633                success = false;
14634                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
14635            }
14636        }
14637        if (app.setSchedGroup != app.curSchedGroup) {
14638            app.setSchedGroup = app.curSchedGroup;
14639            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14640                    "Setting process group of " + app.processName
14641                    + " to " + app.curSchedGroup);
14642            if (app.waitingToKill != null &&
14643                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14644                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14645                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14646                        app.processName, app.setAdj, app.waitingToKill);
14647                app.killedBackground = true;
14648                Process.killProcessQuiet(app.pid);
14649                success = false;
14650            } else {
14651                if (true) {
14652                    long oldId = Binder.clearCallingIdentity();
14653                    try {
14654                        Process.setProcessGroup(app.pid, app.curSchedGroup);
14655                    } catch (Exception e) {
14656                        Slog.w(TAG, "Failed setting process group of " + app.pid
14657                                + " to " + app.curSchedGroup);
14658                        e.printStackTrace();
14659                    } finally {
14660                        Binder.restoreCallingIdentity(oldId);
14661                    }
14662                } else {
14663                    if (app.thread != null) {
14664                        try {
14665                            app.thread.setSchedulingGroup(app.curSchedGroup);
14666                        } catch (RemoteException e) {
14667                        }
14668                    }
14669                }
14670            }
14671        }
14672        return success;
14673    }
14674
14675    private final ActivityRecord resumedAppLocked() {
14676        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
14677        if (resumedActivity == null || resumedActivity.app == null) {
14678            resumedActivity = mMainStack.mPausingActivity;
14679            if (resumedActivity == null || resumedActivity.app == null) {
14680                resumedActivity = mMainStack.topRunningActivityLocked(null);
14681            }
14682        }
14683        return resumedActivity;
14684    }
14685
14686    private final boolean updateOomAdjLocked(ProcessRecord app) {
14687        final ActivityRecord TOP_ACT = resumedAppLocked();
14688        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14689        int curAdj = app.curAdj;
14690        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14691            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14692
14693        mAdjSeq++;
14694
14695        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
14696        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14697            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14698        if (nowHidden != wasHidden) {
14699            // Changed to/from hidden state, so apps after it in the LRU
14700            // list may also be changed.
14701            updateOomAdjLocked();
14702        }
14703        return success;
14704    }
14705
14706    final void updateOomAdjLocked() {
14707        final ActivityRecord TOP_ACT = resumedAppLocked();
14708        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14709
14710        if (false) {
14711            RuntimeException e = new RuntimeException();
14712            e.fillInStackTrace();
14713            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
14714        }
14715
14716        mAdjSeq++;
14717        mNewNumServiceProcs = 0;
14718
14719        // Let's determine how many processes we have running vs.
14720        // how many slots we have for background processes; we may want
14721        // to put multiple processes in a slot of there are enough of
14722        // them.
14723        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
14724        int factor = (mLruProcesses.size()-4)/numSlots;
14725        if (factor < 1) factor = 1;
14726        int step = 0;
14727        int numHidden = 0;
14728        int numTrimming = 0;
14729
14730        // First update the OOM adjustment for each of the
14731        // application processes based on their current state.
14732        int i = mLruProcesses.size();
14733        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
14734        while (i > 0) {
14735            i--;
14736            ProcessRecord app = mLruProcesses.get(i);
14737            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
14738            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14739            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
14740                && app.curAdj == curHiddenAdj) {
14741                step++;
14742                if (step >= factor) {
14743                    step = 0;
14744                    curHiddenAdj++;
14745                }
14746            }
14747            if (!app.killedBackground) {
14748                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14749                    numHidden++;
14750                    if (numHidden > mProcessLimit) {
14751                        Slog.i(TAG, "No longer want " + app.processName
14752                                + " (pid " + app.pid + "): hidden #" + numHidden);
14753                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14754                                app.processName, app.setAdj, "too many background");
14755                        app.killedBackground = true;
14756                        Process.killProcessQuiet(app.pid);
14757                    }
14758                }
14759                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14760                    // If this is an isolated process, and there are no
14761                    // services running in it, then the process is no longer
14762                    // needed.  We agressively kill these because we can by
14763                    // definition not re-use the same process again, and it is
14764                    // good to avoid having whatever code was running in them
14765                    // left sitting around after no longer needed.
14766                    Slog.i(TAG, "Isolated process " + app.processName
14767                            + " (pid " + app.pid + ") no longer needed");
14768                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14769                            app.processName, app.setAdj, "isolated not needed");
14770                    app.killedBackground = true;
14771                    Process.killProcessQuiet(app.pid);
14772                }
14773                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14774                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14775                        && !app.killedBackground) {
14776                    numTrimming++;
14777                }
14778            }
14779        }
14780
14781        mNumServiceProcs = mNewNumServiceProcs;
14782
14783        // Now determine the memory trimming level of background processes.
14784        // Unfortunately we need to start at the back of the list to do this
14785        // properly.  We only do this if the number of background apps we
14786        // are managing to keep around is less than half the maximum we desire;
14787        // if we are keeping a good number around, we'll let them use whatever
14788        // memory they want.
14789        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
14790            final int N = mLruProcesses.size();
14791            factor = numTrimming/3;
14792            int minFactor = 2;
14793            if (mHomeProcess != null) minFactor++;
14794            if (mPreviousProcess != null) minFactor++;
14795            if (factor < minFactor) factor = minFactor;
14796            step = 0;
14797            int fgTrimLevel;
14798            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
14799                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
14800            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
14801                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
14802            } else {
14803                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
14804            }
14805            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
14806            for (i=0; i<N; i++) {
14807                ProcessRecord app = mLruProcesses.get(i);
14808                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14809                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14810                        && !app.killedBackground) {
14811                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
14812                        try {
14813                            app.thread.scheduleTrimMemory(curLevel);
14814                        } catch (RemoteException e) {
14815                        }
14816                        if (false) {
14817                            // For now we won't do this; our memory trimming seems
14818                            // to be good enough at this point that destroying
14819                            // activities causes more harm than good.
14820                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14821                                    && app != mHomeProcess && app != mPreviousProcess) {
14822                                // Need to do this on its own message because the stack may not
14823                                // be in a consistent state at this point.
14824                                // For these apps we will also finish their activities
14825                                // to help them free memory.
14826                                mMainStack.scheduleDestroyActivities(app, false, "trim");
14827                            }
14828                        }
14829                    }
14830                    app.trimMemoryLevel = curLevel;
14831                    step++;
14832                    if (step >= factor) {
14833                        step = 0;
14834                        switch (curLevel) {
14835                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14836                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
14837                                break;
14838                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14839                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14840                                break;
14841                        }
14842                    }
14843                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14844                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
14845                            && app.thread != null) {
14846                        try {
14847                            app.thread.scheduleTrimMemory(
14848                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
14849                        } catch (RemoteException e) {
14850                        }
14851                    }
14852                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14853                } else {
14854                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14855                            && app.pendingUiClean) {
14856                        // If this application is now in the background and it
14857                        // had done UI, then give it the special trim level to
14858                        // have it free UI resources.
14859                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14860                        if (app.trimMemoryLevel < level && app.thread != null) {
14861                            try {
14862                                app.thread.scheduleTrimMemory(level);
14863                            } catch (RemoteException e) {
14864                            }
14865                        }
14866                        app.pendingUiClean = false;
14867                    }
14868                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
14869                        try {
14870                            app.thread.scheduleTrimMemory(fgTrimLevel);
14871                        } catch (RemoteException e) {
14872                        }
14873                    }
14874                    app.trimMemoryLevel = fgTrimLevel;
14875                }
14876            }
14877        } else {
14878            final int N = mLruProcesses.size();
14879            for (i=0; i<N; i++) {
14880                ProcessRecord app = mLruProcesses.get(i);
14881                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14882                        && app.pendingUiClean) {
14883                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14884                            && app.thread != null) {
14885                        try {
14886                            app.thread.scheduleTrimMemory(
14887                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14888                        } catch (RemoteException e) {
14889                        }
14890                    }
14891                    app.pendingUiClean = false;
14892                }
14893                app.trimMemoryLevel = 0;
14894            }
14895        }
14896
14897        if (mAlwaysFinishActivities) {
14898            // Need to do this on its own message because the stack may not
14899            // be in a consistent state at this point.
14900            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
14901        }
14902    }
14903
14904    final void trimApplications() {
14905        synchronized (this) {
14906            int i;
14907
14908            // First remove any unused application processes whose package
14909            // has been removed.
14910            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14911                final ProcessRecord app = mRemovedProcesses.get(i);
14912                if (app.activities.size() == 0
14913                        && app.curReceiver == null && app.services.size() == 0) {
14914                    Slog.i(
14915                        TAG, "Exiting empty application process "
14916                        + app.processName + " ("
14917                        + (app.thread != null ? app.thread.asBinder() : null)
14918                        + ")\n");
14919                    if (app.pid > 0 && app.pid != MY_PID) {
14920                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14921                                app.processName, app.setAdj, "empty");
14922                        Process.killProcessQuiet(app.pid);
14923                    } else {
14924                        try {
14925                            app.thread.scheduleExit();
14926                        } catch (Exception e) {
14927                            // Ignore exceptions.
14928                        }
14929                    }
14930                    cleanUpApplicationRecordLocked(app, false, true, -1);
14931                    mRemovedProcesses.remove(i);
14932
14933                    if (app.persistent) {
14934                        if (app.persistent) {
14935                            addAppLocked(app.info, false);
14936                        }
14937                    }
14938                }
14939            }
14940
14941            // Now update the oom adj for all processes.
14942            updateOomAdjLocked();
14943        }
14944    }
14945
14946    /** This method sends the specified signal to each of the persistent apps */
14947    public void signalPersistentProcesses(int sig) throws RemoteException {
14948        if (sig != Process.SIGNAL_USR1) {
14949            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14950        }
14951
14952        synchronized (this) {
14953            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14954                    != PackageManager.PERMISSION_GRANTED) {
14955                throw new SecurityException("Requires permission "
14956                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14957            }
14958
14959            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14960                ProcessRecord r = mLruProcesses.get(i);
14961                if (r.thread != null && r.persistent) {
14962                    Process.sendSignal(r.pid, sig);
14963                }
14964            }
14965        }
14966    }
14967
14968    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14969        if (proc == null || proc == mProfileProc) {
14970            proc = mProfileProc;
14971            path = mProfileFile;
14972            profileType = mProfileType;
14973            clearProfilerLocked();
14974        }
14975        if (proc == null) {
14976            return;
14977        }
14978        try {
14979            proc.thread.profilerControl(false, path, null, profileType);
14980        } catch (RemoteException e) {
14981            throw new IllegalStateException("Process disappeared");
14982        }
14983    }
14984
14985    private void clearProfilerLocked() {
14986        if (mProfileFd != null) {
14987            try {
14988                mProfileFd.close();
14989            } catch (IOException e) {
14990            }
14991        }
14992        mProfileApp = null;
14993        mProfileProc = null;
14994        mProfileFile = null;
14995        mProfileType = 0;
14996        mAutoStopProfiler = false;
14997    }
14998
14999    public boolean profileControl(String process, boolean start,
15000            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15001
15002        try {
15003            synchronized (this) {
15004                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15005                // its own permission.
15006                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15007                        != PackageManager.PERMISSION_GRANTED) {
15008                    throw new SecurityException("Requires permission "
15009                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15010                }
15011
15012                if (start && fd == null) {
15013                    throw new IllegalArgumentException("null fd");
15014                }
15015
15016                ProcessRecord proc = null;
15017                if (process != null) {
15018                    try {
15019                        int pid = Integer.parseInt(process);
15020                        synchronized (mPidsSelfLocked) {
15021                            proc = mPidsSelfLocked.get(pid);
15022                        }
15023                    } catch (NumberFormatException e) {
15024                    }
15025
15026                    if (proc == null) {
15027                        HashMap<String, SparseArray<ProcessRecord>> all
15028                                = mProcessNames.getMap();
15029                        SparseArray<ProcessRecord> procs = all.get(process);
15030                        if (procs != null && procs.size() > 0) {
15031                            proc = procs.valueAt(0);
15032                        }
15033                    }
15034                }
15035
15036                if (start && (proc == null || proc.thread == null)) {
15037                    throw new IllegalArgumentException("Unknown process: " + process);
15038                }
15039
15040                if (start) {
15041                    stopProfilerLocked(null, null, 0);
15042                    setProfileApp(proc.info, proc.processName, path, fd, false);
15043                    mProfileProc = proc;
15044                    mProfileType = profileType;
15045                    try {
15046                        fd = fd.dup();
15047                    } catch (IOException e) {
15048                        fd = null;
15049                    }
15050                    proc.thread.profilerControl(start, path, fd, profileType);
15051                    fd = null;
15052                    mProfileFd = null;
15053                } else {
15054                    stopProfilerLocked(proc, path, profileType);
15055                    if (fd != null) {
15056                        try {
15057                            fd.close();
15058                        } catch (IOException e) {
15059                        }
15060                    }
15061                }
15062
15063                return true;
15064            }
15065        } catch (RemoteException e) {
15066            throw new IllegalStateException("Process disappeared");
15067        } finally {
15068            if (fd != null) {
15069                try {
15070                    fd.close();
15071                } catch (IOException e) {
15072                }
15073            }
15074        }
15075    }
15076
15077    public boolean dumpHeap(String process, boolean managed,
15078            String path, ParcelFileDescriptor fd) throws RemoteException {
15079
15080        try {
15081            synchronized (this) {
15082                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15083                // its own permission (same as profileControl).
15084                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15085                        != PackageManager.PERMISSION_GRANTED) {
15086                    throw new SecurityException("Requires permission "
15087                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15088                }
15089
15090                if (fd == null) {
15091                    throw new IllegalArgumentException("null fd");
15092                }
15093
15094                ProcessRecord proc = null;
15095                try {
15096                    int pid = Integer.parseInt(process);
15097                    synchronized (mPidsSelfLocked) {
15098                        proc = mPidsSelfLocked.get(pid);
15099                    }
15100                } catch (NumberFormatException e) {
15101                }
15102
15103                if (proc == null) {
15104                    HashMap<String, SparseArray<ProcessRecord>> all
15105                            = mProcessNames.getMap();
15106                    SparseArray<ProcessRecord> procs = all.get(process);
15107                    if (procs != null && procs.size() > 0) {
15108                        proc = procs.valueAt(0);
15109                    }
15110                }
15111
15112                if (proc == null || proc.thread == null) {
15113                    throw new IllegalArgumentException("Unknown process: " + process);
15114                }
15115
15116                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15117                if (!isDebuggable) {
15118                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15119                        throw new SecurityException("Process not debuggable: " + proc);
15120                    }
15121                }
15122
15123                proc.thread.dumpHeap(managed, path, fd);
15124                fd = null;
15125                return true;
15126            }
15127        } catch (RemoteException e) {
15128            throw new IllegalStateException("Process disappeared");
15129        } finally {
15130            if (fd != null) {
15131                try {
15132                    fd.close();
15133                } catch (IOException e) {
15134                }
15135            }
15136        }
15137    }
15138
15139    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15140    public void monitor() {
15141        synchronized (this) { }
15142    }
15143
15144    void onCoreSettingsChange(Bundle settings) {
15145        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15146            ProcessRecord processRecord = mLruProcesses.get(i);
15147            try {
15148                if (processRecord.thread != null) {
15149                    processRecord.thread.setCoreSettings(settings);
15150                }
15151            } catch (RemoteException re) {
15152                /* ignore */
15153            }
15154        }
15155    }
15156
15157    // Multi-user methods
15158
15159    private int mCurrentUserId;
15160    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
15161
15162    public boolean switchUser(int userId) {
15163        final int callingUid = Binder.getCallingUid();
15164        if (callingUid != 0 && callingUid != Process.myUid()) {
15165            Slog.e(TAG, "Trying to switch user from unauthorized app");
15166            return false;
15167        }
15168        if (mCurrentUserId == userId)
15169            return true;
15170
15171        synchronized (this) {
15172            // Check if user is already logged in, otherwise check if user exists first before
15173            // adding to the list of logged in users.
15174            if (mLoggedInUsers.indexOfKey(userId) < 0) {
15175                if (!userExists(userId)) {
15176                    return false;
15177                }
15178                mLoggedInUsers.append(userId, userId);
15179            }
15180
15181            mCurrentUserId = userId;
15182            boolean haveActivities = mMainStack.switchUser(userId);
15183            if (!haveActivities) {
15184                startHomeActivityLocked(userId);
15185            }
15186
15187        }
15188
15189        // Inform of user switch
15190        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
15191        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
15192        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
15193
15194        return true;
15195    }
15196
15197    @Override
15198    public UserInfo getCurrentUser() throws RemoteException {
15199        final int callingUid = Binder.getCallingUid();
15200        if (callingUid != 0 && callingUid != Process.myUid()) {
15201            Slog.e(TAG, "Trying to get user from unauthorized app");
15202            return null;
15203        }
15204        return AppGlobals.getPackageManager().getUser(mCurrentUserId);
15205    }
15206
15207    private void onUserRemoved(Intent intent) {
15208        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
15209        if (extraUserId < 1) return;
15210
15211        // Kill all the processes for the user
15212        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
15213        synchronized (this) {
15214            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
15215            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
15216                SparseArray<ProcessRecord> uids = uidMap.getValue();
15217                for (int i = 0; i < uids.size(); i++) {
15218                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
15219                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
15220                    }
15221                }
15222            }
15223
15224            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
15225                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
15226                        false, false, true, true, extraUserId);
15227            }
15228        }
15229    }
15230
15231    private boolean userExists(int userId) {
15232        try {
15233            UserInfo user = AppGlobals.getPackageManager().getUser(userId);
15234            return user != null;
15235        } catch (RemoteException re) {
15236            // Won't happen, in same process
15237        }
15238
15239        return false;
15240    }
15241
15242    private void checkValidCaller(int uid, int userId) {
15243        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
15244
15245        throw new SecurityException("Caller uid=" + uid
15246                + " is not privileged to communicate with user=" + userId);
15247    }
15248
15249    private int applyUserId(int uid, int userId) {
15250        return UserId.getUid(userId, uid);
15251    }
15252
15253    private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
15254        if (info == null) return null;
15255        ApplicationInfo newInfo = new ApplicationInfo(info);
15256        newInfo.uid = applyUserId(info.uid, userId);
15257        newInfo.dataDir = USER_DATA_DIR + userId + "/"
15258                + info.packageName;
15259        return newInfo;
15260    }
15261
15262    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
15263        if (aInfo == null
15264                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
15265            return aInfo;
15266        }
15267
15268        ActivityInfo info = new ActivityInfo(aInfo);
15269        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15270        return info;
15271    }
15272
15273    static class ServiceMap {
15274
15275        private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15276                = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15277        private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15278                mServicesByIntentPerUser = new SparseArray<
15279                    HashMap<Intent.FilterComparison, ServiceRecord>>();
15280
15281        ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15282            // TODO: Deal with global services
15283            if (DEBUG_MU)
15284                Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15285            return getServices(callingUser).get(name);
15286        }
15287
15288        ServiceRecord getServiceByName(ComponentName name) {
15289            return getServiceByName(name, -1);
15290        }
15291
15292        ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15293            // TODO: Deal with global services
15294            if (DEBUG_MU)
15295                Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15296            return getServicesByIntent(callingUser).get(filter);
15297        }
15298
15299        ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15300            return getServiceByIntent(filter, -1);
15301        }
15302
15303        void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15304            // TODO: Deal with global services
15305            getServices(callingUser).put(name, value);
15306        }
15307
15308        void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15309                ServiceRecord value) {
15310            // TODO: Deal with global services
15311            getServicesByIntent(callingUser).put(filter, value);
15312        }
15313
15314        void removeServiceByName(ComponentName name, int callingUser) {
15315            // TODO: Deal with global services
15316            ServiceRecord removed = getServices(callingUser).remove(name);
15317            if (DEBUG_MU)
15318                Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15319                        + " removed=" + removed);
15320        }
15321
15322        void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15323            // TODO: Deal with global services
15324            ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15325            if (DEBUG_MU)
15326                Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15327                        + " removed=" + removed);
15328        }
15329
15330        Collection<ServiceRecord> getAllServices(int callingUser) {
15331            // TODO: Deal with global services
15332            return getServices(callingUser).values();
15333        }
15334
15335        private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15336            HashMap map = mServicesByNamePerUser.get(callingUser);
15337            if (map == null) {
15338                map = new HashMap<ComponentName, ServiceRecord>();
15339                mServicesByNamePerUser.put(callingUser, map);
15340            }
15341            return map;
15342        }
15343
15344        private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15345                int callingUser) {
15346            HashMap map = mServicesByIntentPerUser.get(callingUser);
15347            if (map == null) {
15348                map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15349                mServicesByIntentPerUser.put(callingUser, map);
15350            }
15351            return map;
15352        }
15353    }
15354}
15355