ActivityManagerService.java revision 59325eb31f25704bb88c348160bb69e7c1aa3b48
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.IIntentReceiver;
66import android.content.IIntentSender;
67import android.content.Intent;
68import android.content.IntentFilter;
69import android.content.IntentSender;
70import android.content.pm.ActivityInfo;
71import android.content.pm.ApplicationInfo;
72import android.content.pm.ConfigurationInfo;
73import android.content.pm.IPackageDataObserver;
74import android.content.pm.IPackageManager;
75import android.content.pm.InstrumentationInfo;
76import android.content.pm.PackageInfo;
77import android.content.pm.PackageManager;
78import android.content.pm.PackageManager.NameNotFoundException;
79import android.content.pm.PathPermission;
80import android.content.pm.ProviderInfo;
81import android.content.pm.ResolveInfo;
82import android.content.pm.ServiceInfo;
83import android.content.pm.UserInfo;
84import android.content.res.CompatibilityInfo;
85import android.content.res.Configuration;
86import android.graphics.Bitmap;
87import android.net.Proxy;
88import android.net.ProxyProperties;
89import android.net.Uri;
90import android.os.Binder;
91import android.os.Build;
92import android.os.Bundle;
93import android.os.Debug;
94import android.os.DropBoxManager;
95import android.os.Environment;
96import android.os.FileObserver;
97import android.os.FileUtils;
98import android.os.Handler;
99import android.os.IBinder;
100import android.os.IPermissionController;
101import android.os.Looper;
102import android.os.Message;
103import android.os.Parcel;
104import android.os.ParcelFileDescriptor;
105import android.os.Process;
106import android.os.RemoteCallbackList;
107import android.os.RemoteException;
108import android.os.ServiceManager;
109import android.os.StrictMode;
110import android.os.SystemClock;
111import android.os.SystemProperties;
112import android.os.UserId;
113import android.provider.Settings;
114import android.text.format.Time;
115import android.util.EventLog;
116import android.util.Log;
117import android.util.Pair;
118import android.util.PrintWriterPrinter;
119import android.util.Slog;
120import android.util.SparseArray;
121import android.util.SparseIntArray;
122import android.util.TimeUtils;
123import android.view.Gravity;
124import android.view.LayoutInflater;
125import android.view.View;
126import android.view.WindowManager;
127import android.view.WindowManagerPolicy;
128
129import java.io.BufferedInputStream;
130import java.io.BufferedOutputStream;
131import java.io.BufferedReader;
132import java.io.DataInputStream;
133import java.io.DataOutputStream;
134import java.io.File;
135import java.io.FileDescriptor;
136import java.io.FileInputStream;
137import java.io.FileNotFoundException;
138import java.io.FileOutputStream;
139import java.io.IOException;
140import java.io.InputStreamReader;
141import java.io.PrintWriter;
142import java.io.StringWriter;
143import java.lang.ref.WeakReference;
144import java.util.ArrayList;
145import java.util.Collection;
146import java.util.Collections;
147import java.util.Comparator;
148import java.util.HashMap;
149import java.util.HashSet;
150import java.util.Iterator;
151import java.util.List;
152import java.util.Locale;
153import java.util.Map;
154import java.util.Map.Entry;
155import java.util.Set;
156import java.util.concurrent.atomic.AtomicBoolean;
157import java.util.concurrent.atomic.AtomicLong;
158
159public final class ActivityManagerService extends ActivityManagerNative
160        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
161    private static final String USER_DATA_DIR = "/data/user/";
162    static final String TAG = "ActivityManager";
163    static final String TAG_MU = "ActivityManagerServiceMU";
164    static final boolean DEBUG = false;
165    static final boolean localLOGV = DEBUG;
166    static final boolean DEBUG_SWITCH = localLOGV || false;
167    static final boolean DEBUG_TASKS = localLOGV || false;
168    static final boolean DEBUG_PAUSE = localLOGV || false;
169    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
170    static final boolean DEBUG_TRANSITION = localLOGV || false;
171    static final boolean DEBUG_BROADCAST = localLOGV || false;
172    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
173    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_SERVICE = localLOGV || false;
175    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
176    static final boolean DEBUG_VISBILITY = localLOGV || false;
177    static final boolean DEBUG_PROCESSES = localLOGV || false;
178    static final boolean DEBUG_PROVIDER = localLOGV || false;
179    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
180    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
181    static final boolean DEBUG_RESULTS = localLOGV || false;
182    static final boolean DEBUG_BACKUP = localLOGV || false;
183    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
184    static final boolean DEBUG_POWER = localLOGV || false;
185    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
186    static final boolean DEBUG_MU = localLOGV || false;
187    static final boolean VALIDATE_TOKENS = false;
188    static final boolean SHOW_ACTIVITY_START_TIME = true;
189
190    // Control over CPU and battery monitoring.
191    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
192    static final boolean MONITOR_CPU_USAGE = true;
193    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
194    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
195    static final boolean MONITOR_THREAD_CPU_USAGE = false;
196
197    // The flags that are set for all calls we make to the package manager.
198    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
199
200    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
201
202    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
203
204    // Maximum number of recent tasks that we can remember.
205    static final int MAX_RECENT_TASKS = 20;
206
207    // Amount of time after a call to stopAppSwitches() during which we will
208    // prevent further untrusted switches from happening.
209    static final long APP_SWITCH_DELAY_TIME = 5*1000;
210
211    // How long we wait for a launched process to attach to the activity manager
212    // before we decide it's never going to come up for real.
213    static final int PROC_START_TIMEOUT = 10*1000;
214
215    // How long we wait for a launched process to attach to the activity manager
216    // before we decide it's never going to come up for real, when the process was
217    // started with a wrapper for instrumentation (such as Valgrind) because it
218    // could take much longer than usual.
219    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
220
221    // How long to wait after going idle before forcing apps to GC.
222    static final int GC_TIMEOUT = 5*1000;
223
224    // The minimum amount of time between successive GC requests for a process.
225    static final int GC_MIN_INTERVAL = 60*1000;
226
227    // The rate at which we check for apps using excessive power -- 15 mins.
228    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
229
230    // The minimum sample duration we will allow before deciding we have
231    // enough data on wake locks to start killing things.
232    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
233
234    // The minimum sample duration we will allow before deciding we have
235    // enough data on CPU usage to start killing things.
236    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
237
238    // How long we allow a receiver to run before giving up on it.
239    static final int BROADCAST_FG_TIMEOUT = 10*1000;
240    static final int BROADCAST_BG_TIMEOUT = 60*1000;
241
242    // How long we wait for a service to finish executing.
243    static final int SERVICE_TIMEOUT = 20*1000;
244
245    // How long a service needs to be running until restarting its process
246    // is no longer considered to be a relaunch of the service.
247    static final int SERVICE_RESTART_DURATION = 5*1000;
248
249    // How long a service needs to be running until it will start back at
250    // SERVICE_RESTART_DURATION after being killed.
251    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
252
253    // Multiplying factor to increase restart duration time by, for each time
254    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
255    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
256
257    // The minimum amount of time between restarting services that we allow.
258    // That is, when multiple services are restarting, we won't allow each
259    // to restart less than this amount of time from the last one.
260    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
261
262    // Maximum amount of time for there to be no activity on a service before
263    // we consider it non-essential and allow its process to go on the
264    // LRU background list.
265    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
266
267    // How long we wait until we timeout on key dispatching.
268    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
269
270    // How long we wait until we timeout on key dispatching during instrumentation.
271    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
272
273    static final int MY_PID = Process.myPid();
274
275    static final String[] EMPTY_STRING_ARRAY = new String[0];
276
277    public ActivityStack mMainStack;
278
279    private final boolean mHeadless;
280
281    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
282    // default actuion automatically.  Important for devices without direct input
283    // devices.
284    private boolean mShowDialogs = true;
285
286    /**
287     * Description of a request to start a new activity, which has been held
288     * due to app switches being disabled.
289     */
290    static class PendingActivityLaunch {
291        ActivityRecord r;
292        ActivityRecord sourceRecord;
293        int startFlags;
294    }
295
296    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
297            = new ArrayList<PendingActivityLaunch>();
298
299
300    BroadcastQueue mFgBroadcastQueue;
301    BroadcastQueue mBgBroadcastQueue;
302    // Convenient for easy iteration over the queues. Foreground is first
303    // so that dispatch of foreground broadcasts gets precedence.
304    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
305
306    BroadcastQueue broadcastQueueForIntent(Intent intent) {
307        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
308        if (DEBUG_BACKGROUND_BROADCAST) {
309            Slog.i(TAG, "Broadcast intent " + intent + " on "
310                    + (isFg ? "foreground" : "background")
311                    + " queue");
312        }
313        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
314    }
315
316    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
317        for (BroadcastQueue queue : mBroadcastQueues) {
318            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
319            if (r != null) {
320                return r;
321            }
322        }
323        return null;
324    }
325
326    /**
327     * Activity we have told the window manager to have key focus.
328     */
329    ActivityRecord mFocusedActivity = null;
330    /**
331     * List of intents that were used to start the most recent tasks.
332     */
333    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
334
335    /**
336     * Process management.
337     */
338    final ProcessList mProcessList = new ProcessList();
339
340    /**
341     * All of the applications we currently have running organized by name.
342     * The keys are strings of the application package name (as
343     * returned by the package manager), and the keys are ApplicationRecord
344     * objects.
345     */
346    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
347
348    /**
349     * The currently running isolated processes.
350     */
351    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
352
353    /**
354     * Counter for assigning isolated process uids, to avoid frequently reusing the
355     * same ones.
356     */
357    int mNextIsolatedProcessUid = 0;
358
359    /**
360     * The currently running heavy-weight process, if any.
361     */
362    ProcessRecord mHeavyWeightProcess = null;
363
364    /**
365     * The last time that various processes have crashed.
366     */
367    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
368
369    /**
370     * Set of applications that we consider to be bad, and will reject
371     * incoming broadcasts from (which the user has no control over).
372     * Processes are added to this set when they have crashed twice within
373     * a minimum amount of time; they are removed from it when they are
374     * later restarted (hopefully due to some user action).  The value is the
375     * time it was added to the list.
376     */
377    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
378
379    /**
380     * All of the processes we currently have running organized by pid.
381     * The keys are the pid running the application.
382     *
383     * <p>NOTE: This object is protected by its own lock, NOT the global
384     * activity manager lock!
385     */
386    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
387
388    /**
389     * All of the processes that have been forced to be foreground.  The key
390     * is the pid of the caller who requested it (we hold a death
391     * link on it).
392     */
393    abstract class ForegroundToken implements IBinder.DeathRecipient {
394        int pid;
395        IBinder token;
396    }
397    final SparseArray<ForegroundToken> mForegroundProcesses
398            = new SparseArray<ForegroundToken>();
399
400    /**
401     * List of records for processes that someone had tried to start before the
402     * system was ready.  We don't start them at that point, but ensure they
403     * are started by the time booting is complete.
404     */
405    final ArrayList<ProcessRecord> mProcessesOnHold
406            = new ArrayList<ProcessRecord>();
407
408    /**
409     * List of persistent applications that are in the process
410     * of being started.
411     */
412    final ArrayList<ProcessRecord> mPersistentStartingProcesses
413            = new ArrayList<ProcessRecord>();
414
415    /**
416     * Processes that are being forcibly torn down.
417     */
418    final ArrayList<ProcessRecord> mRemovedProcesses
419            = new ArrayList<ProcessRecord>();
420
421    /**
422     * List of running applications, sorted by recent usage.
423     * The first entry in the list is the least recently used.
424     * It contains ApplicationRecord objects.  This list does NOT include
425     * any persistent application records (since we never want to exit them).
426     */
427    final ArrayList<ProcessRecord> mLruProcesses
428            = new ArrayList<ProcessRecord>();
429
430    /**
431     * List of processes that should gc as soon as things are idle.
432     */
433    final ArrayList<ProcessRecord> mProcessesToGc
434            = new ArrayList<ProcessRecord>();
435
436    /**
437     * This is the process holding what we currently consider to be
438     * the "home" activity.
439     */
440    ProcessRecord mHomeProcess;
441
442    /**
443     * This is the process holding the activity the user last visited that
444     * is in a different process from the one they are currently in.
445     */
446    ProcessRecord mPreviousProcess;
447
448    /**
449     * The time at which the previous process was last visible.
450     */
451    long mPreviousProcessVisibleTime;
452
453    /**
454     * Packages that the user has asked to have run in screen size
455     * compatibility mode instead of filling the screen.
456     */
457    final CompatModePackages mCompatModePackages;
458
459    /**
460     * Set of PendingResultRecord objects that are currently active.
461     */
462    final HashSet mPendingResultRecords = new HashSet();
463
464    /**
465     * Set of IntentSenderRecord objects that are currently active.
466     */
467    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
468            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
469
470    /**
471     * Fingerprints (hashCode()) of stack traces that we've
472     * already logged DropBox entries for.  Guarded by itself.  If
473     * something (rogue user app) forces this over
474     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
475     */
476    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
477    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
478
479    /**
480     * Strict Mode background batched logging state.
481     *
482     * The string buffer is guarded by itself, and its lock is also
483     * used to determine if another batched write is already
484     * in-flight.
485     */
486    private final StringBuilder mStrictModeBuffer = new StringBuilder();
487
488    /**
489     * Keeps track of all IIntentReceivers that have been registered for
490     * broadcasts.  Hash keys are the receiver IBinder, hash value is
491     * a ReceiverList.
492     */
493    final HashMap mRegisteredReceivers = new HashMap();
494
495    /**
496     * Resolver for broadcast intents to registered receivers.
497     * Holds BroadcastFilter (subclass of IntentFilter).
498     */
499    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
500            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
501        @Override
502        protected boolean allowFilterResult(
503                BroadcastFilter filter, List<BroadcastFilter> dest) {
504            IBinder target = filter.receiverList.receiver.asBinder();
505            for (int i=dest.size()-1; i>=0; i--) {
506                if (dest.get(i).receiverList.receiver.asBinder() == target) {
507                    return false;
508                }
509            }
510            return true;
511        }
512
513        @Override
514        protected String packageForFilter(BroadcastFilter filter) {
515            return filter.packageName;
516        }
517    };
518
519    /**
520     * State of all active sticky broadcasts.  Keys are the action of the
521     * sticky Intent, values are an ArrayList of all broadcasted intents with
522     * that action (which should usually be one).
523     */
524    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
525            new HashMap<String, ArrayList<Intent>>();
526
527    final ServiceMap mServiceMap = new ServiceMap();
528
529    /**
530     * All currently bound service connections.  Keys are the IBinder of
531     * the client's IServiceConnection.
532     */
533    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
534            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
535
536    /**
537     * List of services that we have been asked to start,
538     * but haven't yet been able to.  It is used to hold start requests
539     * while waiting for their corresponding application thread to get
540     * going.
541     */
542    final ArrayList<ServiceRecord> mPendingServices
543            = new ArrayList<ServiceRecord>();
544
545    /**
546     * List of services that are scheduled to restart following a crash.
547     */
548    final ArrayList<ServiceRecord> mRestartingServices
549            = new ArrayList<ServiceRecord>();
550
551    /**
552     * List of services that are in the process of being stopped.
553     */
554    final ArrayList<ServiceRecord> mStoppingServices
555            = new ArrayList<ServiceRecord>();
556
557    /**
558     * Backup/restore process management
559     */
560    String mBackupAppName = null;
561    BackupRecord mBackupTarget = null;
562
563    /**
564     * List of PendingThumbnailsRecord objects of clients who are still
565     * waiting to receive all of the thumbnails for a task.
566     */
567    final ArrayList mPendingThumbnails = new ArrayList();
568
569    /**
570     * List of HistoryRecord objects that have been finished and must
571     * still report back to a pending thumbnail receiver.
572     */
573    final ArrayList mCancelledThumbnails = new ArrayList();
574
575    final ProviderMap mProviderMap = new ProviderMap();
576
577    /**
578     * List of content providers who have clients waiting for them.  The
579     * application is currently being launched and the provider will be
580     * removed from this list once it is published.
581     */
582    final ArrayList<ContentProviderRecord> mLaunchingProviders
583            = new ArrayList<ContentProviderRecord>();
584
585    /**
586     * Global set of specific Uri permissions that have been granted.
587     */
588    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
589            = new SparseArray<HashMap<Uri, UriPermission>>();
590
591    CoreSettingsObserver mCoreSettingsObserver;
592
593    /**
594     * Thread-local storage used to carry caller permissions over through
595     * indirect content-provider access.
596     * @see #ActivityManagerService.openContentUri()
597     */
598    private class Identity {
599        public int pid;
600        public int uid;
601
602        Identity(int _pid, int _uid) {
603            pid = _pid;
604            uid = _uid;
605        }
606    }
607
608    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
609
610    /**
611     * All information we have collected about the runtime performance of
612     * any user id that can impact battery performance.
613     */
614    final BatteryStatsService mBatteryStatsService;
615
616    /**
617     * information about component usage
618     */
619    final UsageStatsService mUsageStatsService;
620
621    /**
622     * Current configuration information.  HistoryRecord objects are given
623     * a reference to this object to indicate which configuration they are
624     * currently running in, so this object must be kept immutable.
625     */
626    Configuration mConfiguration = new Configuration();
627
628    /**
629     * Current sequencing integer of the configuration, for skipping old
630     * configurations.
631     */
632    int mConfigurationSeq = 0;
633
634    /**
635     * Hardware-reported OpenGLES version.
636     */
637    final int GL_ES_VERSION;
638
639    /**
640     * List of initialization arguments to pass to all processes when binding applications to them.
641     * For example, references to the commonly used services.
642     */
643    HashMap<String, IBinder> mAppBindArgs;
644
645    /**
646     * Temporary to avoid allocations.  Protected by main lock.
647     */
648    final StringBuilder mStringBuilder = new StringBuilder(256);
649
650    /**
651     * Used to control how we initialize the service.
652     */
653    boolean mStartRunning = false;
654    ComponentName mTopComponent;
655    String mTopAction;
656    String mTopData;
657    boolean mProcessesReady = false;
658    boolean mSystemReady = false;
659    boolean mBooting = false;
660    boolean mWaitingUpdate = false;
661    boolean mDidUpdate = false;
662    boolean mOnBattery = false;
663    boolean mLaunchWarningShown = false;
664
665    Context mContext;
666
667    int mFactoryTest;
668
669    boolean mCheckedForSetup;
670
671    /**
672     * The time at which we will allow normal application switches again,
673     * after a call to {@link #stopAppSwitches()}.
674     */
675    long mAppSwitchesAllowedTime;
676
677    /**
678     * This is set to true after the first switch after mAppSwitchesAllowedTime
679     * is set; any switches after that will clear the time.
680     */
681    boolean mDidAppSwitch;
682
683    /**
684     * Last time (in realtime) at which we checked for power usage.
685     */
686    long mLastPowerCheckRealtime;
687
688    /**
689     * Last time (in uptime) at which we checked for power usage.
690     */
691    long mLastPowerCheckUptime;
692
693    /**
694     * Set while we are wanting to sleep, to prevent any
695     * activities from being started/resumed.
696     */
697    boolean mSleeping = false;
698
699    /**
700     * State of external calls telling us if the device is asleep.
701     */
702    boolean mWentToSleep = false;
703
704    /**
705     * State of external call telling us if the lock screen is shown.
706     */
707    boolean mLockScreenShown = false;
708
709    /**
710     * Set if we are shutting down the system, similar to sleeping.
711     */
712    boolean mShuttingDown = false;
713
714    /**
715     * Task identifier that activities are currently being started
716     * in.  Incremented each time a new task is created.
717     * todo: Replace this with a TokenSpace class that generates non-repeating
718     * integers that won't wrap.
719     */
720    int mCurTask = 1;
721
722    /**
723     * Current sequence id for oom_adj computation traversal.
724     */
725    int mAdjSeq = 0;
726
727    /**
728     * Current sequence id for process LRU updating.
729     */
730    int mLruSeq = 0;
731
732    /**
733     * Keep track of the number of service processes we last found, to
734     * determine on the next iteration which should be B services.
735     */
736    int mNumServiceProcs = 0;
737    int mNewNumServiceProcs = 0;
738
739    /**
740     * System monitoring: number of processes that died since the last
741     * N procs were started.
742     */
743    int[] mProcDeaths = new int[20];
744
745    /**
746     * This is set if we had to do a delayed dexopt of an app before launching
747     * it, to increasing the ANR timeouts in that case.
748     */
749    boolean mDidDexOpt;
750
751    String mDebugApp = null;
752    boolean mWaitForDebugger = false;
753    boolean mDebugTransient = false;
754    String mOrigDebugApp = null;
755    boolean mOrigWaitForDebugger = false;
756    boolean mAlwaysFinishActivities = false;
757    IActivityController mController = null;
758    String mProfileApp = null;
759    ProcessRecord mProfileProc = null;
760    String mProfileFile;
761    ParcelFileDescriptor mProfileFd;
762    int mProfileType = 0;
763    boolean mAutoStopProfiler = false;
764    String mOpenGlTraceApp = null;
765
766    final RemoteCallbackList<IProcessObserver> mProcessObservers
767            = new RemoteCallbackList<IProcessObserver>();
768
769    /**
770     * Callback of last caller to {@link #requestPss}.
771     */
772    Runnable mRequestPssCallback;
773
774    /**
775     * Remaining processes for which we are waiting results from the last
776     * call to {@link #requestPss}.
777     */
778    final ArrayList<ProcessRecord> mRequestPssList
779            = new ArrayList<ProcessRecord>();
780
781    /**
782     * Runtime statistics collection thread.  This object's lock is used to
783     * protect all related state.
784     */
785    final Thread mProcessStatsThread;
786
787    /**
788     * Used to collect process stats when showing not responding dialog.
789     * Protected by mProcessStatsThread.
790     */
791    final ProcessStats mProcessStats = new ProcessStats(
792            MONITOR_THREAD_CPU_USAGE);
793    final AtomicLong mLastCpuTime = new AtomicLong(0);
794    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
795
796    long mLastWriteTime = 0;
797
798    /**
799     * Set to true after the system has finished booting.
800     */
801    boolean mBooted = false;
802
803    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
804    int mProcessLimitOverride = -1;
805
806    WindowManagerService mWindowManager;
807
808    static ActivityManagerService mSelf;
809    static ActivityThread mSystemThread;
810
811    private final class AppDeathRecipient implements IBinder.DeathRecipient {
812        final ProcessRecord mApp;
813        final int mPid;
814        final IApplicationThread mAppThread;
815
816        AppDeathRecipient(ProcessRecord app, int pid,
817                IApplicationThread thread) {
818            if (localLOGV) Slog.v(
819                TAG, "New death recipient " + this
820                + " for thread " + thread.asBinder());
821            mApp = app;
822            mPid = pid;
823            mAppThread = thread;
824        }
825
826        public void binderDied() {
827            if (localLOGV) Slog.v(
828                TAG, "Death received in " + this
829                + " for thread " + mAppThread.asBinder());
830            synchronized(ActivityManagerService.this) {
831                appDiedLocked(mApp, mPid, mAppThread);
832            }
833        }
834    }
835
836    static final int SHOW_ERROR_MSG = 1;
837    static final int SHOW_NOT_RESPONDING_MSG = 2;
838    static final int SHOW_FACTORY_ERROR_MSG = 3;
839    static final int UPDATE_CONFIGURATION_MSG = 4;
840    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
841    static final int WAIT_FOR_DEBUGGER_MSG = 6;
842    static final int SERVICE_TIMEOUT_MSG = 12;
843    static final int UPDATE_TIME_ZONE = 13;
844    static final int SHOW_UID_ERROR_MSG = 14;
845    static final int IM_FEELING_LUCKY_MSG = 15;
846    static final int PROC_START_TIMEOUT_MSG = 20;
847    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
848    static final int KILL_APPLICATION_MSG = 22;
849    static final int FINALIZE_PENDING_INTENT_MSG = 23;
850    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
851    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
852    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
853    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
854    static final int CLEAR_DNS_CACHE = 28;
855    static final int UPDATE_HTTP_PROXY = 29;
856    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
857    static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
858    static final int DISPATCH_PROCESS_DIED = 32;
859    static final int REPORT_MEM_USAGE = 33;
860
861    static final int FIRST_ACTIVITY_STACK_MSG = 100;
862    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
863    static final int FIRST_COMPAT_MODE_MSG = 300;
864
865    AlertDialog mUidAlert;
866    CompatModeDialog mCompatModeDialog;
867    long mLastMemUsageReportTime = 0;
868
869    final Handler mHandler = new Handler() {
870        //public Handler() {
871        //    if (localLOGV) Slog.v(TAG, "Handler started!");
872        //}
873
874        public void handleMessage(Message msg) {
875            switch (msg.what) {
876            case SHOW_ERROR_MSG: {
877                HashMap data = (HashMap) msg.obj;
878                synchronized (ActivityManagerService.this) {
879                    ProcessRecord proc = (ProcessRecord)data.get("app");
880                    if (proc != null && proc.crashDialog != null) {
881                        Slog.e(TAG, "App already has crash dialog: " + proc);
882                        return;
883                    }
884                    AppErrorResult res = (AppErrorResult) data.get("result");
885                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
886                        Dialog d = new AppErrorDialog(mContext, res, proc);
887                        d.show();
888                        proc.crashDialog = d;
889                    } else {
890                        // The device is asleep, so just pretend that the user
891                        // saw a crash dialog and hit "force quit".
892                        res.set(0);
893                    }
894                }
895
896                ensureBootCompleted();
897            } break;
898            case SHOW_NOT_RESPONDING_MSG: {
899                synchronized (ActivityManagerService.this) {
900                    HashMap data = (HashMap) msg.obj;
901                    ProcessRecord proc = (ProcessRecord)data.get("app");
902                    if (proc != null && proc.anrDialog != null) {
903                        Slog.e(TAG, "App already has anr dialog: " + proc);
904                        return;
905                    }
906
907                    Intent intent = new Intent("android.intent.action.ANR");
908                    if (!mProcessesReady) {
909                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
910                                | Intent.FLAG_RECEIVER_FOREGROUND);
911                    }
912                    broadcastIntentLocked(null, null, intent,
913                            null, null, 0, null, null, null,
914                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
915
916                    if (mShowDialogs) {
917                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
918                                mContext, proc, (ActivityRecord)data.get("activity"));
919                        d.show();
920                        proc.anrDialog = d;
921                    } else {
922                        // Just kill the app if there is no dialog to be shown.
923                        killAppAtUsersRequest(proc, null);
924                    }
925                }
926
927                ensureBootCompleted();
928            } break;
929            case SHOW_STRICT_MODE_VIOLATION_MSG: {
930                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
931                synchronized (ActivityManagerService.this) {
932                    ProcessRecord proc = (ProcessRecord) data.get("app");
933                    if (proc == null) {
934                        Slog.e(TAG, "App not found when showing strict mode dialog.");
935                        break;
936                    }
937                    if (proc.crashDialog != null) {
938                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
939                        return;
940                    }
941                    AppErrorResult res = (AppErrorResult) data.get("result");
942                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
943                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
944                        d.show();
945                        proc.crashDialog = d;
946                    } else {
947                        // The device is asleep, so just pretend that the user
948                        // saw a crash dialog and hit "force quit".
949                        res.set(0);
950                    }
951                }
952                ensureBootCompleted();
953            } break;
954            case SHOW_FACTORY_ERROR_MSG: {
955                Dialog d = new FactoryErrorDialog(
956                    mContext, msg.getData().getCharSequence("msg"));
957                d.show();
958                ensureBootCompleted();
959            } break;
960            case UPDATE_CONFIGURATION_MSG: {
961                final ContentResolver resolver = mContext.getContentResolver();
962                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
963            } break;
964            case GC_BACKGROUND_PROCESSES_MSG: {
965                synchronized (ActivityManagerService.this) {
966                    performAppGcsIfAppropriateLocked();
967                }
968            } break;
969            case WAIT_FOR_DEBUGGER_MSG: {
970                synchronized (ActivityManagerService.this) {
971                    ProcessRecord app = (ProcessRecord)msg.obj;
972                    if (msg.arg1 != 0) {
973                        if (!app.waitedForDebugger) {
974                            Dialog d = new AppWaitingForDebuggerDialog(
975                                    ActivityManagerService.this,
976                                    mContext, app);
977                            app.waitDialog = d;
978                            app.waitedForDebugger = true;
979                            d.show();
980                        }
981                    } else {
982                        if (app.waitDialog != null) {
983                            app.waitDialog.dismiss();
984                            app.waitDialog = null;
985                        }
986                    }
987                }
988            } break;
989            case SERVICE_TIMEOUT_MSG: {
990                if (mDidDexOpt) {
991                    mDidDexOpt = false;
992                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
993                    nmsg.obj = msg.obj;
994                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
995                    return;
996                }
997                serviceTimeout((ProcessRecord)msg.obj);
998            } break;
999            case UPDATE_TIME_ZONE: {
1000                synchronized (ActivityManagerService.this) {
1001                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002                        ProcessRecord r = mLruProcesses.get(i);
1003                        if (r.thread != null) {
1004                            try {
1005                                r.thread.updateTimeZone();
1006                            } catch (RemoteException ex) {
1007                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1008                            }
1009                        }
1010                    }
1011                }
1012            } break;
1013            case CLEAR_DNS_CACHE: {
1014                synchronized (ActivityManagerService.this) {
1015                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1016                        ProcessRecord r = mLruProcesses.get(i);
1017                        if (r.thread != null) {
1018                            try {
1019                                r.thread.clearDnsCache();
1020                            } catch (RemoteException ex) {
1021                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1022                            }
1023                        }
1024                    }
1025                }
1026            } break;
1027            case UPDATE_HTTP_PROXY: {
1028                ProxyProperties proxy = (ProxyProperties)msg.obj;
1029                String host = "";
1030                String port = "";
1031                String exclList = "";
1032                if (proxy != null) {
1033                    host = proxy.getHost();
1034                    port = Integer.toString(proxy.getPort());
1035                    exclList = proxy.getExclusionList();
1036                }
1037                synchronized (ActivityManagerService.this) {
1038                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1039                        ProcessRecord r = mLruProcesses.get(i);
1040                        if (r.thread != null) {
1041                            try {
1042                                r.thread.setHttpProxy(host, port, exclList);
1043                            } catch (RemoteException ex) {
1044                                Slog.w(TAG, "Failed to update http proxy for: " +
1045                                        r.info.processName);
1046                            }
1047                        }
1048                    }
1049                }
1050            } break;
1051            case SHOW_UID_ERROR_MSG: {
1052                String title = "System UIDs Inconsistent";
1053                String text = "UIDs on the system are inconsistent, you need to wipe your"
1054                        + " data partition or your device will be unstable.";
1055                Log.e(TAG, title + ": " + text);
1056                if (mShowDialogs) {
1057                    // XXX This is a temporary dialog, no need to localize.
1058                    AlertDialog d = new BaseErrorDialog(mContext);
1059                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1060                    d.setCancelable(false);
1061                    d.setTitle(title);
1062                    d.setMessage(text);
1063                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1064                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1065                    mUidAlert = d;
1066                    d.show();
1067                }
1068            } break;
1069            case IM_FEELING_LUCKY_MSG: {
1070                if (mUidAlert != null) {
1071                    mUidAlert.dismiss();
1072                    mUidAlert = null;
1073                }
1074            } break;
1075            case PROC_START_TIMEOUT_MSG: {
1076                if (mDidDexOpt) {
1077                    mDidDexOpt = false;
1078                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1079                    nmsg.obj = msg.obj;
1080                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1081                    return;
1082                }
1083                ProcessRecord app = (ProcessRecord)msg.obj;
1084                synchronized (ActivityManagerService.this) {
1085                    processStartTimedOutLocked(app);
1086                }
1087            } break;
1088            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1089                synchronized (ActivityManagerService.this) {
1090                    doPendingActivityLaunchesLocked(true);
1091                }
1092            } break;
1093            case KILL_APPLICATION_MSG: {
1094                synchronized (ActivityManagerService.this) {
1095                    int uid = msg.arg1;
1096                    boolean restart = (msg.arg2 == 1);
1097                    String pkg = (String) msg.obj;
1098                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1099                            UserId.getUserId(uid));
1100                }
1101            } break;
1102            case FINALIZE_PENDING_INTENT_MSG: {
1103                ((PendingIntentRecord)msg.obj).completeFinalize();
1104            } break;
1105            case POST_HEAVY_NOTIFICATION_MSG: {
1106                INotificationManager inm = NotificationManager.getService();
1107                if (inm == null) {
1108                    return;
1109                }
1110
1111                ActivityRecord root = (ActivityRecord)msg.obj;
1112                ProcessRecord process = root.app;
1113                if (process == null) {
1114                    return;
1115                }
1116
1117                try {
1118                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1119                    String text = mContext.getString(R.string.heavy_weight_notification,
1120                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1121                    Notification notification = new Notification();
1122                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1123                    notification.when = 0;
1124                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1125                    notification.tickerText = text;
1126                    notification.defaults = 0; // please be quiet
1127                    notification.sound = null;
1128                    notification.vibrate = null;
1129                    notification.setLatestEventInfo(context, text,
1130                            mContext.getText(R.string.heavy_weight_notification_detail),
1131                            PendingIntent.getActivity(mContext, 0, root.intent,
1132                                    PendingIntent.FLAG_CANCEL_CURRENT));
1133
1134                    try {
1135                        int[] outId = new int[1];
1136                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1137                                notification, outId);
1138                    } catch (RuntimeException e) {
1139                        Slog.w(ActivityManagerService.TAG,
1140                                "Error showing notification for heavy-weight app", e);
1141                    } catch (RemoteException e) {
1142                    }
1143                } catch (NameNotFoundException e) {
1144                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1145                }
1146            } break;
1147            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1148                INotificationManager inm = NotificationManager.getService();
1149                if (inm == null) {
1150                    return;
1151                }
1152                try {
1153                    inm.cancelNotification("android",
1154                            R.string.heavy_weight_notification);
1155                } catch (RuntimeException e) {
1156                    Slog.w(ActivityManagerService.TAG,
1157                            "Error canceling notification for service", e);
1158                } catch (RemoteException e) {
1159                }
1160            } break;
1161            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1162                synchronized (ActivityManagerService.this) {
1163                    checkExcessivePowerUsageLocked(true);
1164                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1165                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1166                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1167                }
1168            } break;
1169            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1170                synchronized (ActivityManagerService.this) {
1171                    ActivityRecord ar = (ActivityRecord)msg.obj;
1172                    if (mCompatModeDialog != null) {
1173                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1174                                ar.info.applicationInfo.packageName)) {
1175                            return;
1176                        }
1177                        mCompatModeDialog.dismiss();
1178                        mCompatModeDialog = null;
1179                    }
1180                    if (ar != null && false) {
1181                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1182                                ar.packageName)) {
1183                            int mode = mCompatModePackages.computeCompatModeLocked(
1184                                    ar.info.applicationInfo);
1185                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1186                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1187                                mCompatModeDialog = new CompatModeDialog(
1188                                        ActivityManagerService.this, mContext,
1189                                        ar.info.applicationInfo);
1190                                mCompatModeDialog.show();
1191                            }
1192                        }
1193                    }
1194                }
1195                break;
1196            }
1197            case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
1198                final int pid = msg.arg1;
1199                final int uid = msg.arg2;
1200                final boolean foregroundActivities = (Boolean) msg.obj;
1201                dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
1202                break;
1203            }
1204            case DISPATCH_PROCESS_DIED: {
1205                final int pid = msg.arg1;
1206                final int uid = msg.arg2;
1207                dispatchProcessDied(pid, uid);
1208                break;
1209            }
1210            case REPORT_MEM_USAGE: {
1211                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1212                if (!isDebuggable) {
1213                    return;
1214                }
1215                synchronized (ActivityManagerService.this) {
1216                    long now = SystemClock.uptimeMillis();
1217                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1218                        // Don't report more than every 5 minutes to somewhat
1219                        // avoid spamming.
1220                        return;
1221                    }
1222                    mLastMemUsageReportTime = now;
1223                }
1224                Thread thread = new Thread() {
1225                    @Override public void run() {
1226                        StringBuilder dropBuilder = new StringBuilder(1024);
1227                        StringBuilder logBuilder = new StringBuilder(1024);
1228                        StringWriter oomSw = new StringWriter();
1229                        PrintWriter oomPw = new PrintWriter(oomSw);
1230                        StringWriter catSw = new StringWriter();
1231                        PrintWriter catPw = new PrintWriter(catSw);
1232                        String[] emptyArgs = new String[] { };
1233                        StringBuilder tag = new StringBuilder(128);
1234                        StringBuilder stack = new StringBuilder(128);
1235                        tag.append("Low on memory -- ");
1236                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1237                                tag, stack);
1238                        dropBuilder.append(stack);
1239                        dropBuilder.append('\n');
1240                        dropBuilder.append('\n');
1241                        String oomString = oomSw.toString();
1242                        dropBuilder.append(oomString);
1243                        dropBuilder.append('\n');
1244                        logBuilder.append(oomString);
1245                        try {
1246                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1247                                    "procrank", });
1248                            final InputStreamReader converter = new InputStreamReader(
1249                                    proc.getInputStream());
1250                            BufferedReader in = new BufferedReader(converter);
1251                            String line;
1252                            while (true) {
1253                                line = in.readLine();
1254                                if (line == null) {
1255                                    break;
1256                                }
1257                                if (line.length() > 0) {
1258                                    logBuilder.append(line);
1259                                    logBuilder.append('\n');
1260                                }
1261                                dropBuilder.append(line);
1262                                dropBuilder.append('\n');
1263                            }
1264                            converter.close();
1265                        } catch (IOException e) {
1266                        }
1267                        synchronized (ActivityManagerService.this) {
1268                            catPw.println();
1269                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1270                            catPw.println();
1271                            dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
1272                            catPw.println();
1273                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1274                        }
1275                        dropBuilder.append(catSw.toString());
1276                        addErrorToDropBox("lowmem", null, "system_server", null,
1277                                null, tag.toString(), dropBuilder.toString(), null, null);
1278                        Slog.i(TAG, logBuilder.toString());
1279                        synchronized (ActivityManagerService.this) {
1280                            long now = SystemClock.uptimeMillis();
1281                            if (mLastMemUsageReportTime < now) {
1282                                mLastMemUsageReportTime = now;
1283                            }
1284                        }
1285                    }
1286                };
1287                thread.start();
1288                break;
1289            }
1290            }
1291        }
1292    };
1293
1294    public static void setSystemProcess() {
1295        try {
1296            ActivityManagerService m = mSelf;
1297
1298            ServiceManager.addService("activity", m, true);
1299            ServiceManager.addService("meminfo", new MemBinder(m));
1300            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1301            ServiceManager.addService("dbinfo", new DbBinder(m));
1302            if (MONITOR_CPU_USAGE) {
1303                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1304            }
1305            ServiceManager.addService("permission", new PermissionController(m));
1306
1307            ApplicationInfo info =
1308                mSelf.mContext.getPackageManager().getApplicationInfo(
1309                            "android", STOCK_PM_FLAGS);
1310            mSystemThread.installSystemApplicationInfo(info);
1311
1312            synchronized (mSelf) {
1313                ProcessRecord app = mSelf.newProcessRecordLocked(
1314                        mSystemThread.getApplicationThread(), info,
1315                        info.processName, false);
1316                app.persistent = true;
1317                app.pid = MY_PID;
1318                app.maxAdj = ProcessList.SYSTEM_ADJ;
1319                mSelf.mProcessNames.put(app.processName, app.uid, app);
1320                synchronized (mSelf.mPidsSelfLocked) {
1321                    mSelf.mPidsSelfLocked.put(app.pid, app);
1322                }
1323                mSelf.updateLruProcessLocked(app, true, true);
1324            }
1325        } catch (PackageManager.NameNotFoundException e) {
1326            throw new RuntimeException(
1327                    "Unable to find android system package", e);
1328        }
1329    }
1330
1331    public void setWindowManager(WindowManagerService wm) {
1332        mWindowManager = wm;
1333    }
1334
1335    public static final Context main(int factoryTest) {
1336        AThread thr = new AThread();
1337        thr.start();
1338
1339        synchronized (thr) {
1340            while (thr.mService == null) {
1341                try {
1342                    thr.wait();
1343                } catch (InterruptedException e) {
1344                }
1345            }
1346        }
1347
1348        ActivityManagerService m = thr.mService;
1349        mSelf = m;
1350        ActivityThread at = ActivityThread.systemMain();
1351        mSystemThread = at;
1352        Context context = at.getSystemContext();
1353        context.setTheme(android.R.style.Theme_Holo);
1354        m.mContext = context;
1355        m.mFactoryTest = factoryTest;
1356        m.mMainStack = new ActivityStack(m, context, true);
1357
1358        m.mBatteryStatsService.publish(context);
1359        m.mUsageStatsService.publish(context);
1360
1361        synchronized (thr) {
1362            thr.mReady = true;
1363            thr.notifyAll();
1364        }
1365
1366        m.startRunning(null, null, null, null);
1367
1368        return context;
1369    }
1370
1371    public static ActivityManagerService self() {
1372        return mSelf;
1373    }
1374
1375    static class AThread extends Thread {
1376        ActivityManagerService mService;
1377        boolean mReady = false;
1378
1379        public AThread() {
1380            super("ActivityManager");
1381        }
1382
1383        public void run() {
1384            Looper.prepare();
1385
1386            android.os.Process.setThreadPriority(
1387                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1388            android.os.Process.setCanSelfBackground(false);
1389
1390            ActivityManagerService m = new ActivityManagerService();
1391
1392            synchronized (this) {
1393                mService = m;
1394                notifyAll();
1395            }
1396
1397            synchronized (this) {
1398                while (!mReady) {
1399                    try {
1400                        wait();
1401                    } catch (InterruptedException e) {
1402                    }
1403                }
1404            }
1405
1406            // For debug builds, log event loop stalls to dropbox for analysis.
1407            if (StrictMode.conditionallyEnableDebugLogging()) {
1408                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1409            }
1410
1411            Looper.loop();
1412        }
1413    }
1414
1415    static class MemBinder extends Binder {
1416        ActivityManagerService mActivityManagerService;
1417        MemBinder(ActivityManagerService activityManagerService) {
1418            mActivityManagerService = activityManagerService;
1419        }
1420
1421        @Override
1422        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1423            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1424                    != PackageManager.PERMISSION_GRANTED) {
1425                pw.println("Permission Denial: can't dump meminfo from from pid="
1426                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1427                        + " without permission " + android.Manifest.permission.DUMP);
1428                return;
1429            }
1430
1431            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1432                    false, null, null, null);
1433        }
1434    }
1435
1436    static class GraphicsBinder extends Binder {
1437        ActivityManagerService mActivityManagerService;
1438        GraphicsBinder(ActivityManagerService activityManagerService) {
1439            mActivityManagerService = activityManagerService;
1440        }
1441
1442        @Override
1443        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1444            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1445                    != PackageManager.PERMISSION_GRANTED) {
1446                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1447                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1448                        + " without permission " + android.Manifest.permission.DUMP);
1449                return;
1450            }
1451
1452            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1453        }
1454    }
1455
1456    static class DbBinder extends Binder {
1457        ActivityManagerService mActivityManagerService;
1458        DbBinder(ActivityManagerService activityManagerService) {
1459            mActivityManagerService = activityManagerService;
1460        }
1461
1462        @Override
1463        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1464            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1465                    != PackageManager.PERMISSION_GRANTED) {
1466                pw.println("Permission Denial: can't dump dbinfo from from pid="
1467                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1468                        + " without permission " + android.Manifest.permission.DUMP);
1469                return;
1470            }
1471
1472            mActivityManagerService.dumpDbInfo(fd, pw, args);
1473        }
1474    }
1475
1476    static class CpuBinder extends Binder {
1477        ActivityManagerService mActivityManagerService;
1478        CpuBinder(ActivityManagerService activityManagerService) {
1479            mActivityManagerService = activityManagerService;
1480        }
1481
1482        @Override
1483        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1484            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1485                    != PackageManager.PERMISSION_GRANTED) {
1486                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1487                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1488                        + " without permission " + android.Manifest.permission.DUMP);
1489                return;
1490            }
1491
1492            synchronized (mActivityManagerService.mProcessStatsThread) {
1493                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1494                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1495                        SystemClock.uptimeMillis()));
1496            }
1497        }
1498    }
1499
1500    private ActivityManagerService() {
1501        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1502
1503        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1504        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1505        mBroadcastQueues[0] = mFgBroadcastQueue;
1506        mBroadcastQueues[1] = mBgBroadcastQueue;
1507
1508        File dataDir = Environment.getDataDirectory();
1509        File systemDir = new File(dataDir, "system");
1510        systemDir.mkdirs();
1511        mBatteryStatsService = new BatteryStatsService(new File(
1512                systemDir, "batterystats.bin").toString());
1513        mBatteryStatsService.getActiveStatistics().readLocked();
1514        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1515        mOnBattery = DEBUG_POWER ? true
1516                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1517        mBatteryStatsService.getActiveStatistics().setCallback(this);
1518
1519        mUsageStatsService = new UsageStatsService(new File(
1520                systemDir, "usagestats").toString());
1521        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1522
1523        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1524            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1525
1526        mConfiguration.setToDefaults();
1527        mConfiguration.locale = Locale.getDefault();
1528        mConfigurationSeq = mConfiguration.seq = 1;
1529        mProcessStats.init();
1530
1531        mCompatModePackages = new CompatModePackages(this, systemDir);
1532
1533        // Add ourself to the Watchdog monitors.
1534        Watchdog.getInstance().addMonitor(this);
1535
1536        mProcessStatsThread = new Thread("ProcessStats") {
1537            public void run() {
1538                while (true) {
1539                    try {
1540                        try {
1541                            synchronized(this) {
1542                                final long now = SystemClock.uptimeMillis();
1543                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1544                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1545                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1546                                //        + ", write delay=" + nextWriteDelay);
1547                                if (nextWriteDelay < nextCpuDelay) {
1548                                    nextCpuDelay = nextWriteDelay;
1549                                }
1550                                if (nextCpuDelay > 0) {
1551                                    mProcessStatsMutexFree.set(true);
1552                                    this.wait(nextCpuDelay);
1553                                }
1554                            }
1555                        } catch (InterruptedException e) {
1556                        }
1557                        updateCpuStatsNow();
1558                    } catch (Exception e) {
1559                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1560                    }
1561                }
1562            }
1563        };
1564        mProcessStatsThread.start();
1565    }
1566
1567    @Override
1568    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1569            throws RemoteException {
1570        if (code == SYSPROPS_TRANSACTION) {
1571            // We need to tell all apps about the system property change.
1572            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1573            synchronized(this) {
1574                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1575                    final int NA = apps.size();
1576                    for (int ia=0; ia<NA; ia++) {
1577                        ProcessRecord app = apps.valueAt(ia);
1578                        if (app.thread != null) {
1579                            procs.add(app.thread.asBinder());
1580                        }
1581                    }
1582                }
1583            }
1584
1585            int N = procs.size();
1586            for (int i=0; i<N; i++) {
1587                Parcel data2 = Parcel.obtain();
1588                try {
1589                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1590                } catch (RemoteException e) {
1591                }
1592                data2.recycle();
1593            }
1594        }
1595        try {
1596            return super.onTransact(code, data, reply, flags);
1597        } catch (RuntimeException e) {
1598            // The activity manager only throws security exceptions, so let's
1599            // log all others.
1600            if (!(e instanceof SecurityException)) {
1601                Slog.e(TAG, "Activity Manager Crash", e);
1602            }
1603            throw e;
1604        }
1605    }
1606
1607    void updateCpuStats() {
1608        final long now = SystemClock.uptimeMillis();
1609        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1610            return;
1611        }
1612        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1613            synchronized (mProcessStatsThread) {
1614                mProcessStatsThread.notify();
1615            }
1616        }
1617    }
1618
1619    void updateCpuStatsNow() {
1620        synchronized (mProcessStatsThread) {
1621            mProcessStatsMutexFree.set(false);
1622            final long now = SystemClock.uptimeMillis();
1623            boolean haveNewCpuStats = false;
1624
1625            if (MONITOR_CPU_USAGE &&
1626                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1627                mLastCpuTime.set(now);
1628                haveNewCpuStats = true;
1629                mProcessStats.update();
1630                //Slog.i(TAG, mProcessStats.printCurrentState());
1631                //Slog.i(TAG, "Total CPU usage: "
1632                //        + mProcessStats.getTotalCpuPercent() + "%");
1633
1634                // Slog the cpu usage if the property is set.
1635                if ("true".equals(SystemProperties.get("events.cpu"))) {
1636                    int user = mProcessStats.getLastUserTime();
1637                    int system = mProcessStats.getLastSystemTime();
1638                    int iowait = mProcessStats.getLastIoWaitTime();
1639                    int irq = mProcessStats.getLastIrqTime();
1640                    int softIrq = mProcessStats.getLastSoftIrqTime();
1641                    int idle = mProcessStats.getLastIdleTime();
1642
1643                    int total = user + system + iowait + irq + softIrq + idle;
1644                    if (total == 0) total = 1;
1645
1646                    EventLog.writeEvent(EventLogTags.CPU,
1647                            ((user+system+iowait+irq+softIrq) * 100) / total,
1648                            (user * 100) / total,
1649                            (system * 100) / total,
1650                            (iowait * 100) / total,
1651                            (irq * 100) / total,
1652                            (softIrq * 100) / total);
1653                }
1654            }
1655
1656            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1657            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1658            synchronized(bstats) {
1659                synchronized(mPidsSelfLocked) {
1660                    if (haveNewCpuStats) {
1661                        if (mOnBattery) {
1662                            int perc = bstats.startAddingCpuLocked();
1663                            int totalUTime = 0;
1664                            int totalSTime = 0;
1665                            final int N = mProcessStats.countStats();
1666                            for (int i=0; i<N; i++) {
1667                                ProcessStats.Stats st = mProcessStats.getStats(i);
1668                                if (!st.working) {
1669                                    continue;
1670                                }
1671                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1672                                int otherUTime = (st.rel_utime*perc)/100;
1673                                int otherSTime = (st.rel_stime*perc)/100;
1674                                totalUTime += otherUTime;
1675                                totalSTime += otherSTime;
1676                                if (pr != null) {
1677                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1678                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1679                                            st.rel_stime-otherSTime);
1680                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1681                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1682                                } else {
1683                                    BatteryStatsImpl.Uid.Proc ps =
1684                                            bstats.getProcessStatsLocked(st.name, st.pid);
1685                                    if (ps != null) {
1686                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1687                                                st.rel_stime-otherSTime);
1688                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1689                                    }
1690                                }
1691                            }
1692                            bstats.finishAddingCpuLocked(perc, totalUTime,
1693                                    totalSTime, cpuSpeedTimes);
1694                        }
1695                    }
1696                }
1697
1698                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1699                    mLastWriteTime = now;
1700                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1701                }
1702            }
1703        }
1704    }
1705
1706    @Override
1707    public void batteryNeedsCpuUpdate() {
1708        updateCpuStatsNow();
1709    }
1710
1711    @Override
1712    public void batteryPowerChanged(boolean onBattery) {
1713        // When plugging in, update the CPU stats first before changing
1714        // the plug state.
1715        updateCpuStatsNow();
1716        synchronized (this) {
1717            synchronized(mPidsSelfLocked) {
1718                mOnBattery = DEBUG_POWER ? true : onBattery;
1719            }
1720        }
1721    }
1722
1723    /**
1724     * Initialize the application bind args. These are passed to each
1725     * process when the bindApplication() IPC is sent to the process. They're
1726     * lazily setup to make sure the services are running when they're asked for.
1727     */
1728    private HashMap<String, IBinder> getCommonServicesLocked() {
1729        if (mAppBindArgs == null) {
1730            mAppBindArgs = new HashMap<String, IBinder>();
1731
1732            // Setup the application init args
1733            mAppBindArgs.put("package", ServiceManager.getService("package"));
1734            mAppBindArgs.put("window", ServiceManager.getService("window"));
1735            mAppBindArgs.put(Context.ALARM_SERVICE,
1736                    ServiceManager.getService(Context.ALARM_SERVICE));
1737        }
1738        return mAppBindArgs;
1739    }
1740
1741    final void setFocusedActivityLocked(ActivityRecord r) {
1742        if (mFocusedActivity != r) {
1743            mFocusedActivity = r;
1744            if (r != null) {
1745                mWindowManager.setFocusedApp(r.appToken, true);
1746            }
1747        }
1748    }
1749
1750    private final void updateLruProcessInternalLocked(ProcessRecord app,
1751            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1752        // put it on the LRU to keep track of when it should be exited.
1753        int lrui = mLruProcesses.indexOf(app);
1754        if (lrui >= 0) mLruProcesses.remove(lrui);
1755
1756        int i = mLruProcesses.size()-1;
1757        int skipTop = 0;
1758
1759        app.lruSeq = mLruSeq;
1760
1761        // compute the new weight for this process.
1762        if (updateActivityTime) {
1763            app.lastActivityTime = SystemClock.uptimeMillis();
1764        }
1765        if (app.activities.size() > 0) {
1766            // If this process has activities, we more strongly want to keep
1767            // it around.
1768            app.lruWeight = app.lastActivityTime;
1769        } else if (app.pubProviders.size() > 0) {
1770            // If this process contains content providers, we want to keep
1771            // it a little more strongly.
1772            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1773            // Also don't let it kick out the first few "real" hidden processes.
1774            skipTop = ProcessList.MIN_HIDDEN_APPS;
1775        } else {
1776            // If this process doesn't have activities, we less strongly
1777            // want to keep it around, and generally want to avoid getting
1778            // in front of any very recently used activities.
1779            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1780            // Also don't let it kick out the first few "real" hidden processes.
1781            skipTop = ProcessList.MIN_HIDDEN_APPS;
1782        }
1783
1784        while (i >= 0) {
1785            ProcessRecord p = mLruProcesses.get(i);
1786            // If this app shouldn't be in front of the first N background
1787            // apps, then skip over that many that are currently hidden.
1788            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1789                skipTop--;
1790            }
1791            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1792                mLruProcesses.add(i+1, app);
1793                break;
1794            }
1795            i--;
1796        }
1797        if (i < 0) {
1798            mLruProcesses.add(0, app);
1799        }
1800
1801        // If the app is currently using a content provider or service,
1802        // bump those processes as well.
1803        if (app.connections.size() > 0) {
1804            for (ConnectionRecord cr : app.connections) {
1805                if (cr.binding != null && cr.binding.service != null
1806                        && cr.binding.service.app != null
1807                        && cr.binding.service.app.lruSeq != mLruSeq) {
1808                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1809                            updateActivityTime, i+1);
1810                }
1811            }
1812        }
1813        if (app.conProviders.size() > 0) {
1814            for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1815                if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1816                    updateLruProcessInternalLocked(cpr.proc, oomAdj,
1817                            updateActivityTime, i+1);
1818                }
1819            }
1820        }
1821
1822        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1823        if (oomAdj) {
1824            updateOomAdjLocked();
1825        }
1826    }
1827
1828    final void updateLruProcessLocked(ProcessRecord app,
1829            boolean oomAdj, boolean updateActivityTime) {
1830        mLruSeq++;
1831        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1832    }
1833
1834    final ProcessRecord getProcessRecordLocked(
1835            String processName, int uid) {
1836        if (uid == Process.SYSTEM_UID) {
1837            // The system gets to run in any process.  If there are multiple
1838            // processes with the same uid, just pick the first (this
1839            // should never happen).
1840            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1841                    processName);
1842            if (procs == null) return null;
1843            final int N = procs.size();
1844            for (int i = 0; i < N; i++) {
1845                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1846            }
1847        }
1848        ProcessRecord proc = mProcessNames.get(processName, uid);
1849        return proc;
1850    }
1851
1852    void ensurePackageDexOpt(String packageName) {
1853        IPackageManager pm = AppGlobals.getPackageManager();
1854        try {
1855            if (pm.performDexOpt(packageName)) {
1856                mDidDexOpt = true;
1857            }
1858        } catch (RemoteException e) {
1859        }
1860    }
1861
1862    boolean isNextTransitionForward() {
1863        int transit = mWindowManager.getPendingAppTransition();
1864        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1865                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1866                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1867    }
1868
1869    final ProcessRecord startProcessLocked(String processName,
1870            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1871            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1872            boolean isolated) {
1873        ProcessRecord app;
1874        if (!isolated) {
1875            app = getProcessRecordLocked(processName, info.uid);
1876        } else {
1877            // If this is an isolated process, it can't re-use an existing process.
1878            app = null;
1879        }
1880        // We don't have to do anything more if:
1881        // (1) There is an existing application record; and
1882        // (2) The caller doesn't think it is dead, OR there is no thread
1883        //     object attached to it so we know it couldn't have crashed; and
1884        // (3) There is a pid assigned to it, so it is either starting or
1885        //     already running.
1886        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1887                + " app=" + app + " knownToBeDead=" + knownToBeDead
1888                + " thread=" + (app != null ? app.thread : null)
1889                + " pid=" + (app != null ? app.pid : -1));
1890        if (app != null && app.pid > 0) {
1891            if (!knownToBeDead || app.thread == null) {
1892                // We already have the app running, or are waiting for it to
1893                // come up (we have a pid but not yet its thread), so keep it.
1894                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1895                // If this is a new package in the process, add the package to the list
1896                app.addPackage(info.packageName);
1897                return app;
1898            } else {
1899                // An application record is attached to a previous process,
1900                // clean it up now.
1901                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1902                handleAppDiedLocked(app, true, true);
1903            }
1904        }
1905
1906        String hostingNameStr = hostingName != null
1907                ? hostingName.flattenToShortString() : null;
1908
1909        if (!isolated) {
1910            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1911                // If we are in the background, then check to see if this process
1912                // is bad.  If so, we will just silently fail.
1913                if (mBadProcesses.get(info.processName, info.uid) != null) {
1914                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1915                            + "/" + info.processName);
1916                    return null;
1917                }
1918            } else {
1919                // When the user is explicitly starting a process, then clear its
1920                // crash count so that we won't make it bad until they see at
1921                // least one crash dialog again, and make the process good again
1922                // if it had been bad.
1923                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1924                        + "/" + info.processName);
1925                mProcessCrashTimes.remove(info.processName, info.uid);
1926                if (mBadProcesses.get(info.processName, info.uid) != null) {
1927                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1928                            info.processName);
1929                    mBadProcesses.remove(info.processName, info.uid);
1930                    if (app != null) {
1931                        app.bad = false;
1932                    }
1933                }
1934            }
1935        }
1936
1937        if (app == null) {
1938            app = newProcessRecordLocked(null, info, processName, isolated);
1939            if (app == null) {
1940                Slog.w(TAG, "Failed making new process record for "
1941                        + processName + "/" + info.uid + " isolated=" + isolated);
1942                return null;
1943            }
1944            mProcessNames.put(processName, app.uid, app);
1945            if (isolated) {
1946                mIsolatedProcesses.put(app.uid, app);
1947            }
1948        } else {
1949            // If this is a new package in the process, add the package to the list
1950            app.addPackage(info.packageName);
1951        }
1952
1953        // If the system is not ready yet, then hold off on starting this
1954        // process until it is.
1955        if (!mProcessesReady
1956                && !isAllowedWhileBooting(info)
1957                && !allowWhileBooting) {
1958            if (!mProcessesOnHold.contains(app)) {
1959                mProcessesOnHold.add(app);
1960            }
1961            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1962            return app;
1963        }
1964
1965        startProcessLocked(app, hostingType, hostingNameStr);
1966        return (app.pid != 0) ? app : null;
1967    }
1968
1969    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1970        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1971    }
1972
1973    private final void startProcessLocked(ProcessRecord app,
1974            String hostingType, String hostingNameStr) {
1975        if (app.pid > 0 && app.pid != MY_PID) {
1976            synchronized (mPidsSelfLocked) {
1977                mPidsSelfLocked.remove(app.pid);
1978                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1979            }
1980            app.pid = 0;
1981        }
1982
1983        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1984                "startProcessLocked removing on hold: " + app);
1985        mProcessesOnHold.remove(app);
1986
1987        updateCpuStats();
1988
1989        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1990        mProcDeaths[0] = 0;
1991
1992        try {
1993            int uid = app.uid;
1994
1995            int[] gids = null;
1996            if (!app.isolated) {
1997                try {
1998                    gids = mContext.getPackageManager().getPackageGids(
1999                            app.info.packageName);
2000                } catch (PackageManager.NameNotFoundException e) {
2001                    Slog.w(TAG, "Unable to retrieve gids", e);
2002                }
2003            }
2004            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2005                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2006                        && mTopComponent != null
2007                        && app.processName.equals(mTopComponent.getPackageName())) {
2008                    uid = 0;
2009                }
2010                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2011                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2012                    uid = 0;
2013                }
2014            }
2015            int debugFlags = 0;
2016            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2017                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2018                // Also turn on CheckJNI for debuggable apps. It's quite
2019                // awkward to turn on otherwise.
2020                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2021            }
2022            // Run the app in safe mode if its manifest requests so or the
2023            // system is booted in safe mode.
2024            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2025                Zygote.systemInSafeMode == true) {
2026                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2027            }
2028            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2029                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2030            }
2031            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2032                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2033            }
2034            if ("1".equals(SystemProperties.get("debug.assert"))) {
2035                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2036            }
2037
2038            // Start the process.  It will either succeed and return a result containing
2039            // the PID of the new process, or else throw a RuntimeException.
2040            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2041                    app.processName, uid, uid, gids, debugFlags,
2042                    app.info.targetSdkVersion, null);
2043
2044            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2045            synchronized (bs) {
2046                if (bs.isOnBattery()) {
2047                    app.batteryStats.incStartsLocked();
2048                }
2049            }
2050
2051            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2052                    app.processName, hostingType,
2053                    hostingNameStr != null ? hostingNameStr : "");
2054
2055            if (app.persistent) {
2056                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2057            }
2058
2059            StringBuilder buf = mStringBuilder;
2060            buf.setLength(0);
2061            buf.append("Start proc ");
2062            buf.append(app.processName);
2063            buf.append(" for ");
2064            buf.append(hostingType);
2065            if (hostingNameStr != null) {
2066                buf.append(" ");
2067                buf.append(hostingNameStr);
2068            }
2069            buf.append(": pid=");
2070            buf.append(startResult.pid);
2071            buf.append(" uid=");
2072            buf.append(uid);
2073            buf.append(" gids={");
2074            if (gids != null) {
2075                for (int gi=0; gi<gids.length; gi++) {
2076                    if (gi != 0) buf.append(", ");
2077                    buf.append(gids[gi]);
2078
2079                }
2080            }
2081            buf.append("}");
2082            Slog.i(TAG, buf.toString());
2083            app.pid = startResult.pid;
2084            app.usingWrapper = startResult.usingWrapper;
2085            app.removed = false;
2086            synchronized (mPidsSelfLocked) {
2087                this.mPidsSelfLocked.put(startResult.pid, app);
2088                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2089                msg.obj = app;
2090                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2091                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2092            }
2093        } catch (RuntimeException e) {
2094            // XXX do better error recovery.
2095            app.pid = 0;
2096            Slog.e(TAG, "Failure starting process " + app.processName, e);
2097        }
2098    }
2099
2100    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2101        if (resumed) {
2102            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2103        } else {
2104            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2105        }
2106    }
2107
2108    boolean startHomeActivityLocked(int userId) {
2109        if (mHeadless) {
2110            // Added because none of the other calls to ensureBootCompleted seem to fire
2111            // when running headless.
2112            ensureBootCompleted();
2113            return false;
2114        }
2115
2116        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2117                && mTopAction == null) {
2118            // We are running in factory test mode, but unable to find
2119            // the factory test app, so just sit around displaying the
2120            // error message and don't try to start anything.
2121            return false;
2122        }
2123        Intent intent = new Intent(
2124            mTopAction,
2125            mTopData != null ? Uri.parse(mTopData) : null);
2126        intent.setComponent(mTopComponent);
2127        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2128            intent.addCategory(Intent.CATEGORY_HOME);
2129        }
2130        ActivityInfo aInfo =
2131            intent.resolveActivityInfo(mContext.getPackageManager(),
2132                    STOCK_PM_FLAGS);
2133        if (aInfo != null) {
2134            intent.setComponent(new ComponentName(
2135                    aInfo.applicationInfo.packageName, aInfo.name));
2136            // Don't do this if the home app is currently being
2137            // instrumented.
2138            aInfo = new ActivityInfo(aInfo);
2139            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2140            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2141                    aInfo.applicationInfo.uid);
2142            if (app == null || app.instrumentationClass == null) {
2143                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2144                mMainStack.startActivityLocked(null, intent, null, aInfo,
2145                        null, null, 0, 0, 0, 0, null, false, null);
2146            }
2147        }
2148
2149        return true;
2150    }
2151
2152    /**
2153     * Starts the "new version setup screen" if appropriate.
2154     */
2155    void startSetupActivityLocked() {
2156        // Only do this once per boot.
2157        if (mCheckedForSetup) {
2158            return;
2159        }
2160
2161        // We will show this screen if the current one is a different
2162        // version than the last one shown, and we are not running in
2163        // low-level factory test mode.
2164        final ContentResolver resolver = mContext.getContentResolver();
2165        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2166                Settings.Secure.getInt(resolver,
2167                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2168            mCheckedForSetup = true;
2169
2170            // See if we should be showing the platform update setup UI.
2171            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2172            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2173                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2174
2175            // We don't allow third party apps to replace this.
2176            ResolveInfo ri = null;
2177            for (int i=0; ris != null && i<ris.size(); i++) {
2178                if ((ris.get(i).activityInfo.applicationInfo.flags
2179                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2180                    ri = ris.get(i);
2181                    break;
2182                }
2183            }
2184
2185            if (ri != null) {
2186                String vers = ri.activityInfo.metaData != null
2187                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2188                        : null;
2189                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2190                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2191                            Intent.METADATA_SETUP_VERSION);
2192                }
2193                String lastVers = Settings.Secure.getString(
2194                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2195                if (vers != null && !vers.equals(lastVers)) {
2196                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2197                    intent.setComponent(new ComponentName(
2198                            ri.activityInfo.packageName, ri.activityInfo.name));
2199                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2200                            null, null, 0, 0, 0, 0, null, false, null);
2201                }
2202            }
2203        }
2204    }
2205
2206    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2207        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2208    }
2209
2210    void enforceNotIsolatedCaller(String caller) {
2211        if (UserId.isIsolated(Binder.getCallingUid())) {
2212            throw new SecurityException("Isolated process not allowed to call " + caller);
2213        }
2214    }
2215
2216    public int getFrontActivityScreenCompatMode() {
2217        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2218        synchronized (this) {
2219            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2220        }
2221    }
2222
2223    public void setFrontActivityScreenCompatMode(int mode) {
2224        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2225                "setFrontActivityScreenCompatMode");
2226        synchronized (this) {
2227            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2228        }
2229    }
2230
2231    public int getPackageScreenCompatMode(String packageName) {
2232        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2233        synchronized (this) {
2234            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2235        }
2236    }
2237
2238    public void setPackageScreenCompatMode(String packageName, int mode) {
2239        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2240                "setPackageScreenCompatMode");
2241        synchronized (this) {
2242            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2243        }
2244    }
2245
2246    public boolean getPackageAskScreenCompat(String packageName) {
2247        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2248        synchronized (this) {
2249            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2250        }
2251    }
2252
2253    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2255                "setPackageAskScreenCompat");
2256        synchronized (this) {
2257            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2258        }
2259    }
2260
2261    void reportResumedActivityLocked(ActivityRecord r) {
2262        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2263
2264        final int identHash = System.identityHashCode(r);
2265        updateUsageStats(r, true);
2266    }
2267
2268    private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2269        int i = mProcessObservers.beginBroadcast();
2270        while (i > 0) {
2271            i--;
2272            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2273            if (observer != null) {
2274                try {
2275                    observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2276                } catch (RemoteException e) {
2277                }
2278            }
2279        }
2280        mProcessObservers.finishBroadcast();
2281    }
2282
2283    private void dispatchProcessDied(int pid, int uid) {
2284        int i = mProcessObservers.beginBroadcast();
2285        while (i > 0) {
2286            i--;
2287            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2288            if (observer != null) {
2289                try {
2290                    observer.onProcessDied(pid, uid);
2291                } catch (RemoteException e) {
2292                }
2293            }
2294        }
2295        mProcessObservers.finishBroadcast();
2296    }
2297
2298    final void doPendingActivityLaunchesLocked(boolean doResume) {
2299        final int N = mPendingActivityLaunches.size();
2300        if (N <= 0) {
2301            return;
2302        }
2303        for (int i=0; i<N; i++) {
2304            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2305            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2306                    pal.startFlags, doResume && i == (N-1), null);
2307        }
2308        mPendingActivityLaunches.clear();
2309    }
2310
2311    public final int startActivity(IApplicationThread caller,
2312            Intent intent, String resolvedType, IBinder resultTo,
2313            String resultWho, int requestCode, int startFlags,
2314            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2315        enforceNotIsolatedCaller("startActivity");
2316        int userId = 0;
2317        if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2318            // Requesting home, set the identity to the current user
2319            // HACK!
2320            userId = mCurrentUserId;
2321        } else {
2322            // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2323            // the current user's userId
2324            if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2325                userId = 0;
2326            } else {
2327                userId = Binder.getOrigCallingUser();
2328            }
2329        }
2330        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2331                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2332                null, null, options, userId);
2333    }
2334
2335    public final WaitResult startActivityAndWait(IApplicationThread caller,
2336            Intent intent, String resolvedType, IBinder resultTo,
2337            String resultWho, int requestCode, int startFlags, String profileFile,
2338            ParcelFileDescriptor profileFd, Bundle options) {
2339        enforceNotIsolatedCaller("startActivityAndWait");
2340        WaitResult res = new WaitResult();
2341        int userId = Binder.getOrigCallingUser();
2342        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2343                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2344                res, null, options, userId);
2345        return res;
2346    }
2347
2348    public final int startActivityWithConfig(IApplicationThread caller,
2349            Intent intent, String resolvedType, IBinder resultTo,
2350            String resultWho, int requestCode, int startFlags, Configuration config,
2351            Bundle options) {
2352        enforceNotIsolatedCaller("startActivityWithConfig");
2353        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2354                resultTo, resultWho, requestCode, startFlags,
2355                null, null, null, config, options, Binder.getOrigCallingUser());
2356        return ret;
2357    }
2358
2359    public int startActivityIntentSender(IApplicationThread caller,
2360            IntentSender intent, Intent fillInIntent, String resolvedType,
2361            IBinder resultTo, String resultWho, int requestCode,
2362            int flagsMask, int flagsValues, Bundle options) {
2363        enforceNotIsolatedCaller("startActivityIntentSender");
2364        // Refuse possible leaked file descriptors
2365        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2366            throw new IllegalArgumentException("File descriptors passed in Intent");
2367        }
2368
2369        IIntentSender sender = intent.getTarget();
2370        if (!(sender instanceof PendingIntentRecord)) {
2371            throw new IllegalArgumentException("Bad PendingIntent object");
2372        }
2373
2374        PendingIntentRecord pir = (PendingIntentRecord)sender;
2375
2376        synchronized (this) {
2377            // If this is coming from the currently resumed activity, it is
2378            // effectively saying that app switches are allowed at this point.
2379            if (mMainStack.mResumedActivity != null
2380                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2381                            Binder.getCallingUid()) {
2382                mAppSwitchesAllowedTime = 0;
2383            }
2384        }
2385        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2386                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2387        return ret;
2388    }
2389
2390    public boolean startNextMatchingActivity(IBinder callingActivity,
2391            Intent intent, Bundle options) {
2392        // Refuse possible leaked file descriptors
2393        if (intent != null && intent.hasFileDescriptors() == true) {
2394            throw new IllegalArgumentException("File descriptors passed in Intent");
2395        }
2396
2397        synchronized (this) {
2398            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2399            if (r == null) {
2400                ActivityOptions.abort(options);
2401                return false;
2402            }
2403            if (r.app == null || r.app.thread == null) {
2404                // The caller is not running...  d'oh!
2405                ActivityOptions.abort(options);
2406                return false;
2407            }
2408            intent = new Intent(intent);
2409            // The caller is not allowed to change the data.
2410            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2411            // And we are resetting to find the next component...
2412            intent.setComponent(null);
2413
2414            ActivityInfo aInfo = null;
2415            try {
2416                List<ResolveInfo> resolves =
2417                    AppGlobals.getPackageManager().queryIntentActivities(
2418                            intent, r.resolvedType,
2419                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2420                            UserId.getCallingUserId());
2421
2422                // Look for the original activity in the list...
2423                final int N = resolves != null ? resolves.size() : 0;
2424                for (int i=0; i<N; i++) {
2425                    ResolveInfo rInfo = resolves.get(i);
2426                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2427                            && rInfo.activityInfo.name.equals(r.info.name)) {
2428                        // We found the current one...  the next matching is
2429                        // after it.
2430                        i++;
2431                        if (i<N) {
2432                            aInfo = resolves.get(i).activityInfo;
2433                        }
2434                        break;
2435                    }
2436                }
2437            } catch (RemoteException e) {
2438            }
2439
2440            if (aInfo == null) {
2441                // Nobody who is next!
2442                ActivityOptions.abort(options);
2443                return false;
2444            }
2445
2446            intent.setComponent(new ComponentName(
2447                    aInfo.applicationInfo.packageName, aInfo.name));
2448            intent.setFlags(intent.getFlags()&~(
2449                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2450                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2451                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2452                    Intent.FLAG_ACTIVITY_NEW_TASK));
2453
2454            // Okay now we need to start the new activity, replacing the
2455            // currently running activity.  This is a little tricky because
2456            // we want to start the new one as if the current one is finished,
2457            // but not finish the current one first so that there is no flicker.
2458            // And thus...
2459            final boolean wasFinishing = r.finishing;
2460            r.finishing = true;
2461
2462            // Propagate reply information over to the new activity.
2463            final ActivityRecord resultTo = r.resultTo;
2464            final String resultWho = r.resultWho;
2465            final int requestCode = r.requestCode;
2466            r.resultTo = null;
2467            if (resultTo != null) {
2468                resultTo.removeResultsLocked(r, resultWho, requestCode);
2469            }
2470
2471            final long origId = Binder.clearCallingIdentity();
2472            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2473                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2474                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2475                    options, false, null);
2476            Binder.restoreCallingIdentity(origId);
2477
2478            r.finishing = wasFinishing;
2479            if (res != ActivityManager.START_SUCCESS) {
2480                return false;
2481            }
2482            return true;
2483        }
2484    }
2485
2486    public final int startActivityInPackage(int uid,
2487            Intent intent, String resolvedType, IBinder resultTo,
2488            String resultWho, int requestCode, int startFlags, Bundle options) {
2489
2490        // This is so super not safe, that only the system (or okay root)
2491        // can do it.
2492        int userId = Binder.getOrigCallingUser();
2493        final int callingUid = Binder.getCallingUid();
2494        if (callingUid != 0 && callingUid != Process.myUid()) {
2495            throw new SecurityException(
2496                    "startActivityInPackage only available to the system");
2497        }
2498
2499        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2500                resultTo, resultWho, requestCode, startFlags,
2501                null, null, null, null, options, userId);
2502        return ret;
2503    }
2504
2505    public final int startActivities(IApplicationThread caller,
2506            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2507        enforceNotIsolatedCaller("startActivities");
2508        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2509                options, Binder.getOrigCallingUser());
2510        return ret;
2511    }
2512
2513    public final int startActivitiesInPackage(int uid,
2514            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2515            Bundle options) {
2516
2517        // This is so super not safe, that only the system (or okay root)
2518        // can do it.
2519        final int callingUid = Binder.getCallingUid();
2520        if (callingUid != 0 && callingUid != Process.myUid()) {
2521            throw new SecurityException(
2522                    "startActivityInPackage only available to the system");
2523        }
2524        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2525                options, UserId.getUserId(uid));
2526        return ret;
2527    }
2528
2529    final void addRecentTaskLocked(TaskRecord task) {
2530        int N = mRecentTasks.size();
2531        // Quick case: check if the top-most recent task is the same.
2532        if (N > 0 && mRecentTasks.get(0) == task) {
2533            return;
2534        }
2535        // Remove any existing entries that are the same kind of task.
2536        for (int i=0; i<N; i++) {
2537            TaskRecord tr = mRecentTasks.get(i);
2538            if (task.userId == tr.userId
2539                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2540                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2541                mRecentTasks.remove(i);
2542                i--;
2543                N--;
2544                if (task.intent == null) {
2545                    // If the new recent task we are adding is not fully
2546                    // specified, then replace it with the existing recent task.
2547                    task = tr;
2548                }
2549            }
2550        }
2551        if (N >= MAX_RECENT_TASKS) {
2552            mRecentTasks.remove(N-1);
2553        }
2554        mRecentTasks.add(0, task);
2555    }
2556
2557    public void setRequestedOrientation(IBinder token,
2558            int requestedOrientation) {
2559        synchronized (this) {
2560            ActivityRecord r = mMainStack.isInStackLocked(token);
2561            if (r == null) {
2562                return;
2563            }
2564            final long origId = Binder.clearCallingIdentity();
2565            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2566            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2567                    mConfiguration,
2568                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2569            if (config != null) {
2570                r.frozenBeforeDestroy = true;
2571                if (!updateConfigurationLocked(config, r, false, false)) {
2572                    mMainStack.resumeTopActivityLocked(null);
2573                }
2574            }
2575            Binder.restoreCallingIdentity(origId);
2576        }
2577    }
2578
2579    public int getRequestedOrientation(IBinder token) {
2580        synchronized (this) {
2581            ActivityRecord r = mMainStack.isInStackLocked(token);
2582            if (r == null) {
2583                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2584            }
2585            return mWindowManager.getAppOrientation(r.appToken);
2586        }
2587    }
2588
2589    /**
2590     * This is the internal entry point for handling Activity.finish().
2591     *
2592     * @param token The Binder token referencing the Activity we want to finish.
2593     * @param resultCode Result code, if any, from this Activity.
2594     * @param resultData Result data (Intent), if any, from this Activity.
2595     *
2596     * @return Returns true if the activity successfully finished, or false if it is still running.
2597     */
2598    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2599        // Refuse possible leaked file descriptors
2600        if (resultData != null && resultData.hasFileDescriptors() == true) {
2601            throw new IllegalArgumentException("File descriptors passed in Intent");
2602        }
2603
2604        synchronized(this) {
2605            if (mController != null) {
2606                // Find the first activity that is not finishing.
2607                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2608                if (next != null) {
2609                    // ask watcher if this is allowed
2610                    boolean resumeOK = true;
2611                    try {
2612                        resumeOK = mController.activityResuming(next.packageName);
2613                    } catch (RemoteException e) {
2614                        mController = null;
2615                    }
2616
2617                    if (!resumeOK) {
2618                        return false;
2619                    }
2620                }
2621            }
2622            final long origId = Binder.clearCallingIdentity();
2623            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2624                    resultData, "app-request");
2625            Binder.restoreCallingIdentity(origId);
2626            return res;
2627        }
2628    }
2629
2630    public final void finishHeavyWeightApp() {
2631        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2632                != PackageManager.PERMISSION_GRANTED) {
2633            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2634                    + Binder.getCallingPid()
2635                    + ", uid=" + Binder.getCallingUid()
2636                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2637            Slog.w(TAG, msg);
2638            throw new SecurityException(msg);
2639        }
2640
2641        synchronized(this) {
2642            if (mHeavyWeightProcess == null) {
2643                return;
2644            }
2645
2646            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2647                    mHeavyWeightProcess.activities);
2648            for (int i=0; i<activities.size(); i++) {
2649                ActivityRecord r = activities.get(i);
2650                if (!r.finishing) {
2651                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2652                    if (index >= 0) {
2653                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2654                                null, "finish-heavy");
2655                    }
2656                }
2657            }
2658
2659            mHeavyWeightProcess = null;
2660            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2661        }
2662    }
2663
2664    public void crashApplication(int uid, int initialPid, String packageName,
2665            String message) {
2666        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2667                != PackageManager.PERMISSION_GRANTED) {
2668            String msg = "Permission Denial: crashApplication() from pid="
2669                    + Binder.getCallingPid()
2670                    + ", uid=" + Binder.getCallingUid()
2671                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2672            Slog.w(TAG, msg);
2673            throw new SecurityException(msg);
2674        }
2675
2676        synchronized(this) {
2677            ProcessRecord proc = null;
2678
2679            // Figure out which process to kill.  We don't trust that initialPid
2680            // still has any relation to current pids, so must scan through the
2681            // list.
2682            synchronized (mPidsSelfLocked) {
2683                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2684                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2685                    if (p.uid != uid) {
2686                        continue;
2687                    }
2688                    if (p.pid == initialPid) {
2689                        proc = p;
2690                        break;
2691                    }
2692                    for (String str : p.pkgList) {
2693                        if (str.equals(packageName)) {
2694                            proc = p;
2695                        }
2696                    }
2697                }
2698            }
2699
2700            if (proc == null) {
2701                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2702                        + " initialPid=" + initialPid
2703                        + " packageName=" + packageName);
2704                return;
2705            }
2706
2707            if (proc.thread != null) {
2708                if (proc.pid == Process.myPid()) {
2709                    Log.w(TAG, "crashApplication: trying to crash self!");
2710                    return;
2711                }
2712                long ident = Binder.clearCallingIdentity();
2713                try {
2714                    proc.thread.scheduleCrash(message);
2715                } catch (RemoteException e) {
2716                }
2717                Binder.restoreCallingIdentity(ident);
2718            }
2719        }
2720    }
2721
2722    public final void finishSubActivity(IBinder token, String resultWho,
2723            int requestCode) {
2724        synchronized(this) {
2725            final long origId = Binder.clearCallingIdentity();
2726            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2727            Binder.restoreCallingIdentity(origId);
2728        }
2729    }
2730
2731    public boolean finishActivityAffinity(IBinder token) {
2732        synchronized(this) {
2733            final long origId = Binder.clearCallingIdentity();
2734            boolean res = mMainStack.finishActivityAffinityLocked(token);
2735            Binder.restoreCallingIdentity(origId);
2736            return res;
2737        }
2738    }
2739
2740    public boolean willActivityBeVisible(IBinder token) {
2741        synchronized(this) {
2742            int i;
2743            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2744                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2745                if (r.appToken == token) {
2746                    return true;
2747                }
2748                if (r.fullscreen && !r.finishing) {
2749                    return false;
2750                }
2751            }
2752            return true;
2753        }
2754    }
2755
2756    public void overridePendingTransition(IBinder token, String packageName,
2757            int enterAnim, int exitAnim) {
2758        synchronized(this) {
2759            ActivityRecord self = mMainStack.isInStackLocked(token);
2760            if (self == null) {
2761                return;
2762            }
2763
2764            final long origId = Binder.clearCallingIdentity();
2765
2766            if (self.state == ActivityState.RESUMED
2767                    || self.state == ActivityState.PAUSING) {
2768                mWindowManager.overridePendingAppTransition(packageName,
2769                        enterAnim, exitAnim);
2770            }
2771
2772            Binder.restoreCallingIdentity(origId);
2773        }
2774    }
2775
2776    /**
2777     * Main function for removing an existing process from the activity manager
2778     * as a result of that process going away.  Clears out all connections
2779     * to the process.
2780     */
2781    private final void handleAppDiedLocked(ProcessRecord app,
2782            boolean restarting, boolean allowRestart) {
2783        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2784        if (!restarting) {
2785            mLruProcesses.remove(app);
2786        }
2787
2788        if (mProfileProc == app) {
2789            clearProfilerLocked();
2790        }
2791
2792        // Just in case...
2793        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2794            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2795            mMainStack.mPausingActivity = null;
2796        }
2797        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2798            mMainStack.mLastPausedActivity = null;
2799        }
2800
2801        // Remove this application's activities from active lists.
2802        mMainStack.removeHistoryRecordsForAppLocked(app);
2803
2804        boolean atTop = true;
2805        boolean hasVisibleActivities = false;
2806
2807        // Clean out the history list.
2808        int i = mMainStack.mHistory.size();
2809        if (localLOGV) Slog.v(
2810            TAG, "Removing app " + app + " from history with " + i + " entries");
2811        while (i > 0) {
2812            i--;
2813            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2814            if (localLOGV) Slog.v(
2815                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2816            if (r.app == app) {
2817                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2818                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2819                        RuntimeException here = new RuntimeException("here");
2820                        here.fillInStackTrace();
2821                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2822                                + ": haveState=" + r.haveState
2823                                + " stateNotNeeded=" + r.stateNotNeeded
2824                                + " finishing=" + r.finishing
2825                                + " state=" + r.state, here);
2826                    }
2827                    if (!r.finishing) {
2828                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2829                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2830                                System.identityHashCode(r),
2831                                r.task.taskId, r.shortComponentName,
2832                                "proc died without state saved");
2833                    }
2834                    mMainStack.removeActivityFromHistoryLocked(r);
2835
2836                } else {
2837                    // We have the current state for this activity, so
2838                    // it can be restarted later when needed.
2839                    if (localLOGV) Slog.v(
2840                        TAG, "Keeping entry, setting app to null");
2841                    if (r.visible) {
2842                        hasVisibleActivities = true;
2843                    }
2844                    r.app = null;
2845                    r.nowVisible = false;
2846                    if (!r.haveState) {
2847                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2848                                "App died, clearing saved state of " + r);
2849                        r.icicle = null;
2850                    }
2851                }
2852
2853                r.stack.cleanUpActivityLocked(r, true, true);
2854            }
2855            atTop = false;
2856        }
2857
2858        app.activities.clear();
2859
2860        if (app.instrumentationClass != null) {
2861            Slog.w(TAG, "Crash of app " + app.processName
2862                  + " running instrumentation " + app.instrumentationClass);
2863            Bundle info = new Bundle();
2864            info.putString("shortMsg", "Process crashed.");
2865            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2866        }
2867
2868        if (!restarting) {
2869            if (!mMainStack.resumeTopActivityLocked(null)) {
2870                // If there was nothing to resume, and we are not already
2871                // restarting this process, but there is a visible activity that
2872                // is hosted by the process...  then make sure all visible
2873                // activities are running, taking care of restarting this
2874                // process.
2875                if (hasVisibleActivities) {
2876                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2877                }
2878            }
2879        }
2880    }
2881
2882    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2883        IBinder threadBinder = thread.asBinder();
2884        // Find the application record.
2885        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2886            ProcessRecord rec = mLruProcesses.get(i);
2887            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2888                return i;
2889            }
2890        }
2891        return -1;
2892    }
2893
2894    final ProcessRecord getRecordForAppLocked(
2895            IApplicationThread thread) {
2896        if (thread == null) {
2897            return null;
2898        }
2899
2900        int appIndex = getLRURecordIndexForAppLocked(thread);
2901        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2902    }
2903
2904    final void appDiedLocked(ProcessRecord app, int pid,
2905            IApplicationThread thread) {
2906
2907        mProcDeaths[0]++;
2908
2909        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2910        synchronized (stats) {
2911            stats.noteProcessDiedLocked(app.info.uid, pid);
2912        }
2913
2914        // Clean up already done if the process has been re-started.
2915        if (app.pid == pid && app.thread != null &&
2916                app.thread.asBinder() == thread.asBinder()) {
2917            if (!app.killedBackground) {
2918                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2919                        + ") has died.");
2920            }
2921            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2922            if (localLOGV) Slog.v(
2923                TAG, "Dying app: " + app + ", pid: " + pid
2924                + ", thread: " + thread.asBinder());
2925            boolean doLowMem = app.instrumentationClass == null;
2926            handleAppDiedLocked(app, false, true);
2927
2928            if (doLowMem) {
2929                // If there are no longer any background processes running,
2930                // and the app that died was not running instrumentation,
2931                // then tell everyone we are now low on memory.
2932                boolean haveBg = false;
2933                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2934                    ProcessRecord rec = mLruProcesses.get(i);
2935                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2936                        haveBg = true;
2937                        break;
2938                    }
2939                }
2940
2941                if (!haveBg) {
2942                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2943                    long now = SystemClock.uptimeMillis();
2944                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2945                        ProcessRecord rec = mLruProcesses.get(i);
2946                        if (rec != app && rec.thread != null &&
2947                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2948                            // The low memory report is overriding any current
2949                            // state for a GC request.  Make sure to do
2950                            // heavy/important/visible/foreground processes first.
2951                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2952                                rec.lastRequestedGc = 0;
2953                            } else {
2954                                rec.lastRequestedGc = rec.lastLowMemory;
2955                            }
2956                            rec.reportLowMemory = true;
2957                            rec.lastLowMemory = now;
2958                            mProcessesToGc.remove(rec);
2959                            addProcessToGcListLocked(rec);
2960                        }
2961                    }
2962                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
2963                    scheduleAppGcsLocked();
2964                }
2965            }
2966        } else if (app.pid != pid) {
2967            // A new process has already been started.
2968            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2969                    + ") has died and restarted (pid " + app.pid + ").");
2970            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2971        } else if (DEBUG_PROCESSES) {
2972            Slog.d(TAG, "Received spurious death notification for thread "
2973                    + thread.asBinder());
2974        }
2975    }
2976
2977    /**
2978     * If a stack trace dump file is configured, dump process stack traces.
2979     * @param clearTraces causes the dump file to be erased prior to the new
2980     *    traces being written, if true; when false, the new traces will be
2981     *    appended to any existing file content.
2982     * @param firstPids of dalvik VM processes to dump stack traces for first
2983     * @param lastPids of dalvik VM processes to dump stack traces for last
2984     * @return file containing stack traces, or null if no dump file is configured
2985     */
2986    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2987            ProcessStats processStats, SparseArray<Boolean> lastPids) {
2988        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2989        if (tracesPath == null || tracesPath.length() == 0) {
2990            return null;
2991        }
2992
2993        File tracesFile = new File(tracesPath);
2994        try {
2995            File tracesDir = tracesFile.getParentFile();
2996            if (!tracesDir.exists()) tracesFile.mkdirs();
2997            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
2998
2999            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3000            tracesFile.createNewFile();
3001            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3002        } catch (IOException e) {
3003            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3004            return null;
3005        }
3006
3007        dumpStackTraces(tracesPath, firstPids, processStats, lastPids);
3008        return tracesFile;
3009    }
3010
3011    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3012            ProcessStats processStats, SparseArray<Boolean> lastPids) {
3013        // Use a FileObserver to detect when traces finish writing.
3014        // The order of traces is considered important to maintain for legibility.
3015        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3016            public synchronized void onEvent(int event, String path) { notify(); }
3017        };
3018
3019        try {
3020            observer.startWatching();
3021
3022            // First collect all of the stacks of the most important pids.
3023            if (firstPids != null) {
3024                try {
3025                    int num = firstPids.size();
3026                    for (int i = 0; i < num; i++) {
3027                        synchronized (observer) {
3028                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3029                            observer.wait(200);  // Wait for write-close, give up after 200msec
3030                        }
3031                    }
3032                } catch (InterruptedException e) {
3033                    Log.wtf(TAG, e);
3034                }
3035            }
3036
3037            // Next measure CPU usage.
3038            if (processStats != null) {
3039                processStats.init();
3040                System.gc();
3041                processStats.update();
3042                try {
3043                    synchronized (processStats) {
3044                        processStats.wait(500); // measure over 1/2 second.
3045                    }
3046                } catch (InterruptedException e) {
3047                }
3048                processStats.update();
3049
3050                // We'll take the stack crawls of just the top apps using CPU.
3051                final int N = processStats.countWorkingStats();
3052                int numProcs = 0;
3053                for (int i=0; i<N && numProcs<5; i++) {
3054                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3055                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3056                        numProcs++;
3057                        try {
3058                            synchronized (observer) {
3059                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3060                                observer.wait(200);  // Wait for write-close, give up after 200msec
3061                            }
3062                        } catch (InterruptedException e) {
3063                            Log.wtf(TAG, e);
3064                        }
3065
3066                    }
3067                }
3068            }
3069
3070        } finally {
3071            observer.stopWatching();
3072        }
3073    }
3074
3075    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3076        if (true || IS_USER_BUILD) {
3077            return;
3078        }
3079        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3080        if (tracesPath == null || tracesPath.length() == 0) {
3081            return;
3082        }
3083
3084        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3085        StrictMode.allowThreadDiskWrites();
3086        try {
3087            final File tracesFile = new File(tracesPath);
3088            final File tracesDir = tracesFile.getParentFile();
3089            final File tracesTmp = new File(tracesDir, "__tmp__");
3090            try {
3091                if (!tracesDir.exists()) tracesFile.mkdirs();
3092                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3093
3094                if (tracesFile.exists()) {
3095                    tracesTmp.delete();
3096                    tracesFile.renameTo(tracesTmp);
3097                }
3098                StringBuilder sb = new StringBuilder();
3099                Time tobj = new Time();
3100                tobj.set(System.currentTimeMillis());
3101                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3102                sb.append(": ");
3103                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3104                sb.append(" since ");
3105                sb.append(msg);
3106                FileOutputStream fos = new FileOutputStream(tracesFile);
3107                fos.write(sb.toString().getBytes());
3108                if (app == null) {
3109                    fos.write("\n*** No application process!".getBytes());
3110                }
3111                fos.close();
3112                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3113            } catch (IOException e) {
3114                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3115                return;
3116            }
3117
3118            if (app != null) {
3119                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3120                firstPids.add(app.pid);
3121                dumpStackTraces(tracesPath, firstPids, null, null);
3122            }
3123
3124            File lastTracesFile = null;
3125            File curTracesFile = null;
3126            for (int i=9; i>=0; i--) {
3127                String name = String.format("slow%02d.txt", i);
3128                curTracesFile = new File(tracesDir, name);
3129                if (curTracesFile.exists()) {
3130                    if (lastTracesFile != null) {
3131                        curTracesFile.renameTo(lastTracesFile);
3132                    } else {
3133                        curTracesFile.delete();
3134                    }
3135                }
3136                lastTracesFile = curTracesFile;
3137            }
3138            tracesFile.renameTo(curTracesFile);
3139            if (tracesTmp.exists()) {
3140                tracesTmp.renameTo(tracesFile);
3141            }
3142        } finally {
3143            StrictMode.setThreadPolicy(oldPolicy);
3144        }
3145    }
3146
3147    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3148            ActivityRecord parent, final String annotation) {
3149        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3150        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3151
3152        if (mController != null) {
3153            try {
3154                // 0 == continue, -1 = kill process immediately
3155                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3156                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3157            } catch (RemoteException e) {
3158                mController = null;
3159            }
3160        }
3161
3162        long anrTime = SystemClock.uptimeMillis();
3163        if (MONITOR_CPU_USAGE) {
3164            updateCpuStatsNow();
3165        }
3166
3167        synchronized (this) {
3168            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3169            if (mShuttingDown) {
3170                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3171                return;
3172            } else if (app.notResponding) {
3173                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3174                return;
3175            } else if (app.crashing) {
3176                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3177                return;
3178            }
3179
3180            // In case we come through here for the same app before completing
3181            // this one, mark as anring now so we will bail out.
3182            app.notResponding = true;
3183
3184            // Log the ANR to the event log.
3185            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3186                    annotation);
3187
3188            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3189            firstPids.add(app.pid);
3190
3191            int parentPid = app.pid;
3192            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3193            if (parentPid != app.pid) firstPids.add(parentPid);
3194
3195            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3196
3197            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3198                ProcessRecord r = mLruProcesses.get(i);
3199                if (r != null && r.thread != null) {
3200                    int pid = r.pid;
3201                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3202                        if (r.persistent) {
3203                            firstPids.add(pid);
3204                        } else {
3205                            lastPids.put(pid, Boolean.TRUE);
3206                        }
3207                    }
3208                }
3209            }
3210        }
3211
3212        // Log the ANR to the main log.
3213        StringBuilder info = new StringBuilder();
3214        info.setLength(0);
3215        info.append("ANR in ").append(app.processName);
3216        if (activity != null && activity.shortComponentName != null) {
3217            info.append(" (").append(activity.shortComponentName).append(")");
3218        }
3219        info.append("\n");
3220        if (annotation != null) {
3221            info.append("Reason: ").append(annotation).append("\n");
3222        }
3223        if (parent != null && parent != activity) {
3224            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3225        }
3226
3227        final ProcessStats processStats = new ProcessStats(true);
3228
3229        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3230
3231        String cpuInfo = null;
3232        if (MONITOR_CPU_USAGE) {
3233            updateCpuStatsNow();
3234            synchronized (mProcessStatsThread) {
3235                cpuInfo = mProcessStats.printCurrentState(anrTime);
3236            }
3237            info.append(processStats.printCurrentLoad());
3238            info.append(cpuInfo);
3239        }
3240
3241        info.append(processStats.printCurrentState(anrTime));
3242
3243        Slog.e(TAG, info.toString());
3244        if (tracesFile == null) {
3245            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3246            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3247        }
3248
3249        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3250                cpuInfo, tracesFile, null);
3251
3252        if (mController != null) {
3253            try {
3254                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3255                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3256                if (res != 0) {
3257                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3258                    return;
3259                }
3260            } catch (RemoteException e) {
3261                mController = null;
3262            }
3263        }
3264
3265        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3266        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3267                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3268
3269        synchronized (this) {
3270            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3271                Slog.w(TAG, "Killing " + app + ": background ANR");
3272                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3273                        app.processName, app.setAdj, "background ANR");
3274                Process.killProcessQuiet(app.pid);
3275                return;
3276            }
3277
3278            // Set the app's notResponding state, and look up the errorReportReceiver
3279            makeAppNotRespondingLocked(app,
3280                    activity != null ? activity.shortComponentName : null,
3281                    annotation != null ? "ANR " + annotation : "ANR",
3282                    info.toString());
3283
3284            // Bring up the infamous App Not Responding dialog
3285            Message msg = Message.obtain();
3286            HashMap map = new HashMap();
3287            msg.what = SHOW_NOT_RESPONDING_MSG;
3288            msg.obj = map;
3289            map.put("app", app);
3290            if (activity != null) {
3291                map.put("activity", activity);
3292            }
3293
3294            mHandler.sendMessage(msg);
3295        }
3296    }
3297
3298    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3299        if (!mLaunchWarningShown) {
3300            mLaunchWarningShown = true;
3301            mHandler.post(new Runnable() {
3302                @Override
3303                public void run() {
3304                    synchronized (ActivityManagerService.this) {
3305                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3306                        d.show();
3307                        mHandler.postDelayed(new Runnable() {
3308                            @Override
3309                            public void run() {
3310                                synchronized (ActivityManagerService.this) {
3311                                    d.dismiss();
3312                                    mLaunchWarningShown = false;
3313                                }
3314                            }
3315                        }, 4000);
3316                    }
3317                }
3318            });
3319        }
3320    }
3321
3322    public boolean clearApplicationUserData(final String packageName,
3323            final IPackageDataObserver observer, final int userId) {
3324        enforceNotIsolatedCaller("clearApplicationUserData");
3325        int uid = Binder.getCallingUid();
3326        int pid = Binder.getCallingPid();
3327        long callingId = Binder.clearCallingIdentity();
3328        try {
3329            IPackageManager pm = AppGlobals.getPackageManager();
3330            int pkgUid = -1;
3331            synchronized(this) {
3332                try {
3333                    pkgUid = pm.getPackageUid(packageName, userId);
3334                } catch (RemoteException e) {
3335                }
3336                if (pkgUid == -1) {
3337                    Slog.w(TAG, "Invalid packageName:" + packageName);
3338                    return false;
3339                }
3340                if (uid == pkgUid || checkComponentPermission(
3341                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3342                        pid, uid, -1, true)
3343                        == PackageManager.PERMISSION_GRANTED) {
3344                    forceStopPackageLocked(packageName, pkgUid);
3345                } else {
3346                    throw new SecurityException(pid+" does not have permission:"+
3347                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3348                                    "for process:"+packageName);
3349                }
3350            }
3351
3352            try {
3353                //clear application user data
3354                pm.clearApplicationUserData(packageName, observer, userId);
3355                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3356                        Uri.fromParts("package", packageName, null));
3357                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3358                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3359                        null, null, 0, null, null, null, false, false, userId);
3360            } catch (RemoteException e) {
3361            }
3362        } finally {
3363            Binder.restoreCallingIdentity(callingId);
3364        }
3365        return true;
3366    }
3367
3368    public void killBackgroundProcesses(final String packageName) {
3369        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3370                != PackageManager.PERMISSION_GRANTED &&
3371                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3372                        != PackageManager.PERMISSION_GRANTED) {
3373            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3374                    + Binder.getCallingPid()
3375                    + ", uid=" + Binder.getCallingUid()
3376                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3377            Slog.w(TAG, msg);
3378            throw new SecurityException(msg);
3379        }
3380
3381        int userId = UserId.getCallingUserId();
3382        long callingId = Binder.clearCallingIdentity();
3383        try {
3384            IPackageManager pm = AppGlobals.getPackageManager();
3385            int pkgUid = -1;
3386            synchronized(this) {
3387                try {
3388                    pkgUid = pm.getPackageUid(packageName, userId);
3389                } catch (RemoteException e) {
3390                }
3391                if (pkgUid == -1) {
3392                    Slog.w(TAG, "Invalid packageName: " + packageName);
3393                    return;
3394                }
3395                killPackageProcessesLocked(packageName, pkgUid,
3396                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3397            }
3398        } finally {
3399            Binder.restoreCallingIdentity(callingId);
3400        }
3401    }
3402
3403    public void killAllBackgroundProcesses() {
3404        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3405                != PackageManager.PERMISSION_GRANTED) {
3406            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3407                    + Binder.getCallingPid()
3408                    + ", uid=" + Binder.getCallingUid()
3409                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3410            Slog.w(TAG, msg);
3411            throw new SecurityException(msg);
3412        }
3413
3414        long callingId = Binder.clearCallingIdentity();
3415        try {
3416            synchronized(this) {
3417                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3418                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3419                    final int NA = apps.size();
3420                    for (int ia=0; ia<NA; ia++) {
3421                        ProcessRecord app = apps.valueAt(ia);
3422                        if (app.persistent) {
3423                            // we don't kill persistent processes
3424                            continue;
3425                        }
3426                        if (app.removed) {
3427                            procs.add(app);
3428                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3429                            app.removed = true;
3430                            procs.add(app);
3431                        }
3432                    }
3433                }
3434
3435                int N = procs.size();
3436                for (int i=0; i<N; i++) {
3437                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3438                }
3439            }
3440        } finally {
3441            Binder.restoreCallingIdentity(callingId);
3442        }
3443    }
3444
3445    public void forceStopPackage(final String packageName) {
3446        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3447                != PackageManager.PERMISSION_GRANTED) {
3448            String msg = "Permission Denial: forceStopPackage() from pid="
3449                    + Binder.getCallingPid()
3450                    + ", uid=" + Binder.getCallingUid()
3451                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3452            Slog.w(TAG, msg);
3453            throw new SecurityException(msg);
3454        }
3455        final int userId = UserId.getCallingUserId();
3456        long callingId = Binder.clearCallingIdentity();
3457        try {
3458            IPackageManager pm = AppGlobals.getPackageManager();
3459            int pkgUid = -1;
3460            synchronized(this) {
3461                try {
3462                    pkgUid = pm.getPackageUid(packageName, userId);
3463                } catch (RemoteException e) {
3464                }
3465                if (pkgUid == -1) {
3466                    Slog.w(TAG, "Invalid packageName: " + packageName);
3467                    return;
3468                }
3469                forceStopPackageLocked(packageName, pkgUid);
3470                try {
3471                    pm.setPackageStoppedState(packageName, true, userId);
3472                } catch (RemoteException e) {
3473                } catch (IllegalArgumentException e) {
3474                    Slog.w(TAG, "Failed trying to unstop package "
3475                            + packageName + ": " + e);
3476                }
3477            }
3478        } finally {
3479            Binder.restoreCallingIdentity(callingId);
3480        }
3481    }
3482
3483    /*
3484     * The pkg name and uid have to be specified.
3485     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3486     */
3487    public void killApplicationWithUid(String pkg, int uid) {
3488        if (pkg == null) {
3489            return;
3490        }
3491        // Make sure the uid is valid.
3492        if (uid < 0) {
3493            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3494            return;
3495        }
3496        int callerUid = Binder.getCallingUid();
3497        // Only the system server can kill an application
3498        if (callerUid == Process.SYSTEM_UID) {
3499            // Post an aysnc message to kill the application
3500            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3501            msg.arg1 = uid;
3502            msg.arg2 = 0;
3503            msg.obj = pkg;
3504            mHandler.sendMessage(msg);
3505        } else {
3506            throw new SecurityException(callerUid + " cannot kill pkg: " +
3507                    pkg);
3508        }
3509    }
3510
3511    public void closeSystemDialogs(String reason) {
3512        enforceNotIsolatedCaller("closeSystemDialogs");
3513        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3514        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3515        if (reason != null) {
3516            intent.putExtra("reason", reason);
3517        }
3518
3519        final int uid = Binder.getCallingUid();
3520        final long origId = Binder.clearCallingIdentity();
3521        synchronized (this) {
3522            mWindowManager.closeSystemDialogs(reason);
3523
3524            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3525                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3526                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3527                    r.stack.finishActivityLocked(r, i,
3528                            Activity.RESULT_CANCELED, null, "close-sys");
3529                }
3530            }
3531
3532            broadcastIntentLocked(null, null, intent, null,
3533                    null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */);
3534        }
3535        Binder.restoreCallingIdentity(origId);
3536    }
3537
3538    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3539            throws RemoteException {
3540        enforceNotIsolatedCaller("getProcessMemoryInfo");
3541        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3542        for (int i=pids.length-1; i>=0; i--) {
3543            infos[i] = new Debug.MemoryInfo();
3544            Debug.getMemoryInfo(pids[i], infos[i]);
3545        }
3546        return infos;
3547    }
3548
3549    public long[] getProcessPss(int[] pids) throws RemoteException {
3550        enforceNotIsolatedCaller("getProcessPss");
3551        long[] pss = new long[pids.length];
3552        for (int i=pids.length-1; i>=0; i--) {
3553            pss[i] = Debug.getPss(pids[i]);
3554        }
3555        return pss;
3556    }
3557
3558    public void killApplicationProcess(String processName, int uid) {
3559        if (processName == null) {
3560            return;
3561        }
3562
3563        int callerUid = Binder.getCallingUid();
3564        // Only the system server can kill an application
3565        if (callerUid == Process.SYSTEM_UID) {
3566            synchronized (this) {
3567                ProcessRecord app = getProcessRecordLocked(processName, uid);
3568                if (app != null && app.thread != null) {
3569                    try {
3570                        app.thread.scheduleSuicide();
3571                    } catch (RemoteException e) {
3572                        // If the other end already died, then our work here is done.
3573                    }
3574                } else {
3575                    Slog.w(TAG, "Process/uid not found attempting kill of "
3576                            + processName + " / " + uid);
3577                }
3578            }
3579        } else {
3580            throw new SecurityException(callerUid + " cannot kill app process: " +
3581                    processName);
3582        }
3583    }
3584
3585    private void forceStopPackageLocked(final String packageName, int uid) {
3586        forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
3587        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3588                Uri.fromParts("package", packageName, null));
3589        if (!mProcessesReady) {
3590            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3591        }
3592        intent.putExtra(Intent.EXTRA_UID, uid);
3593        broadcastIntentLocked(null, null, intent,
3594                null, null, 0, null, null, null,
3595                false, false,
3596                MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
3597    }
3598
3599    private final boolean killPackageProcessesLocked(String packageName, int uid,
3600            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3601            boolean evenPersistent, String reason) {
3602        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3603
3604        // Remove all processes this package may have touched: all with the
3605        // same UID (except for the system or root user), and all whose name
3606        // matches the package name.
3607        final String procNamePrefix = packageName + ":";
3608        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3609            final int NA = apps.size();
3610            for (int ia=0; ia<NA; ia++) {
3611                ProcessRecord app = apps.valueAt(ia);
3612                if (app.persistent && !evenPersistent) {
3613                    // we don't kill persistent processes
3614                    continue;
3615                }
3616                if (app.removed) {
3617                    if (doit) {
3618                        procs.add(app);
3619                    }
3620                // If uid is specified and the uid and process name match
3621                // Or, the uid is not specified and the process name matches
3622                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3623                            || ((app.processName.equals(packageName)
3624                                 || app.processName.startsWith(procNamePrefix))
3625                                && uid < 0))) {
3626                    if (app.setAdj >= minOomAdj) {
3627                        if (!doit) {
3628                            return true;
3629                        }
3630                        app.removed = true;
3631                        procs.add(app);
3632                    }
3633                }
3634            }
3635        }
3636
3637        int N = procs.size();
3638        for (int i=0; i<N; i++) {
3639            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3640        }
3641        return N > 0;
3642    }
3643
3644    private final boolean forceStopPackageLocked(String name, int uid,
3645            boolean callerWillRestart, boolean purgeCache, boolean doit,
3646            boolean evenPersistent, int userId) {
3647        int i;
3648        int N;
3649
3650        if (uid < 0) {
3651            try {
3652                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3653            } catch (RemoteException e) {
3654            }
3655        }
3656
3657        if (doit) {
3658            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3659
3660            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3661            while (badApps.hasNext()) {
3662                SparseArray<Long> ba = badApps.next();
3663                if (ba.get(uid) != null) {
3664                    badApps.remove();
3665                }
3666            }
3667        }
3668
3669        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3670                callerWillRestart, false, doit, evenPersistent, "force stop");
3671
3672        TaskRecord lastTask = null;
3673        for (i=0; i<mMainStack.mHistory.size(); i++) {
3674            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3675            final boolean samePackage = r.packageName.equals(name);
3676            if (r.userId == userId
3677                    && (samePackage || r.task == lastTask)
3678                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3679                if (!doit) {
3680                    if (r.finishing) {
3681                        // If this activity is just finishing, then it is not
3682                        // interesting as far as something to stop.
3683                        continue;
3684                    }
3685                    return true;
3686                }
3687                didSomething = true;
3688                Slog.i(TAG, "  Force finishing activity " + r);
3689                if (samePackage) {
3690                    if (r.app != null) {
3691                        r.app.removed = true;
3692                    }
3693                    r.app = null;
3694                }
3695                lastTask = r.task;
3696                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3697                        null, "force-stop", true)) {
3698                    i--;
3699                }
3700            }
3701        }
3702
3703        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3704        for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
3705            if (service.packageName.equals(name)
3706                    && (service.app == null || evenPersistent || !service.app.persistent)) {
3707                if (!doit) {
3708                    return true;
3709                }
3710                didSomething = true;
3711                Slog.i(TAG, "  Force stopping service " + service);
3712                if (service.app != null) {
3713                    service.app.removed = true;
3714                }
3715                service.app = null;
3716                service.isolatedProc = null;
3717                services.add(service);
3718            }
3719        }
3720
3721        N = services.size();
3722        for (i=0; i<N; i++) {
3723            bringDownServiceLocked(services.get(i), true);
3724        }
3725
3726        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3727        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3728            if (provider.info.packageName.equals(name)
3729                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3730                if (!doit) {
3731                    return true;
3732                }
3733                didSomething = true;
3734                providers.add(provider);
3735            }
3736        }
3737
3738        N = providers.size();
3739        for (i=0; i<N; i++) {
3740            removeDyingProviderLocked(null, providers.get(i));
3741        }
3742
3743        if (doit) {
3744            if (purgeCache) {
3745                AttributeCache ac = AttributeCache.instance();
3746                if (ac != null) {
3747                    ac.removePackage(name);
3748                }
3749            }
3750            if (mBooted) {
3751                mMainStack.resumeTopActivityLocked(null);
3752                mMainStack.scheduleIdleLocked();
3753            }
3754        }
3755
3756        return didSomething;
3757    }
3758
3759    private final boolean removeProcessLocked(ProcessRecord app,
3760            boolean callerWillRestart, boolean allowRestart, String reason) {
3761        final String name = app.processName;
3762        final int uid = app.uid;
3763        if (DEBUG_PROCESSES) Slog.d(
3764            TAG, "Force removing proc " + app.toShortString() + " (" + name
3765            + "/" + uid + ")");
3766
3767        mProcessNames.remove(name, uid);
3768        mIsolatedProcesses.remove(app.uid);
3769        if (mHeavyWeightProcess == app) {
3770            mHeavyWeightProcess = null;
3771            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3772        }
3773        boolean needRestart = false;
3774        if (app.pid > 0 && app.pid != MY_PID) {
3775            int pid = app.pid;
3776            synchronized (mPidsSelfLocked) {
3777                mPidsSelfLocked.remove(pid);
3778                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3779            }
3780            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3781            handleAppDiedLocked(app, true, allowRestart);
3782            mLruProcesses.remove(app);
3783            Process.killProcessQuiet(pid);
3784
3785            if (app.persistent && !app.isolated) {
3786                if (!callerWillRestart) {
3787                    addAppLocked(app.info, false);
3788                } else {
3789                    needRestart = true;
3790                }
3791            }
3792        } else {
3793            mRemovedProcesses.add(app);
3794        }
3795
3796        return needRestart;
3797    }
3798
3799    private final void processStartTimedOutLocked(ProcessRecord app) {
3800        final int pid = app.pid;
3801        boolean gone = false;
3802        synchronized (mPidsSelfLocked) {
3803            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3804            if (knownApp != null && knownApp.thread == null) {
3805                mPidsSelfLocked.remove(pid);
3806                gone = true;
3807            }
3808        }
3809
3810        if (gone) {
3811            Slog.w(TAG, "Process " + app + " failed to attach");
3812            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3813                    app.processName);
3814            mProcessNames.remove(app.processName, app.uid);
3815            mIsolatedProcesses.remove(app.uid);
3816            if (mHeavyWeightProcess == app) {
3817                mHeavyWeightProcess = null;
3818                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3819            }
3820            // Take care of any launching providers waiting for this process.
3821            checkAppInLaunchingProvidersLocked(app, true);
3822            // Take care of any services that are waiting for the process.
3823            for (int i=0; i<mPendingServices.size(); i++) {
3824                ServiceRecord sr = mPendingServices.get(i);
3825                if ((app.uid == sr.appInfo.uid
3826                        && app.processName.equals(sr.processName))
3827                        || sr.isolatedProc == app) {
3828                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3829                    sr.isolatedProc = null;
3830                    mPendingServices.remove(i);
3831                    i--;
3832                    bringDownServiceLocked(sr, true);
3833                }
3834            }
3835            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3836                    app.processName, app.setAdj, "start timeout");
3837            Process.killProcessQuiet(pid);
3838            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3839                Slog.w(TAG, "Unattached app died before backup, skipping");
3840                try {
3841                    IBackupManager bm = IBackupManager.Stub.asInterface(
3842                            ServiceManager.getService(Context.BACKUP_SERVICE));
3843                    bm.agentDisconnected(app.info.packageName);
3844                } catch (RemoteException e) {
3845                    // Can't happen; the backup manager is local
3846                }
3847            }
3848            if (isPendingBroadcastProcessLocked(pid)) {
3849                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3850                skipPendingBroadcastLocked(pid);
3851            }
3852        } else {
3853            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3854        }
3855    }
3856
3857    private final boolean attachApplicationLocked(IApplicationThread thread,
3858            int pid) {
3859
3860        // Find the application record that is being attached...  either via
3861        // the pid if we are running in multiple processes, or just pull the
3862        // next app record if we are emulating process with anonymous threads.
3863        ProcessRecord app;
3864        if (pid != MY_PID && pid >= 0) {
3865            synchronized (mPidsSelfLocked) {
3866                app = mPidsSelfLocked.get(pid);
3867            }
3868        } else {
3869            app = null;
3870        }
3871
3872        if (app == null) {
3873            Slog.w(TAG, "No pending application record for pid " + pid
3874                    + " (IApplicationThread " + thread + "); dropping process");
3875            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3876            if (pid > 0 && pid != MY_PID) {
3877                Process.killProcessQuiet(pid);
3878            } else {
3879                try {
3880                    thread.scheduleExit();
3881                } catch (Exception e) {
3882                    // Ignore exceptions.
3883                }
3884            }
3885            return false;
3886        }
3887
3888        // If this application record is still attached to a previous
3889        // process, clean it up now.
3890        if (app.thread != null) {
3891            handleAppDiedLocked(app, true, true);
3892        }
3893
3894        // Tell the process all about itself.
3895
3896        if (localLOGV) Slog.v(
3897                TAG, "Binding process pid " + pid + " to record " + app);
3898
3899        String processName = app.processName;
3900        try {
3901            AppDeathRecipient adr = new AppDeathRecipient(
3902                    app, pid, thread);
3903            thread.asBinder().linkToDeath(adr, 0);
3904            app.deathRecipient = adr;
3905        } catch (RemoteException e) {
3906            app.resetPackageList();
3907            startProcessLocked(app, "link fail", processName);
3908            return false;
3909        }
3910
3911        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3912
3913        app.thread = thread;
3914        app.curAdj = app.setAdj = -100;
3915        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3916        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3917        app.forcingToForeground = null;
3918        app.foregroundServices = false;
3919        app.hasShownUi = false;
3920        app.debugging = false;
3921
3922        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3923
3924        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3925        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3926
3927        if (!normalMode) {
3928            Slog.i(TAG, "Launching preboot mode app: " + app);
3929        }
3930
3931        if (localLOGV) Slog.v(
3932            TAG, "New app record " + app
3933            + " thread=" + thread.asBinder() + " pid=" + pid);
3934        try {
3935            int testMode = IApplicationThread.DEBUG_OFF;
3936            if (mDebugApp != null && mDebugApp.equals(processName)) {
3937                testMode = mWaitForDebugger
3938                    ? IApplicationThread.DEBUG_WAIT
3939                    : IApplicationThread.DEBUG_ON;
3940                app.debugging = true;
3941                if (mDebugTransient) {
3942                    mDebugApp = mOrigDebugApp;
3943                    mWaitForDebugger = mOrigWaitForDebugger;
3944                }
3945            }
3946            String profileFile = app.instrumentationProfileFile;
3947            ParcelFileDescriptor profileFd = null;
3948            boolean profileAutoStop = false;
3949            if (mProfileApp != null && mProfileApp.equals(processName)) {
3950                mProfileProc = app;
3951                profileFile = mProfileFile;
3952                profileFd = mProfileFd;
3953                profileAutoStop = mAutoStopProfiler;
3954            }
3955            boolean enableOpenGlTrace = false;
3956            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3957                enableOpenGlTrace = true;
3958                mOpenGlTraceApp = null;
3959            }
3960
3961            // If the app is being launched for restore or full backup, set it up specially
3962            boolean isRestrictedBackupMode = false;
3963            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3964                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3965                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3966                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3967            }
3968
3969            ensurePackageDexOpt(app.instrumentationInfo != null
3970                    ? app.instrumentationInfo.packageName
3971                    : app.info.packageName);
3972            if (app.instrumentationClass != null) {
3973                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3974            }
3975            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3976                    + processName + " with config " + mConfiguration);
3977            ApplicationInfo appInfo = app.instrumentationInfo != null
3978                    ? app.instrumentationInfo : app.info;
3979            app.compat = compatibilityInfoForPackageLocked(appInfo);
3980            if (profileFd != null) {
3981                profileFd = profileFd.dup();
3982            }
3983            thread.bindApplication(processName, appInfo, providers,
3984                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
3985                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3986                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
3987                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
3988                    mCoreSettingsObserver.getCoreSettingsLocked());
3989            updateLruProcessLocked(app, false, true);
3990            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
3991        } catch (Exception e) {
3992            // todo: Yikes!  What should we do?  For now we will try to
3993            // start another process, but that could easily get us in
3994            // an infinite loop of restarting processes...
3995            Slog.w(TAG, "Exception thrown during bind!", e);
3996
3997            app.resetPackageList();
3998            app.unlinkDeathRecipient();
3999            startProcessLocked(app, "bind fail", processName);
4000            return false;
4001        }
4002
4003        // Remove this record from the list of starting applications.
4004        mPersistentStartingProcesses.remove(app);
4005        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4006                "Attach application locked removing on hold: " + app);
4007        mProcessesOnHold.remove(app);
4008
4009        boolean badApp = false;
4010        boolean didSomething = false;
4011
4012        // See if the top visible activity is waiting to run in this process...
4013        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4014        if (hr != null && normalMode) {
4015            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4016                    && processName.equals(hr.processName)) {
4017                try {
4018                    if (mHeadless) {
4019                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4020                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4021                        didSomething = true;
4022                    }
4023                } catch (Exception e) {
4024                    Slog.w(TAG, "Exception in new application when starting activity "
4025                          + hr.intent.getComponent().flattenToShortString(), e);
4026                    badApp = true;
4027                }
4028            } else {
4029                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4030            }
4031        }
4032
4033        // Find any services that should be running in this process...
4034        if (!badApp && mPendingServices.size() > 0) {
4035            ServiceRecord sr = null;
4036            try {
4037                for (int i=0; i<mPendingServices.size(); i++) {
4038                    sr = mPendingServices.get(i);
4039                    if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4040                            || !processName.equals(sr.processName))) {
4041                        continue;
4042                    }
4043
4044                    mPendingServices.remove(i);
4045                    i--;
4046                    realStartServiceLocked(sr, app);
4047                    didSomething = true;
4048                }
4049            } catch (Exception e) {
4050                Slog.w(TAG, "Exception in new application when starting service "
4051                      + sr.shortName, e);
4052                badApp = true;
4053            }
4054        }
4055
4056        // Check if a next-broadcast receiver is in this process...
4057        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4058            try {
4059                didSomething = sendPendingBroadcastsLocked(app);
4060            } catch (Exception e) {
4061                // If the app died trying to launch the receiver we declare it 'bad'
4062                badApp = true;
4063            }
4064        }
4065
4066        // Check whether the next backup agent is in this process...
4067        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4068            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4069            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4070            try {
4071                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4072                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4073                        mBackupTarget.backupMode);
4074            } catch (Exception e) {
4075                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4076                e.printStackTrace();
4077            }
4078        }
4079
4080        if (badApp) {
4081            // todo: Also need to kill application to deal with all
4082            // kinds of exceptions.
4083            handleAppDiedLocked(app, false, true);
4084            return false;
4085        }
4086
4087        if (!didSomething) {
4088            updateOomAdjLocked();
4089        }
4090
4091        return true;
4092    }
4093
4094    public final void attachApplication(IApplicationThread thread) {
4095        synchronized (this) {
4096            int callingPid = Binder.getCallingPid();
4097            final long origId = Binder.clearCallingIdentity();
4098            attachApplicationLocked(thread, callingPid);
4099            Binder.restoreCallingIdentity(origId);
4100        }
4101    }
4102
4103    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4104        final long origId = Binder.clearCallingIdentity();
4105        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4106        if (stopProfiling) {
4107            synchronized (this) {
4108                if (mProfileProc == r.app) {
4109                    if (mProfileFd != null) {
4110                        try {
4111                            mProfileFd.close();
4112                        } catch (IOException e) {
4113                        }
4114                        clearProfilerLocked();
4115                    }
4116                }
4117            }
4118        }
4119        Binder.restoreCallingIdentity(origId);
4120    }
4121
4122    void enableScreenAfterBoot() {
4123        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4124                SystemClock.uptimeMillis());
4125        mWindowManager.enableScreenAfterBoot();
4126
4127        synchronized (this) {
4128            updateEventDispatchingLocked();
4129        }
4130    }
4131
4132    public void showBootMessage(final CharSequence msg, final boolean always) {
4133        enforceNotIsolatedCaller("showBootMessage");
4134        mWindowManager.showBootMessage(msg, always);
4135    }
4136
4137    public void dismissKeyguardOnNextActivity() {
4138        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4139        final long token = Binder.clearCallingIdentity();
4140        try {
4141            synchronized (this) {
4142                if (mLockScreenShown) {
4143                    mLockScreenShown = false;
4144                    comeOutOfSleepIfNeededLocked();
4145                }
4146                mMainStack.dismissKeyguardOnNextActivityLocked();
4147            }
4148        } finally {
4149            Binder.restoreCallingIdentity(token);
4150        }
4151    }
4152
4153    final void finishBooting() {
4154        IntentFilter pkgFilter = new IntentFilter();
4155        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4156        pkgFilter.addDataScheme("package");
4157        mContext.registerReceiver(new BroadcastReceiver() {
4158            @Override
4159            public void onReceive(Context context, Intent intent) {
4160                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4161                if (pkgs != null) {
4162                    for (String pkg : pkgs) {
4163                        synchronized (ActivityManagerService.this) {
4164                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4165                                setResultCode(Activity.RESULT_OK);
4166                                return;
4167                            }
4168                        }
4169                    }
4170                }
4171            }
4172        }, pkgFilter);
4173
4174        IntentFilter userFilter = new IntentFilter();
4175        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4176        mContext.registerReceiver(new BroadcastReceiver() {
4177            @Override
4178            public void onReceive(Context context, Intent intent) {
4179                onUserRemoved(intent);
4180            }
4181        }, userFilter);
4182
4183        synchronized (this) {
4184            // Ensure that any processes we had put on hold are now started
4185            // up.
4186            final int NP = mProcessesOnHold.size();
4187            if (NP > 0) {
4188                ArrayList<ProcessRecord> procs =
4189                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4190                for (int ip=0; ip<NP; ip++) {
4191                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4192                            + procs.get(ip));
4193                    startProcessLocked(procs.get(ip), "on-hold", null);
4194                }
4195            }
4196
4197            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4198                // Start looking for apps that are abusing wake locks.
4199                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4200                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4201                // Tell anyone interested that we are done booting!
4202                SystemProperties.set("sys.boot_completed", "1");
4203                SystemProperties.set("dev.bootcomplete", "1");
4204                /* TODO: Send this to all users that are to be logged in on startup */
4205                broadcastIntentLocked(null, null,
4206                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4207                        null, null, 0, null, null,
4208                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4209                        false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
4210            }
4211        }
4212    }
4213
4214    final void ensureBootCompleted() {
4215        boolean booting;
4216        boolean enableScreen;
4217        synchronized (this) {
4218            booting = mBooting;
4219            mBooting = false;
4220            enableScreen = !mBooted;
4221            mBooted = true;
4222        }
4223
4224        if (booting) {
4225            finishBooting();
4226        }
4227
4228        if (enableScreen) {
4229            enableScreenAfterBoot();
4230        }
4231    }
4232
4233    public final void activityPaused(IBinder token) {
4234        final long origId = Binder.clearCallingIdentity();
4235        mMainStack.activityPaused(token, false);
4236        Binder.restoreCallingIdentity(origId);
4237    }
4238
4239    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4240            CharSequence description) {
4241        if (localLOGV) Slog.v(
4242            TAG, "Activity stopped: token=" + token);
4243
4244        // Refuse possible leaked file descriptors
4245        if (icicle != null && icicle.hasFileDescriptors()) {
4246            throw new IllegalArgumentException("File descriptors passed in Bundle");
4247        }
4248
4249        ActivityRecord r = null;
4250
4251        final long origId = Binder.clearCallingIdentity();
4252
4253        synchronized (this) {
4254            r = mMainStack.isInStackLocked(token);
4255            if (r != null) {
4256                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4257            }
4258        }
4259
4260        if (r != null) {
4261            sendPendingThumbnail(r, null, null, null, false);
4262        }
4263
4264        trimApplications();
4265
4266        Binder.restoreCallingIdentity(origId);
4267    }
4268
4269    public final void activityDestroyed(IBinder token) {
4270        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4271        mMainStack.activityDestroyed(token);
4272    }
4273
4274    public String getCallingPackage(IBinder token) {
4275        synchronized (this) {
4276            ActivityRecord r = getCallingRecordLocked(token);
4277            return r != null && r.app != null ? r.info.packageName : null;
4278        }
4279    }
4280
4281    public ComponentName getCallingActivity(IBinder token) {
4282        synchronized (this) {
4283            ActivityRecord r = getCallingRecordLocked(token);
4284            return r != null ? r.intent.getComponent() : null;
4285        }
4286    }
4287
4288    private ActivityRecord getCallingRecordLocked(IBinder token) {
4289        ActivityRecord r = mMainStack.isInStackLocked(token);
4290        if (r == null) {
4291            return null;
4292        }
4293        return r.resultTo;
4294    }
4295
4296    public ComponentName getActivityClassForToken(IBinder token) {
4297        synchronized(this) {
4298            ActivityRecord r = mMainStack.isInStackLocked(token);
4299            if (r == null) {
4300                return null;
4301            }
4302            return r.intent.getComponent();
4303        }
4304    }
4305
4306    public String getPackageForToken(IBinder token) {
4307        synchronized(this) {
4308            ActivityRecord r = mMainStack.isInStackLocked(token);
4309            if (r == null) {
4310                return null;
4311            }
4312            return r.packageName;
4313        }
4314    }
4315
4316    public IIntentSender getIntentSender(int type,
4317            String packageName, IBinder token, String resultWho,
4318            int requestCode, Intent[] intents, String[] resolvedTypes,
4319            int flags, Bundle options) {
4320        enforceNotIsolatedCaller("getIntentSender");
4321        // Refuse possible leaked file descriptors
4322        if (intents != null) {
4323            if (intents.length < 1) {
4324                throw new IllegalArgumentException("Intents array length must be >= 1");
4325            }
4326            for (int i=0; i<intents.length; i++) {
4327                Intent intent = intents[i];
4328                if (intent != null) {
4329                    if (intent.hasFileDescriptors()) {
4330                        throw new IllegalArgumentException("File descriptors passed in Intent");
4331                    }
4332                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4333                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4334                        throw new IllegalArgumentException(
4335                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4336                    }
4337                    intents[i] = new Intent(intent);
4338                }
4339            }
4340            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4341                throw new IllegalArgumentException(
4342                        "Intent array length does not match resolvedTypes length");
4343            }
4344        }
4345        if (options != null) {
4346            if (options.hasFileDescriptors()) {
4347                throw new IllegalArgumentException("File descriptors passed in options");
4348            }
4349        }
4350
4351        synchronized(this) {
4352            int callingUid = Binder.getCallingUid();
4353            try {
4354                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4355                    int uid = AppGlobals.getPackageManager()
4356                            .getPackageUid(packageName, UserId.getUserId(callingUid));
4357                    if (!UserId.isSameApp(callingUid, uid)) {
4358                        String msg = "Permission Denial: getIntentSender() from pid="
4359                            + Binder.getCallingPid()
4360                            + ", uid=" + Binder.getCallingUid()
4361                            + ", (need uid=" + uid + ")"
4362                            + " is not allowed to send as package " + packageName;
4363                        Slog.w(TAG, msg);
4364                        throw new SecurityException(msg);
4365                    }
4366                }
4367
4368                if (DEBUG_MU)
4369                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4370                            + Binder.getOrigCallingUid());
4371                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4372                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4373
4374            } catch (RemoteException e) {
4375                throw new SecurityException(e);
4376            }
4377        }
4378    }
4379
4380    IIntentSender getIntentSenderLocked(int type,
4381            String packageName, int callingUid, IBinder token, String resultWho,
4382            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4383            Bundle options) {
4384        if (DEBUG_MU)
4385            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4386        ActivityRecord activity = null;
4387        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4388            activity = mMainStack.isInStackLocked(token);
4389            if (activity == null) {
4390                return null;
4391            }
4392            if (activity.finishing) {
4393                return null;
4394            }
4395        }
4396
4397        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4398        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4399        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4400        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4401                |PendingIntent.FLAG_UPDATE_CURRENT);
4402
4403        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4404                type, packageName, activity, resultWho,
4405                requestCode, intents, resolvedTypes, flags, options);
4406        WeakReference<PendingIntentRecord> ref;
4407        ref = mIntentSenderRecords.get(key);
4408        PendingIntentRecord rec = ref != null ? ref.get() : null;
4409        if (rec != null) {
4410            if (!cancelCurrent) {
4411                if (updateCurrent) {
4412                    if (rec.key.requestIntent != null) {
4413                        rec.key.requestIntent.replaceExtras(intents != null ?
4414                                intents[intents.length - 1] : null);
4415                    }
4416                    if (intents != null) {
4417                        intents[intents.length-1] = rec.key.requestIntent;
4418                        rec.key.allIntents = intents;
4419                        rec.key.allResolvedTypes = resolvedTypes;
4420                    } else {
4421                        rec.key.allIntents = null;
4422                        rec.key.allResolvedTypes = null;
4423                    }
4424                }
4425                return rec;
4426            }
4427            rec.canceled = true;
4428            mIntentSenderRecords.remove(key);
4429        }
4430        if (noCreate) {
4431            return rec;
4432        }
4433        rec = new PendingIntentRecord(this, key, callingUid);
4434        mIntentSenderRecords.put(key, rec.ref);
4435        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4436            if (activity.pendingResults == null) {
4437                activity.pendingResults
4438                        = new HashSet<WeakReference<PendingIntentRecord>>();
4439            }
4440            activity.pendingResults.add(rec.ref);
4441        }
4442        return rec;
4443    }
4444
4445    public void cancelIntentSender(IIntentSender sender) {
4446        if (!(sender instanceof PendingIntentRecord)) {
4447            return;
4448        }
4449        synchronized(this) {
4450            PendingIntentRecord rec = (PendingIntentRecord)sender;
4451            try {
4452                int uid = AppGlobals.getPackageManager()
4453                        .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
4454                if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
4455                    String msg = "Permission Denial: cancelIntentSender() from pid="
4456                        + Binder.getCallingPid()
4457                        + ", uid=" + Binder.getCallingUid()
4458                        + " is not allowed to cancel packges "
4459                        + rec.key.packageName;
4460                    Slog.w(TAG, msg);
4461                    throw new SecurityException(msg);
4462                }
4463            } catch (RemoteException e) {
4464                throw new SecurityException(e);
4465            }
4466            cancelIntentSenderLocked(rec, true);
4467        }
4468    }
4469
4470    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4471        rec.canceled = true;
4472        mIntentSenderRecords.remove(rec.key);
4473        if (cleanActivity && rec.key.activity != null) {
4474            rec.key.activity.pendingResults.remove(rec.ref);
4475        }
4476    }
4477
4478    public String getPackageForIntentSender(IIntentSender pendingResult) {
4479        if (!(pendingResult instanceof PendingIntentRecord)) {
4480            return null;
4481        }
4482        try {
4483            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4484            return res.key.packageName;
4485        } catch (ClassCastException e) {
4486        }
4487        return null;
4488    }
4489
4490    public int getUidForIntentSender(IIntentSender sender) {
4491        if (sender instanceof PendingIntentRecord) {
4492            try {
4493                PendingIntentRecord res = (PendingIntentRecord)sender;
4494                return res.uid;
4495            } catch (ClassCastException e) {
4496            }
4497        }
4498        return -1;
4499    }
4500
4501    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4502        if (!(pendingResult instanceof PendingIntentRecord)) {
4503            return false;
4504        }
4505        try {
4506            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4507            if (res.key.allIntents == null) {
4508                return false;
4509            }
4510            for (int i=0; i<res.key.allIntents.length; i++) {
4511                Intent intent = res.key.allIntents[i];
4512                if (intent.getPackage() != null && intent.getComponent() != null) {
4513                    return false;
4514                }
4515            }
4516            return true;
4517        } catch (ClassCastException e) {
4518        }
4519        return false;
4520    }
4521
4522    public void setProcessLimit(int max) {
4523        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4524                "setProcessLimit()");
4525        synchronized (this) {
4526            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4527            mProcessLimitOverride = max;
4528        }
4529        trimApplications();
4530    }
4531
4532    public int getProcessLimit() {
4533        synchronized (this) {
4534            return mProcessLimitOverride;
4535        }
4536    }
4537
4538    void foregroundTokenDied(ForegroundToken token) {
4539        synchronized (ActivityManagerService.this) {
4540            synchronized (mPidsSelfLocked) {
4541                ForegroundToken cur
4542                    = mForegroundProcesses.get(token.pid);
4543                if (cur != token) {
4544                    return;
4545                }
4546                mForegroundProcesses.remove(token.pid);
4547                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4548                if (pr == null) {
4549                    return;
4550                }
4551                pr.forcingToForeground = null;
4552                pr.foregroundServices = false;
4553            }
4554            updateOomAdjLocked();
4555        }
4556    }
4557
4558    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4559        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4560                "setProcessForeground()");
4561        synchronized(this) {
4562            boolean changed = false;
4563
4564            synchronized (mPidsSelfLocked) {
4565                ProcessRecord pr = mPidsSelfLocked.get(pid);
4566                if (pr == null && isForeground) {
4567                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4568                    return;
4569                }
4570                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4571                if (oldToken != null) {
4572                    oldToken.token.unlinkToDeath(oldToken, 0);
4573                    mForegroundProcesses.remove(pid);
4574                    if (pr != null) {
4575                        pr.forcingToForeground = null;
4576                    }
4577                    changed = true;
4578                }
4579                if (isForeground && token != null) {
4580                    ForegroundToken newToken = new ForegroundToken() {
4581                        public void binderDied() {
4582                            foregroundTokenDied(this);
4583                        }
4584                    };
4585                    newToken.pid = pid;
4586                    newToken.token = token;
4587                    try {
4588                        token.linkToDeath(newToken, 0);
4589                        mForegroundProcesses.put(pid, newToken);
4590                        pr.forcingToForeground = token;
4591                        changed = true;
4592                    } catch (RemoteException e) {
4593                        // If the process died while doing this, we will later
4594                        // do the cleanup with the process death link.
4595                    }
4596                }
4597            }
4598
4599            if (changed) {
4600                updateOomAdjLocked();
4601            }
4602        }
4603    }
4604
4605    // =========================================================
4606    // PERMISSIONS
4607    // =========================================================
4608
4609    static class PermissionController extends IPermissionController.Stub {
4610        ActivityManagerService mActivityManagerService;
4611        PermissionController(ActivityManagerService activityManagerService) {
4612            mActivityManagerService = activityManagerService;
4613        }
4614
4615        public boolean checkPermission(String permission, int pid, int uid) {
4616            return mActivityManagerService.checkPermission(permission, pid,
4617                    uid) == PackageManager.PERMISSION_GRANTED;
4618        }
4619    }
4620
4621    /**
4622     * This can be called with or without the global lock held.
4623     */
4624    int checkComponentPermission(String permission, int pid, int uid,
4625            int owningUid, boolean exported) {
4626        // We might be performing an operation on behalf of an indirect binder
4627        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4628        // client identity accordingly before proceeding.
4629        Identity tlsIdentity = sCallerIdentity.get();
4630        if (tlsIdentity != null) {
4631            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4632                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4633            uid = tlsIdentity.uid;
4634            pid = tlsIdentity.pid;
4635        }
4636
4637        // Root, system server and our own process get to do everything.
4638        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
4639            return PackageManager.PERMISSION_GRANTED;
4640        }
4641        // Isolated processes don't get any permissions.
4642        if (UserId.isIsolated(uid)) {
4643            return PackageManager.PERMISSION_DENIED;
4644        }
4645        // If there is a uid that owns whatever is being accessed, it has
4646        // blanket access to it regardless of the permissions it requires.
4647        if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) {
4648            return PackageManager.PERMISSION_GRANTED;
4649        }
4650        // If the target is not exported, then nobody else can get to it.
4651        if (!exported) {
4652            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
4653            return PackageManager.PERMISSION_DENIED;
4654        }
4655        if (permission == null) {
4656            return PackageManager.PERMISSION_GRANTED;
4657        }
4658        try {
4659            return AppGlobals.getPackageManager()
4660                    .checkUidPermission(permission, uid);
4661        } catch (RemoteException e) {
4662            // Should never happen, but if it does... deny!
4663            Slog.e(TAG, "PackageManager is dead?!?", e);
4664        }
4665        return PackageManager.PERMISSION_DENIED;
4666    }
4667
4668    /**
4669     * As the only public entry point for permissions checking, this method
4670     * can enforce the semantic that requesting a check on a null global
4671     * permission is automatically denied.  (Internally a null permission
4672     * string is used when calling {@link #checkComponentPermission} in cases
4673     * when only uid-based security is needed.)
4674     *
4675     * This can be called with or without the global lock held.
4676     */
4677    public int checkPermission(String permission, int pid, int uid) {
4678        if (permission == null) {
4679            return PackageManager.PERMISSION_DENIED;
4680        }
4681        return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
4682    }
4683
4684    /**
4685     * Binder IPC calls go through the public entry point.
4686     * This can be called with or without the global lock held.
4687     */
4688    int checkCallingPermission(String permission) {
4689        return checkPermission(permission,
4690                Binder.getCallingPid(),
4691                UserId.getAppId(Binder.getCallingUid()));
4692    }
4693
4694    /**
4695     * This can be called with or without the global lock held.
4696     */
4697    void enforceCallingPermission(String permission, String func) {
4698        if (checkCallingPermission(permission)
4699                == PackageManager.PERMISSION_GRANTED) {
4700            return;
4701        }
4702
4703        String msg = "Permission Denial: " + func + " from pid="
4704                + Binder.getCallingPid()
4705                + ", uid=" + Binder.getCallingUid()
4706                + " requires " + permission;
4707        Slog.w(TAG, msg);
4708        throw new SecurityException(msg);
4709    }
4710
4711    /**
4712     * Determine if UID is holding permissions required to access {@link Uri} in
4713     * the given {@link ProviderInfo}. Final permission checking is always done
4714     * in {@link ContentProvider}.
4715     */
4716    private final boolean checkHoldingPermissionsLocked(
4717            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4718        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4719                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4720
4721        if (pi.applicationInfo.uid == uid) {
4722            return true;
4723        } else if (!pi.exported) {
4724            return false;
4725        }
4726
4727        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4728        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4729        try {
4730            // check if target holds top-level <provider> permissions
4731            if (!readMet && pi.readPermission != null
4732                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4733                readMet = true;
4734            }
4735            if (!writeMet && pi.writePermission != null
4736                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4737                writeMet = true;
4738            }
4739
4740            // track if unprotected read/write is allowed; any denied
4741            // <path-permission> below removes this ability
4742            boolean allowDefaultRead = pi.readPermission == null;
4743            boolean allowDefaultWrite = pi.writePermission == null;
4744
4745            // check if target holds any <path-permission> that match uri
4746            final PathPermission[] pps = pi.pathPermissions;
4747            if (pps != null) {
4748                final String path = uri.getPath();
4749                int i = pps.length;
4750                while (i > 0 && (!readMet || !writeMet)) {
4751                    i--;
4752                    PathPermission pp = pps[i];
4753                    if (pp.match(path)) {
4754                        if (!readMet) {
4755                            final String pprperm = pp.getReadPermission();
4756                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4757                                    + pprperm + " for " + pp.getPath()
4758                                    + ": match=" + pp.match(path)
4759                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4760                            if (pprperm != null) {
4761                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4762                                    readMet = true;
4763                                } else {
4764                                    allowDefaultRead = false;
4765                                }
4766                            }
4767                        }
4768                        if (!writeMet) {
4769                            final String ppwperm = pp.getWritePermission();
4770                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4771                                    + ppwperm + " for " + pp.getPath()
4772                                    + ": match=" + pp.match(path)
4773                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4774                            if (ppwperm != null) {
4775                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4776                                    writeMet = true;
4777                                } else {
4778                                    allowDefaultWrite = false;
4779                                }
4780                            }
4781                        }
4782                    }
4783                }
4784            }
4785
4786            // grant unprotected <provider> read/write, if not blocked by
4787            // <path-permission> above
4788            if (allowDefaultRead) readMet = true;
4789            if (allowDefaultWrite) writeMet = true;
4790
4791        } catch (RemoteException e) {
4792            return false;
4793        }
4794
4795        return readMet && writeMet;
4796    }
4797
4798    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4799            int modeFlags) {
4800        // Root gets to do everything.
4801        if (uid == 0) {
4802            return true;
4803        }
4804        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4805        if (perms == null) return false;
4806        UriPermission perm = perms.get(uri);
4807        if (perm == null) return false;
4808        return (modeFlags&perm.modeFlags) == modeFlags;
4809    }
4810
4811    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4812        enforceNotIsolatedCaller("checkUriPermission");
4813
4814        // Another redirected-binder-call permissions check as in
4815        // {@link checkComponentPermission}.
4816        Identity tlsIdentity = sCallerIdentity.get();
4817        if (tlsIdentity != null) {
4818            uid = tlsIdentity.uid;
4819            pid = tlsIdentity.pid;
4820        }
4821
4822        uid = UserId.getAppId(uid);
4823        // Our own process gets to do everything.
4824        if (pid == MY_PID) {
4825            return PackageManager.PERMISSION_GRANTED;
4826        }
4827        synchronized(this) {
4828            return checkUriPermissionLocked(uri, uid, modeFlags)
4829                    ? PackageManager.PERMISSION_GRANTED
4830                    : PackageManager.PERMISSION_DENIED;
4831        }
4832    }
4833
4834    /**
4835     * Check if the targetPkg can be granted permission to access uri by
4836     * the callingUid using the given modeFlags.  Throws a security exception
4837     * if callingUid is not allowed to do this.  Returns the uid of the target
4838     * if the URI permission grant should be performed; returns -1 if it is not
4839     * needed (for example targetPkg already has permission to access the URI).
4840     * If you already know the uid of the target, you can supply it in
4841     * lastTargetUid else set that to -1.
4842     */
4843    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4844            Uri uri, int modeFlags, int lastTargetUid) {
4845        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4846                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4847        if (modeFlags == 0) {
4848            return -1;
4849        }
4850
4851        if (targetPkg != null) {
4852            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4853                    "Checking grant " + targetPkg + " permission to " + uri);
4854        }
4855
4856        final IPackageManager pm = AppGlobals.getPackageManager();
4857
4858        // If this is not a content: uri, we can't do anything with it.
4859        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4860            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4861                    "Can't grant URI permission for non-content URI: " + uri);
4862            return -1;
4863        }
4864
4865        String name = uri.getAuthority();
4866        ProviderInfo pi = null;
4867        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4868                UserId.getUserId(callingUid));
4869        if (cpr != null) {
4870            pi = cpr.info;
4871        } else {
4872            try {
4873                pi = pm.resolveContentProvider(name,
4874                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
4875            } catch (RemoteException ex) {
4876            }
4877        }
4878        if (pi == null) {
4879            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4880            return -1;
4881        }
4882
4883        int targetUid = lastTargetUid;
4884        if (targetUid < 0 && targetPkg != null) {
4885            try {
4886                targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
4887                if (targetUid < 0) {
4888                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4889                            "Can't grant URI permission no uid for: " + targetPkg);
4890                    return -1;
4891                }
4892            } catch (RemoteException ex) {
4893                return -1;
4894            }
4895        }
4896
4897        if (targetUid >= 0) {
4898            // First...  does the target actually need this permission?
4899            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4900                // No need to grant the target this permission.
4901                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4902                        "Target " + targetPkg + " already has full permission to " + uri);
4903                return -1;
4904            }
4905        } else {
4906            // First...  there is no target package, so can anyone access it?
4907            boolean allowed = pi.exported;
4908            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4909                if (pi.readPermission != null) {
4910                    allowed = false;
4911                }
4912            }
4913            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4914                if (pi.writePermission != null) {
4915                    allowed = false;
4916                }
4917            }
4918            if (allowed) {
4919                return -1;
4920            }
4921        }
4922
4923        // Second...  is the provider allowing granting of URI permissions?
4924        if (!pi.grantUriPermissions) {
4925            throw new SecurityException("Provider " + pi.packageName
4926                    + "/" + pi.name
4927                    + " does not allow granting of Uri permissions (uri "
4928                    + uri + ")");
4929        }
4930        if (pi.uriPermissionPatterns != null) {
4931            final int N = pi.uriPermissionPatterns.length;
4932            boolean allowed = false;
4933            for (int i=0; i<N; i++) {
4934                if (pi.uriPermissionPatterns[i] != null
4935                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4936                    allowed = true;
4937                    break;
4938                }
4939            }
4940            if (!allowed) {
4941                throw new SecurityException("Provider " + pi.packageName
4942                        + "/" + pi.name
4943                        + " does not allow granting of permission to path of Uri "
4944                        + uri);
4945            }
4946        }
4947
4948        // Third...  does the caller itself have permission to access
4949        // this uri?
4950        if (callingUid != Process.myUid()) {
4951            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4952                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4953                    throw new SecurityException("Uid " + callingUid
4954                            + " does not have permission to uri " + uri);
4955                }
4956            }
4957        }
4958
4959        return targetUid;
4960    }
4961
4962    public int checkGrantUriPermission(int callingUid, String targetPkg,
4963            Uri uri, int modeFlags) {
4964        enforceNotIsolatedCaller("checkGrantUriPermission");
4965        synchronized(this) {
4966            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4967        }
4968    }
4969
4970    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4971            Uri uri, int modeFlags, UriPermissionOwner owner) {
4972        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4973                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4974        if (modeFlags == 0) {
4975            return;
4976        }
4977
4978        // So here we are: the caller has the assumed permission
4979        // to the uri, and the target doesn't.  Let's now give this to
4980        // the target.
4981
4982        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4983                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4984
4985        HashMap<Uri, UriPermission> targetUris
4986                = mGrantedUriPermissions.get(targetUid);
4987        if (targetUris == null) {
4988            targetUris = new HashMap<Uri, UriPermission>();
4989            mGrantedUriPermissions.put(targetUid, targetUris);
4990        }
4991
4992        UriPermission perm = targetUris.get(uri);
4993        if (perm == null) {
4994            perm = new UriPermission(targetUid, uri);
4995            targetUris.put(uri, perm);
4996        }
4997
4998        perm.modeFlags |= modeFlags;
4999        if (owner == null) {
5000            perm.globalModeFlags |= modeFlags;
5001        } else {
5002            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5003                 perm.readOwners.add(owner);
5004                 owner.addReadPermission(perm);
5005            }
5006            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5007                 perm.writeOwners.add(owner);
5008                 owner.addWritePermission(perm);
5009            }
5010        }
5011    }
5012
5013    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5014            int modeFlags, UriPermissionOwner owner) {
5015        if (targetPkg == null) {
5016            throw new NullPointerException("targetPkg");
5017        }
5018
5019        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5020        if (targetUid < 0) {
5021            return;
5022        }
5023
5024        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5025    }
5026
5027    static class NeededUriGrants extends ArrayList<Uri> {
5028        final String targetPkg;
5029        final int targetUid;
5030        final int flags;
5031
5032        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5033            targetPkg = _targetPkg;
5034            targetUid = _targetUid;
5035            flags = _flags;
5036        }
5037    }
5038
5039    /**
5040     * Like checkGrantUriPermissionLocked, but takes an Intent.
5041     */
5042    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5043            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5044        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5045                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5046                + " clip=" + (intent != null ? intent.getClipData() : null)
5047                + " from " + intent + "; flags=0x"
5048                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5049
5050        if (targetPkg == null) {
5051            throw new NullPointerException("targetPkg");
5052        }
5053
5054        if (intent == null) {
5055            return null;
5056        }
5057        Uri data = intent.getData();
5058        ClipData clip = intent.getClipData();
5059        if (data == null && clip == null) {
5060            return null;
5061        }
5062        if (data != null) {
5063            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5064                mode, needed != null ? needed.targetUid : -1);
5065            if (target > 0) {
5066                if (needed == null) {
5067                    needed = new NeededUriGrants(targetPkg, target, mode);
5068                }
5069                needed.add(data);
5070            }
5071        }
5072        if (clip != null) {
5073            for (int i=0; i<clip.getItemCount(); i++) {
5074                Uri uri = clip.getItemAt(i).getUri();
5075                if (uri != null) {
5076                    int target = -1;
5077                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5078                            mode, needed != null ? needed.targetUid : -1);
5079                    if (target > 0) {
5080                        if (needed == null) {
5081                            needed = new NeededUriGrants(targetPkg, target, mode);
5082                        }
5083                        needed.add(uri);
5084                    }
5085                } else {
5086                    Intent clipIntent = clip.getItemAt(i).getIntent();
5087                    if (clipIntent != null) {
5088                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5089                                callingUid, targetPkg, clipIntent, mode, needed);
5090                        if (newNeeded != null) {
5091                            needed = newNeeded;
5092                        }
5093                    }
5094                }
5095            }
5096        }
5097
5098        return needed;
5099    }
5100
5101    /**
5102     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5103     */
5104    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5105            UriPermissionOwner owner) {
5106        if (needed != null) {
5107            for (int i=0; i<needed.size(); i++) {
5108                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5109                        needed.get(i), needed.flags, owner);
5110            }
5111        }
5112    }
5113
5114    void grantUriPermissionFromIntentLocked(int callingUid,
5115            String targetPkg, Intent intent, UriPermissionOwner owner) {
5116        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5117                intent, intent != null ? intent.getFlags() : 0, null);
5118        if (needed == null) {
5119            return;
5120        }
5121
5122        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5123    }
5124
5125    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5126            Uri uri, int modeFlags) {
5127        enforceNotIsolatedCaller("grantUriPermission");
5128        synchronized(this) {
5129            final ProcessRecord r = getRecordForAppLocked(caller);
5130            if (r == null) {
5131                throw new SecurityException("Unable to find app for caller "
5132                        + caller
5133                        + " when granting permission to uri " + uri);
5134            }
5135            if (targetPkg == null) {
5136                throw new IllegalArgumentException("null target");
5137            }
5138            if (uri == null) {
5139                throw new IllegalArgumentException("null uri");
5140            }
5141
5142            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5143                    null);
5144        }
5145    }
5146
5147    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5148        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5149                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5150            HashMap<Uri, UriPermission> perms
5151                    = mGrantedUriPermissions.get(perm.uid);
5152            if (perms != null) {
5153                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5154                        "Removing " + perm.uid + " permission to " + perm.uri);
5155                perms.remove(perm.uri);
5156                if (perms.size() == 0) {
5157                    mGrantedUriPermissions.remove(perm.uid);
5158                }
5159            }
5160        }
5161    }
5162
5163    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5164            int modeFlags) {
5165        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5166                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5167        if (modeFlags == 0) {
5168            return;
5169        }
5170
5171        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5172                "Revoking all granted permissions to " + uri);
5173
5174        final IPackageManager pm = AppGlobals.getPackageManager();
5175
5176        final String authority = uri.getAuthority();
5177        ProviderInfo pi = null;
5178        int userId = UserId.getUserId(callingUid);
5179        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5180        if (cpr != null) {
5181            pi = cpr.info;
5182        } else {
5183            try {
5184                pi = pm.resolveContentProvider(authority,
5185                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5186            } catch (RemoteException ex) {
5187            }
5188        }
5189        if (pi == null) {
5190            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5191            return;
5192        }
5193
5194        // Does the caller have this permission on the URI?
5195        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5196            // Right now, if you are not the original owner of the permission,
5197            // you are not allowed to revoke it.
5198            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5199                throw new SecurityException("Uid " + callingUid
5200                        + " does not have permission to uri " + uri);
5201            //}
5202        }
5203
5204        // Go through all of the permissions and remove any that match.
5205        final List<String> SEGMENTS = uri.getPathSegments();
5206        if (SEGMENTS != null) {
5207            final int NS = SEGMENTS.size();
5208            int N = mGrantedUriPermissions.size();
5209            for (int i=0; i<N; i++) {
5210                HashMap<Uri, UriPermission> perms
5211                        = mGrantedUriPermissions.valueAt(i);
5212                Iterator<UriPermission> it = perms.values().iterator();
5213            toploop:
5214                while (it.hasNext()) {
5215                    UriPermission perm = it.next();
5216                    Uri targetUri = perm.uri;
5217                    if (!authority.equals(targetUri.getAuthority())) {
5218                        continue;
5219                    }
5220                    List<String> targetSegments = targetUri.getPathSegments();
5221                    if (targetSegments == null) {
5222                        continue;
5223                    }
5224                    if (targetSegments.size() < NS) {
5225                        continue;
5226                    }
5227                    for (int j=0; j<NS; j++) {
5228                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5229                            continue toploop;
5230                        }
5231                    }
5232                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5233                            "Revoking " + perm.uid + " permission to " + perm.uri);
5234                    perm.clearModes(modeFlags);
5235                    if (perm.modeFlags == 0) {
5236                        it.remove();
5237                    }
5238                }
5239                if (perms.size() == 0) {
5240                    mGrantedUriPermissions.remove(
5241                            mGrantedUriPermissions.keyAt(i));
5242                    N--;
5243                    i--;
5244                }
5245            }
5246        }
5247    }
5248
5249    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5250            int modeFlags) {
5251        enforceNotIsolatedCaller("revokeUriPermission");
5252        synchronized(this) {
5253            final ProcessRecord r = getRecordForAppLocked(caller);
5254            if (r == null) {
5255                throw new SecurityException("Unable to find app for caller "
5256                        + caller
5257                        + " when revoking permission to uri " + uri);
5258            }
5259            if (uri == null) {
5260                Slog.w(TAG, "revokeUriPermission: null uri");
5261                return;
5262            }
5263
5264            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5265                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5266            if (modeFlags == 0) {
5267                return;
5268            }
5269
5270            final IPackageManager pm = AppGlobals.getPackageManager();
5271
5272            final String authority = uri.getAuthority();
5273            ProviderInfo pi = null;
5274            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5275            if (cpr != null) {
5276                pi = cpr.info;
5277            } else {
5278                try {
5279                    pi = pm.resolveContentProvider(authority,
5280                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5281                } catch (RemoteException ex) {
5282                }
5283            }
5284            if (pi == null) {
5285                Slog.w(TAG, "No content provider found for permission revoke: "
5286                        + uri.toSafeString());
5287                return;
5288            }
5289
5290            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5291        }
5292    }
5293
5294    @Override
5295    public IBinder newUriPermissionOwner(String name) {
5296        enforceNotIsolatedCaller("newUriPermissionOwner");
5297        synchronized(this) {
5298            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5299            return owner.getExternalTokenLocked();
5300        }
5301    }
5302
5303    @Override
5304    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5305            Uri uri, int modeFlags) {
5306        synchronized(this) {
5307            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5308            if (owner == null) {
5309                throw new IllegalArgumentException("Unknown owner: " + token);
5310            }
5311            if (fromUid != Binder.getCallingUid()) {
5312                if (Binder.getCallingUid() != Process.myUid()) {
5313                    // Only system code can grant URI permissions on behalf
5314                    // of other users.
5315                    throw new SecurityException("nice try");
5316                }
5317            }
5318            if (targetPkg == null) {
5319                throw new IllegalArgumentException("null target");
5320            }
5321            if (uri == null) {
5322                throw new IllegalArgumentException("null uri");
5323            }
5324
5325            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5326        }
5327    }
5328
5329    @Override
5330    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5331        synchronized(this) {
5332            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5333            if (owner == null) {
5334                throw new IllegalArgumentException("Unknown owner: " + token);
5335            }
5336
5337            if (uri == null) {
5338                owner.removeUriPermissionsLocked(mode);
5339            } else {
5340                owner.removeUriPermissionLocked(uri, mode);
5341            }
5342        }
5343    }
5344
5345    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5346        synchronized (this) {
5347            ProcessRecord app =
5348                who != null ? getRecordForAppLocked(who) : null;
5349            if (app == null) return;
5350
5351            Message msg = Message.obtain();
5352            msg.what = WAIT_FOR_DEBUGGER_MSG;
5353            msg.obj = app;
5354            msg.arg1 = waiting ? 1 : 0;
5355            mHandler.sendMessage(msg);
5356        }
5357    }
5358
5359    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5360        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5361        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5362        outInfo.availMem = Process.getFreeMemory();
5363        outInfo.totalMem = Process.getTotalMemory();
5364        outInfo.threshold = homeAppMem;
5365        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5366        outInfo.hiddenAppThreshold = hiddenAppMem;
5367        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5368                ProcessList.SERVICE_ADJ);
5369        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5370                ProcessList.VISIBLE_APP_ADJ);
5371        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5372                ProcessList.FOREGROUND_APP_ADJ);
5373    }
5374
5375    // =========================================================
5376    // TASK MANAGEMENT
5377    // =========================================================
5378
5379    public List getTasks(int maxNum, int flags,
5380                         IThumbnailReceiver receiver) {
5381        ArrayList list = new ArrayList();
5382
5383        PendingThumbnailsRecord pending = null;
5384        IApplicationThread topThumbnail = null;
5385        ActivityRecord topRecord = null;
5386
5387        synchronized(this) {
5388            if (localLOGV) Slog.v(
5389                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5390                + ", receiver=" + receiver);
5391
5392            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5393                    != PackageManager.PERMISSION_GRANTED) {
5394                if (receiver != null) {
5395                    // If the caller wants to wait for pending thumbnails,
5396                    // it ain't gonna get them.
5397                    try {
5398                        receiver.finished();
5399                    } catch (RemoteException ex) {
5400                    }
5401                }
5402                String msg = "Permission Denial: getTasks() from pid="
5403                        + Binder.getCallingPid()
5404                        + ", uid=" + Binder.getCallingUid()
5405                        + " requires " + android.Manifest.permission.GET_TASKS;
5406                Slog.w(TAG, msg);
5407                throw new SecurityException(msg);
5408            }
5409
5410            int pos = mMainStack.mHistory.size()-1;
5411            ActivityRecord next =
5412                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5413            ActivityRecord top = null;
5414            TaskRecord curTask = null;
5415            int numActivities = 0;
5416            int numRunning = 0;
5417            while (pos >= 0 && maxNum > 0) {
5418                final ActivityRecord r = next;
5419                pos--;
5420                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5421
5422                // Initialize state for next task if needed.
5423                if (top == null ||
5424                        (top.state == ActivityState.INITIALIZING
5425                            && top.task == r.task)) {
5426                    top = r;
5427                    curTask = r.task;
5428                    numActivities = numRunning = 0;
5429                }
5430
5431                // Add 'r' into the current task.
5432                numActivities++;
5433                if (r.app != null && r.app.thread != null) {
5434                    numRunning++;
5435                }
5436
5437                if (localLOGV) Slog.v(
5438                    TAG, r.intent.getComponent().flattenToShortString()
5439                    + ": task=" + r.task);
5440
5441                // If the next one is a different task, generate a new
5442                // TaskInfo entry for what we have.
5443                if (next == null || next.task != curTask) {
5444                    ActivityManager.RunningTaskInfo ci
5445                            = new ActivityManager.RunningTaskInfo();
5446                    ci.id = curTask.taskId;
5447                    ci.baseActivity = r.intent.getComponent();
5448                    ci.topActivity = top.intent.getComponent();
5449                    if (top.thumbHolder != null) {
5450                        ci.description = top.thumbHolder.lastDescription;
5451                    }
5452                    ci.numActivities = numActivities;
5453                    ci.numRunning = numRunning;
5454                    //System.out.println(
5455                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5456                    if (ci.thumbnail == null && receiver != null) {
5457                        if (localLOGV) Slog.v(
5458                            TAG, "State=" + top.state + "Idle=" + top.idle
5459                            + " app=" + top.app
5460                            + " thr=" + (top.app != null ? top.app.thread : null));
5461                        if (top.state == ActivityState.RESUMED
5462                                || top.state == ActivityState.PAUSING) {
5463                            if (top.idle && top.app != null
5464                                && top.app.thread != null) {
5465                                topRecord = top;
5466                                topThumbnail = top.app.thread;
5467                            } else {
5468                                top.thumbnailNeeded = true;
5469                            }
5470                        }
5471                        if (pending == null) {
5472                            pending = new PendingThumbnailsRecord(receiver);
5473                        }
5474                        pending.pendingRecords.add(top);
5475                    }
5476                    list.add(ci);
5477                    maxNum--;
5478                    top = null;
5479                }
5480            }
5481
5482            if (pending != null) {
5483                mPendingThumbnails.add(pending);
5484            }
5485        }
5486
5487        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5488
5489        if (topThumbnail != null) {
5490            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5491            try {
5492                topThumbnail.requestThumbnail(topRecord.appToken);
5493            } catch (Exception e) {
5494                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5495                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5496            }
5497        }
5498
5499        if (pending == null && receiver != null) {
5500            // In this case all thumbnails were available and the client
5501            // is being asked to be told when the remaining ones come in...
5502            // which is unusually, since the top-most currently running
5503            // activity should never have a canned thumbnail!  Oh well.
5504            try {
5505                receiver.finished();
5506            } catch (RemoteException ex) {
5507            }
5508        }
5509
5510        return list;
5511    }
5512
5513    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5514            int flags) {
5515        final int callingUid = Binder.getCallingUid();
5516        // If it's the system uid asking, then use the current user id.
5517        // TODO: Make sure that there aren't any other legitimate calls from the system uid that
5518        // require the entire list.
5519        final int callingUserId = callingUid == Process.SYSTEM_UID
5520                ? mCurrentUserId : UserId.getUserId(callingUid);
5521        synchronized (this) {
5522            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5523                    "getRecentTasks()");
5524            final boolean detailed = checkCallingPermission(
5525                    android.Manifest.permission.GET_DETAILED_TASKS)
5526                    == PackageManager.PERMISSION_GRANTED;
5527
5528            IPackageManager pm = AppGlobals.getPackageManager();
5529
5530            final int N = mRecentTasks.size();
5531            ArrayList<ActivityManager.RecentTaskInfo> res
5532                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5533                            maxNum < N ? maxNum : N);
5534            for (int i=0; i<N && maxNum > 0; i++) {
5535                TaskRecord tr = mRecentTasks.get(i);
5536                // Only add calling user's recent tasks
5537                if (tr.userId != callingUserId) continue;
5538                // Return the entry if desired by the caller.  We always return
5539                // the first entry, because callers always expect this to be the
5540                // foreground app.  We may filter others if the caller has
5541                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5542                // we should exclude the entry.
5543
5544                if (i == 0
5545                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5546                        || (tr.intent == null)
5547                        || ((tr.intent.getFlags()
5548                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5549                    ActivityManager.RecentTaskInfo rti
5550                            = new ActivityManager.RecentTaskInfo();
5551                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5552                    rti.persistentId = tr.taskId;
5553                    rti.baseIntent = new Intent(
5554                            tr.intent != null ? tr.intent : tr.affinityIntent);
5555                    if (!detailed) {
5556                        rti.baseIntent.replaceExtras((Bundle)null);
5557                    }
5558                    rti.origActivity = tr.origActivity;
5559                    rti.description = tr.lastDescription;
5560
5561                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5562                        // Check whether this activity is currently available.
5563                        try {
5564                            if (rti.origActivity != null) {
5565                                if (pm.getActivityInfo(rti.origActivity, 0, callingUserId)
5566                                        == null) {
5567                                    continue;
5568                                }
5569                            } else if (rti.baseIntent != null) {
5570                                if (pm.queryIntentActivities(rti.baseIntent,
5571                                        null, 0, callingUserId) == null) {
5572                                    continue;
5573                                }
5574                            }
5575                        } catch (RemoteException e) {
5576                            // Will never happen.
5577                        }
5578                    }
5579
5580                    res.add(rti);
5581                    maxNum--;
5582                }
5583            }
5584            return res;
5585        }
5586    }
5587
5588    private TaskRecord taskForIdLocked(int id) {
5589        final int N = mRecentTasks.size();
5590        for (int i=0; i<N; i++) {
5591            TaskRecord tr = mRecentTasks.get(i);
5592            if (tr.taskId == id) {
5593                return tr;
5594            }
5595        }
5596        return null;
5597    }
5598
5599    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5600        synchronized (this) {
5601            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5602                    "getTaskThumbnails()");
5603            TaskRecord tr = taskForIdLocked(id);
5604            if (tr != null) {
5605                return mMainStack.getTaskThumbnailsLocked(tr);
5606            }
5607        }
5608        return null;
5609    }
5610
5611    public boolean removeSubTask(int taskId, int subTaskIndex) {
5612        synchronized (this) {
5613            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5614                    "removeSubTask()");
5615            long ident = Binder.clearCallingIdentity();
5616            try {
5617                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5618                        true) != null;
5619            } finally {
5620                Binder.restoreCallingIdentity(ident);
5621            }
5622        }
5623    }
5624
5625    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5626        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5627        Intent baseIntent = new Intent(
5628                tr.intent != null ? tr.intent : tr.affinityIntent);
5629        ComponentName component = baseIntent.getComponent();
5630        if (component == null) {
5631            Slog.w(TAG, "Now component for base intent of task: " + tr);
5632            return;
5633        }
5634
5635        // Find any running services associated with this app.
5636        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5637        for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) {
5638            if (sr.packageName.equals(component.getPackageName())) {
5639                services.add(sr);
5640            }
5641        }
5642
5643        // Take care of any running services associated with the app.
5644        for (int i=0; i<services.size(); i++) {
5645            ServiceRecord sr = services.get(i);
5646            if (sr.startRequested) {
5647                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5648                    Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
5649                    stopServiceLocked(sr);
5650                } else {
5651                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5652                            sr.makeNextStartId(), baseIntent, null));
5653                    if (sr.app != null && sr.app.thread != null) {
5654                        sendServiceArgsLocked(sr, false);
5655                    }
5656                }
5657            }
5658        }
5659
5660        if (killProcesses) {
5661            // Find any running processes associated with this app.
5662            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5663            SparseArray<ProcessRecord> appProcs
5664                    = mProcessNames.getMap().get(component.getPackageName());
5665            if (appProcs != null) {
5666                for (int i=0; i<appProcs.size(); i++) {
5667                    procs.add(appProcs.valueAt(i));
5668                }
5669            }
5670
5671            // Kill the running processes.
5672            for (int i=0; i<procs.size(); i++) {
5673                ProcessRecord pr = procs.get(i);
5674                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5675                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5676                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5677                            pr.processName, pr.setAdj, "remove task");
5678                    Process.killProcessQuiet(pr.pid);
5679                } else {
5680                    pr.waitingToKill = "remove task";
5681                }
5682            }
5683        }
5684    }
5685
5686    public boolean removeTask(int taskId, int flags) {
5687        synchronized (this) {
5688            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5689                    "removeTask()");
5690            long ident = Binder.clearCallingIdentity();
5691            try {
5692                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5693                        false);
5694                if (r != null) {
5695                    mRecentTasks.remove(r.task);
5696                    cleanUpRemovedTaskLocked(r.task, flags);
5697                    return true;
5698                } else {
5699                    TaskRecord tr = null;
5700                    int i=0;
5701                    while (i < mRecentTasks.size()) {
5702                        TaskRecord t = mRecentTasks.get(i);
5703                        if (t.taskId == taskId) {
5704                            tr = t;
5705                            break;
5706                        }
5707                        i++;
5708                    }
5709                    if (tr != null) {
5710                        if (tr.numActivities <= 0) {
5711                            // Caller is just removing a recent task that is
5712                            // not actively running.  That is easy!
5713                            mRecentTasks.remove(i);
5714                            cleanUpRemovedTaskLocked(tr, flags);
5715                            return true;
5716                        } else {
5717                            Slog.w(TAG, "removeTask: task " + taskId
5718                                    + " does not have activities to remove, "
5719                                    + " but numActivities=" + tr.numActivities
5720                                    + ": " + tr);
5721                        }
5722                    }
5723                }
5724            } finally {
5725                Binder.restoreCallingIdentity(ident);
5726            }
5727        }
5728        return false;
5729    }
5730
5731    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5732        int j;
5733        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5734        TaskRecord jt = startTask;
5735
5736        // First look backwards
5737        for (j=startIndex-1; j>=0; j--) {
5738            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5739            if (r.task != jt) {
5740                jt = r.task;
5741                if (affinity.equals(jt.affinity)) {
5742                    return j;
5743                }
5744            }
5745        }
5746
5747        // Now look forwards
5748        final int N = mMainStack.mHistory.size();
5749        jt = startTask;
5750        for (j=startIndex+1; j<N; j++) {
5751            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5752            if (r.task != jt) {
5753                if (affinity.equals(jt.affinity)) {
5754                    return j;
5755                }
5756                jt = r.task;
5757            }
5758        }
5759
5760        // Might it be at the top?
5761        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5762            return N-1;
5763        }
5764
5765        return -1;
5766    }
5767
5768    /**
5769     * TODO: Add mController hook
5770     */
5771    public void moveTaskToFront(int task, int flags, Bundle options) {
5772        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5773                "moveTaskToFront()");
5774
5775        synchronized(this) {
5776            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5777                    Binder.getCallingUid(), "Task to front")) {
5778                ActivityOptions.abort(options);
5779                return;
5780            }
5781            final long origId = Binder.clearCallingIdentity();
5782            try {
5783                TaskRecord tr = taskForIdLocked(task);
5784                if (tr != null) {
5785                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5786                        mMainStack.mUserLeaving = true;
5787                    }
5788                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5789                        // Caller wants the home activity moved with it.  To accomplish this,
5790                        // we'll just move the home task to the top first.
5791                        mMainStack.moveHomeToFrontLocked();
5792                    }
5793                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5794                    return;
5795                }
5796                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5797                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5798                    if (hr.task.taskId == task) {
5799                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5800                            mMainStack.mUserLeaving = true;
5801                        }
5802                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5803                            // Caller wants the home activity moved with it.  To accomplish this,
5804                            // we'll just move the home task to the top first.
5805                            mMainStack.moveHomeToFrontLocked();
5806                        }
5807                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5808                        return;
5809                    }
5810                }
5811            } finally {
5812                Binder.restoreCallingIdentity(origId);
5813            }
5814            ActivityOptions.abort(options);
5815        }
5816    }
5817
5818    public void moveTaskToBack(int task) {
5819        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5820                "moveTaskToBack()");
5821
5822        synchronized(this) {
5823            if (mMainStack.mResumedActivity != null
5824                    && mMainStack.mResumedActivity.task.taskId == task) {
5825                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5826                        Binder.getCallingUid(), "Task to back")) {
5827                    return;
5828                }
5829            }
5830            final long origId = Binder.clearCallingIdentity();
5831            mMainStack.moveTaskToBackLocked(task, null);
5832            Binder.restoreCallingIdentity(origId);
5833        }
5834    }
5835
5836    /**
5837     * Moves an activity, and all of the other activities within the same task, to the bottom
5838     * of the history stack.  The activity's order within the task is unchanged.
5839     *
5840     * @param token A reference to the activity we wish to move
5841     * @param nonRoot If false then this only works if the activity is the root
5842     *                of a task; if true it will work for any activity in a task.
5843     * @return Returns true if the move completed, false if not.
5844     */
5845    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5846        enforceNotIsolatedCaller("moveActivityTaskToBack");
5847        synchronized(this) {
5848            final long origId = Binder.clearCallingIdentity();
5849            int taskId = getTaskForActivityLocked(token, !nonRoot);
5850            if (taskId >= 0) {
5851                return mMainStack.moveTaskToBackLocked(taskId, null);
5852            }
5853            Binder.restoreCallingIdentity(origId);
5854        }
5855        return false;
5856    }
5857
5858    public void moveTaskBackwards(int task) {
5859        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5860                "moveTaskBackwards()");
5861
5862        synchronized(this) {
5863            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5864                    Binder.getCallingUid(), "Task backwards")) {
5865                return;
5866            }
5867            final long origId = Binder.clearCallingIdentity();
5868            moveTaskBackwardsLocked(task);
5869            Binder.restoreCallingIdentity(origId);
5870        }
5871    }
5872
5873    private final void moveTaskBackwardsLocked(int task) {
5874        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5875    }
5876
5877    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5878        synchronized(this) {
5879            return getTaskForActivityLocked(token, onlyRoot);
5880        }
5881    }
5882
5883    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5884        final int N = mMainStack.mHistory.size();
5885        TaskRecord lastTask = null;
5886        for (int i=0; i<N; i++) {
5887            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5888            if (r.appToken == token) {
5889                if (!onlyRoot || lastTask != r.task) {
5890                    return r.task.taskId;
5891                }
5892                return -1;
5893            }
5894            lastTask = r.task;
5895        }
5896
5897        return -1;
5898    }
5899
5900    // =========================================================
5901    // THUMBNAILS
5902    // =========================================================
5903
5904    public void reportThumbnail(IBinder token,
5905            Bitmap thumbnail, CharSequence description) {
5906        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5907        final long origId = Binder.clearCallingIdentity();
5908        sendPendingThumbnail(null, token, thumbnail, description, true);
5909        Binder.restoreCallingIdentity(origId);
5910    }
5911
5912    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5913            Bitmap thumbnail, CharSequence description, boolean always) {
5914        TaskRecord task = null;
5915        ArrayList receivers = null;
5916
5917        //System.out.println("Send pending thumbnail: " + r);
5918
5919        synchronized(this) {
5920            if (r == null) {
5921                r = mMainStack.isInStackLocked(token);
5922                if (r == null) {
5923                    return;
5924                }
5925            }
5926            if (thumbnail == null && r.thumbHolder != null) {
5927                thumbnail = r.thumbHolder.lastThumbnail;
5928                description = r.thumbHolder.lastDescription;
5929            }
5930            if (thumbnail == null && !always) {
5931                // If there is no thumbnail, and this entry is not actually
5932                // going away, then abort for now and pick up the next
5933                // thumbnail we get.
5934                return;
5935            }
5936            task = r.task;
5937
5938            int N = mPendingThumbnails.size();
5939            int i=0;
5940            while (i<N) {
5941                PendingThumbnailsRecord pr =
5942                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5943                //System.out.println("Looking in " + pr.pendingRecords);
5944                if (pr.pendingRecords.remove(r)) {
5945                    if (receivers == null) {
5946                        receivers = new ArrayList();
5947                    }
5948                    receivers.add(pr);
5949                    if (pr.pendingRecords.size() == 0) {
5950                        pr.finished = true;
5951                        mPendingThumbnails.remove(i);
5952                        N--;
5953                        continue;
5954                    }
5955                }
5956                i++;
5957            }
5958        }
5959
5960        if (receivers != null) {
5961            final int N = receivers.size();
5962            for (int i=0; i<N; i++) {
5963                try {
5964                    PendingThumbnailsRecord pr =
5965                        (PendingThumbnailsRecord)receivers.get(i);
5966                    pr.receiver.newThumbnail(
5967                        task != null ? task.taskId : -1, thumbnail, description);
5968                    if (pr.finished) {
5969                        pr.receiver.finished();
5970                    }
5971                } catch (Exception e) {
5972                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5973                }
5974            }
5975        }
5976    }
5977
5978    // =========================================================
5979    // CONTENT PROVIDERS
5980    // =========================================================
5981
5982    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5983        List<ProviderInfo> providers = null;
5984        try {
5985            providers = AppGlobals.getPackageManager().
5986                queryContentProviders(app.processName, app.uid,
5987                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5988        } catch (RemoteException ex) {
5989        }
5990        if (DEBUG_MU)
5991            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
5992        int userId = app.userId;
5993        if (providers != null) {
5994            final int N = providers.size();
5995            for (int i=0; i<N; i++) {
5996                ProviderInfo cpi =
5997                    (ProviderInfo)providers.get(i);
5998
5999                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6000                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6001                if (cpr == null) {
6002                    cpr = new ContentProviderRecord(this, cpi, app.info, comp);
6003                    mProviderMap.putProviderByClass(comp, cpr);
6004                }
6005                if (DEBUG_MU)
6006                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6007                app.pubProviders.put(cpi.name, cpr);
6008                app.addPackage(cpi.applicationInfo.packageName);
6009                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6010            }
6011        }
6012        return providers;
6013    }
6014
6015    /**
6016     * Check if {@link ProcessRecord} has a possible chance at accessing the
6017     * given {@link ProviderInfo}. Final permission checking is always done
6018     * in {@link ContentProvider}.
6019     */
6020    private final String checkContentProviderPermissionLocked(
6021            ProviderInfo cpi, ProcessRecord r) {
6022        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6023        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6024        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6025                cpi.applicationInfo.uid, cpi.exported)
6026                == PackageManager.PERMISSION_GRANTED) {
6027            return null;
6028        }
6029        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6030                cpi.applicationInfo.uid, cpi.exported)
6031                == PackageManager.PERMISSION_GRANTED) {
6032            return null;
6033        }
6034
6035        PathPermission[] pps = cpi.pathPermissions;
6036        if (pps != null) {
6037            int i = pps.length;
6038            while (i > 0) {
6039                i--;
6040                PathPermission pp = pps[i];
6041                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6042                        cpi.applicationInfo.uid, cpi.exported)
6043                        == PackageManager.PERMISSION_GRANTED) {
6044                    return null;
6045                }
6046                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6047                        cpi.applicationInfo.uid, cpi.exported)
6048                        == PackageManager.PERMISSION_GRANTED) {
6049                    return null;
6050                }
6051            }
6052        }
6053
6054        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6055        if (perms != null) {
6056            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6057                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6058                    return null;
6059                }
6060            }
6061        }
6062
6063        String msg;
6064        if (!cpi.exported) {
6065            msg = "Permission Denial: opening provider " + cpi.name
6066                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6067                    + ", uid=" + callingUid + ") that is not exported from uid "
6068                    + cpi.applicationInfo.uid;
6069        } else {
6070            msg = "Permission Denial: opening provider " + cpi.name
6071                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6072                    + ", uid=" + callingUid + ") requires "
6073                    + cpi.readPermission + " or " + cpi.writePermission;
6074        }
6075        Slog.w(TAG, msg);
6076        return msg;
6077    }
6078
6079    boolean incProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
6080            IBinder externalProcessToken) {
6081        if (r != null) {
6082            Integer cnt = r.conProviders.get(cpr);
6083            if (DEBUG_PROVIDER) Slog.v(TAG,
6084                    "Adding provider requested by "
6085                    + r.processName + " from process "
6086                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6087                    + " cnt=" + (cnt == null ? 1 : cnt));
6088            if (cnt == null) {
6089                cpr.clients.add(r);
6090                r.conProviders.put(cpr, new Integer(1));
6091                return true;
6092            } else {
6093                r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
6094            }
6095        } else {
6096            cpr.addExternalProcessHandleLocked(externalProcessToken);
6097        }
6098        return false;
6099    }
6100
6101    boolean decProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
6102            IBinder externalProcessToken) {
6103        if (r != null) {
6104            Integer cnt = r.conProviders.get(cpr);
6105            if (DEBUG_PROVIDER) Slog.v(TAG,
6106                    "Removing provider requested by "
6107                    + r.processName + " from process "
6108                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6109                    + " cnt=" + cnt);
6110            if (cnt == null || cnt.intValue() <= 1) {
6111                cpr.clients.remove(r);
6112                r.conProviders.remove(cpr);
6113                return true;
6114            } else {
6115                r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
6116            }
6117        } else {
6118            cpr.removeExternalProcessHandleLocked(externalProcessToken);
6119        }
6120        return false;
6121    }
6122
6123    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6124            String name, IBinder token) {
6125        ContentProviderRecord cpr;
6126        ProviderInfo cpi = null;
6127
6128        synchronized(this) {
6129            ProcessRecord r = null;
6130            if (caller != null) {
6131                r = getRecordForAppLocked(caller);
6132                if (r == null) {
6133                    throw new SecurityException(
6134                            "Unable to find app for caller " + caller
6135                          + " (pid=" + Binder.getCallingPid()
6136                          + ") when getting content provider " + name);
6137                }
6138            }
6139
6140            // First check if this content provider has been published...
6141            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6142            cpr = mProviderMap.getProviderByName(name, userId);
6143            boolean providerRunning = cpr != null;
6144            if (providerRunning) {
6145                cpi = cpr.info;
6146                String msg;
6147                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6148                    throw new SecurityException(msg);
6149                }
6150
6151                if (r != null && cpr.canRunHere(r)) {
6152                    // This provider has been published or is in the process
6153                    // of being published...  but it is also allowed to run
6154                    // in the caller's process, so don't make a connection
6155                    // and just let the caller instantiate its own instance.
6156                    if (cpr.provider != null) {
6157                        // don't give caller the provider object, it needs
6158                        // to make its own.
6159                        cpr = new ContentProviderRecord(cpr);
6160                    }
6161                    return cpr;
6162                }
6163
6164                final long origId = Binder.clearCallingIdentity();
6165
6166                // In this case the provider instance already exists, so we can
6167                // return it right away.
6168                final boolean countChanged = incProviderCount(r, cpr, token);
6169                if (countChanged) {
6170                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6171                        // If this is a perceptible app accessing the provider,
6172                        // make sure to count it as being accessed and thus
6173                        // back up on the LRU list.  This is good because
6174                        // content providers are often expensive to start.
6175                        updateLruProcessLocked(cpr.proc, false, true);
6176                    }
6177                }
6178
6179                if (cpr.proc != null) {
6180                    if (false) {
6181                        if (cpr.name.flattenToShortString().equals(
6182                                "com.android.providers.calendar/.CalendarProvider2")) {
6183                            Slog.v(TAG, "****************** KILLING "
6184                                + cpr.name.flattenToShortString());
6185                            Process.killProcess(cpr.proc.pid);
6186                        }
6187                    }
6188                    boolean success = updateOomAdjLocked(cpr.proc);
6189                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6190                    // NOTE: there is still a race here where a signal could be
6191                    // pending on the process even though we managed to update its
6192                    // adj level.  Not sure what to do about this, but at least
6193                    // the race is now smaller.
6194                    if (!success) {
6195                        // Uh oh...  it looks like the provider's process
6196                        // has been killed on us.  We need to wait for a new
6197                        // process to be started, and make sure its death
6198                        // doesn't kill our process.
6199                        Slog.i(TAG,
6200                                "Existing provider " + cpr.name.flattenToShortString()
6201                                + " is crashing; detaching " + r);
6202                        boolean lastRef = decProviderCount(r, cpr, token);
6203                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6204                        if (!lastRef) {
6205                            // This wasn't the last ref our process had on
6206                            // the provider...  we have now been killed, bail.
6207                            return null;
6208                        }
6209                        providerRunning = false;
6210                    }
6211                }
6212
6213                Binder.restoreCallingIdentity(origId);
6214            }
6215
6216            if (!providerRunning) {
6217                try {
6218                    cpi = AppGlobals.getPackageManager().
6219                        resolveContentProvider(name,
6220                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6221                } catch (RemoteException ex) {
6222                }
6223                if (cpi == null) {
6224                    return null;
6225                }
6226                if (isSingleton(cpi.processName, cpi.applicationInfo)) {
6227                    userId = 0;
6228                }
6229                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6230
6231                String msg;
6232                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6233                    throw new SecurityException(msg);
6234                }
6235
6236                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6237                        && !cpi.processName.equals("system")) {
6238                    // If this content provider does not run in the system
6239                    // process, and the system is not yet ready to run other
6240                    // processes, then fail fast instead of hanging.
6241                    throw new IllegalArgumentException(
6242                            "Attempt to launch content provider before system ready");
6243                }
6244
6245                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6246                cpr = mProviderMap.getProviderByClass(comp, userId);
6247                final boolean firstClass = cpr == null;
6248                if (firstClass) {
6249                    try {
6250                        ApplicationInfo ai =
6251                            AppGlobals.getPackageManager().
6252                                getApplicationInfo(
6253                                        cpi.applicationInfo.packageName,
6254                                        STOCK_PM_FLAGS, userId);
6255                        if (ai == null) {
6256                            Slog.w(TAG, "No package info for content provider "
6257                                    + cpi.name);
6258                            return null;
6259                        }
6260                        ai = getAppInfoForUser(ai, userId);
6261                        cpr = new ContentProviderRecord(this, cpi, ai, comp);
6262                    } catch (RemoteException ex) {
6263                        // pm is in same process, this will never happen.
6264                    }
6265                }
6266
6267                if (r != null && cpr.canRunHere(r)) {
6268                    // If this is a multiprocess provider, then just return its
6269                    // info and allow the caller to instantiate it.  Only do
6270                    // this if the provider is the same user as the caller's
6271                    // process, or can run as root (so can be in any process).
6272                    return cpr;
6273                }
6274
6275                if (DEBUG_PROVIDER) {
6276                    RuntimeException e = new RuntimeException("here");
6277                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6278                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6279                }
6280
6281                // This is single process, and our app is now connecting to it.
6282                // See if we are already in the process of launching this
6283                // provider.
6284                final int N = mLaunchingProviders.size();
6285                int i;
6286                for (i=0; i<N; i++) {
6287                    if (mLaunchingProviders.get(i) == cpr) {
6288                        break;
6289                    }
6290                }
6291
6292                // If the provider is not already being launched, then get it
6293                // started.
6294                if (i >= N) {
6295                    final long origId = Binder.clearCallingIdentity();
6296
6297                    try {
6298                        // Content provider is now in use, its package can't be stopped.
6299                        try {
6300                            AppGlobals.getPackageManager().setPackageStoppedState(
6301                                    cpr.appInfo.packageName, false, userId);
6302                        } catch (RemoteException e) {
6303                        } catch (IllegalArgumentException e) {
6304                            Slog.w(TAG, "Failed trying to unstop package "
6305                                    + cpr.appInfo.packageName + ": " + e);
6306                        }
6307
6308                        ProcessRecord proc = startProcessLocked(cpi.processName,
6309                                cpr.appInfo, false, 0, "content provider",
6310                                new ComponentName(cpi.applicationInfo.packageName,
6311                                        cpi.name), false, false);
6312                        if (proc == null) {
6313                            Slog.w(TAG, "Unable to launch app "
6314                                    + cpi.applicationInfo.packageName + "/"
6315                                    + cpi.applicationInfo.uid + " for provider "
6316                                    + name + ": process is bad");
6317                            return null;
6318                        }
6319                        cpr.launchingApp = proc;
6320                        mLaunchingProviders.add(cpr);
6321                    } finally {
6322                        Binder.restoreCallingIdentity(origId);
6323                    }
6324                }
6325
6326                // Make sure the provider is published (the same provider class
6327                // may be published under multiple names).
6328                if (firstClass) {
6329                    mProviderMap.putProviderByClass(comp, cpr);
6330                }
6331
6332                mProviderMap.putProviderByName(name, cpr);
6333                incProviderCount(r, cpr, token);
6334            }
6335        }
6336
6337        // Wait for the provider to be published...
6338        synchronized (cpr) {
6339            while (cpr.provider == null) {
6340                if (cpr.launchingApp == null) {
6341                    Slog.w(TAG, "Unable to launch app "
6342                            + cpi.applicationInfo.packageName + "/"
6343                            + cpi.applicationInfo.uid + " for provider "
6344                            + name + ": launching app became null");
6345                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6346                            cpi.applicationInfo.packageName,
6347                            cpi.applicationInfo.uid, name);
6348                    return null;
6349                }
6350                try {
6351                    if (DEBUG_MU) {
6352                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6353                                + cpr.launchingApp);
6354                    }
6355                    cpr.wait();
6356                } catch (InterruptedException ex) {
6357                }
6358            }
6359        }
6360        return cpr;
6361    }
6362
6363    public final ContentProviderHolder getContentProvider(
6364            IApplicationThread caller, String name) {
6365        enforceNotIsolatedCaller("getContentProvider");
6366        if (caller == null) {
6367            String msg = "null IApplicationThread when getting content provider "
6368                    + name;
6369            Slog.w(TAG, msg);
6370            throw new SecurityException(msg);
6371        }
6372
6373        return getContentProviderImpl(caller, name, null);
6374    }
6375
6376    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6377        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6378            "Do not have permission in call getContentProviderExternal()");
6379        return getContentProviderExternalUnchecked(name, token);
6380    }
6381
6382    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6383        return getContentProviderImpl(null, name, token);
6384    }
6385
6386    /**
6387     * Drop a content provider from a ProcessRecord's bookkeeping
6388     * @param cpr
6389     */
6390    public void removeContentProvider(IApplicationThread caller, String name) {
6391        enforceNotIsolatedCaller("removeContentProvider");
6392        synchronized (this) {
6393            int userId = UserId.getUserId(Binder.getCallingUid());
6394            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6395            if(cpr == null) {
6396                // remove from mProvidersByClass
6397                if (DEBUG_PROVIDER) Slog.v(TAG, name +
6398                        " provider not found in providers list");
6399                return;
6400            }
6401            final ProcessRecord r = getRecordForAppLocked(caller);
6402            if (r == null) {
6403                throw new SecurityException(
6404                        "Unable to find app for caller " + caller +
6405                        " when removing content provider " + name);
6406            }
6407            //update content provider record entry info
6408            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6409            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6410            if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
6411                    + r.info.processName + " from process "
6412                    + localCpr.appInfo.processName);
6413            if (localCpr.launchingApp == r) {
6414                //should not happen. taken care of as a local provider
6415                Slog.w(TAG, "removeContentProvider called on local provider: "
6416                        + cpr.info.name + " in process " + r.processName);
6417                return;
6418            } else {
6419                if (decProviderCount(r, localCpr, null)) {
6420                    updateOomAdjLocked();
6421                }
6422            }
6423        }
6424    }
6425
6426    public void removeContentProviderExternal(String name, IBinder token) {
6427        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6428            "Do not have permission in call removeContentProviderExternal()");
6429        removeContentProviderExternalUnchecked(name, token);
6430    }
6431
6432    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6433        synchronized (this) {
6434            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6435                    Binder.getOrigCallingUser());
6436            if(cpr == null) {
6437                //remove from mProvidersByClass
6438                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6439                return;
6440            }
6441
6442            //update content provider record entry info
6443            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6444            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6445                    Binder.getOrigCallingUser());
6446            if (localCpr.hasExternalProcessHandles()) {
6447                if (localCpr.removeExternalProcessHandleLocked(token)) {
6448                    updateOomAdjLocked();
6449                } else {
6450                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6451                            + " with no external reference for token: "
6452                            + token + ".");
6453                }
6454            } else {
6455                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6456                        + " with no external references.");
6457            }
6458        }
6459    }
6460
6461    public final void publishContentProviders(IApplicationThread caller,
6462            List<ContentProviderHolder> providers) {
6463        if (providers == null) {
6464            return;
6465        }
6466
6467        enforceNotIsolatedCaller("publishContentProviders");
6468        synchronized(this) {
6469            final ProcessRecord r = getRecordForAppLocked(caller);
6470            if (DEBUG_MU)
6471                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6472            if (r == null) {
6473                throw new SecurityException(
6474                        "Unable to find app for caller " + caller
6475                      + " (pid=" + Binder.getCallingPid()
6476                      + ") when publishing content providers");
6477            }
6478
6479            final long origId = Binder.clearCallingIdentity();
6480
6481            final int N = providers.size();
6482            for (int i=0; i<N; i++) {
6483                ContentProviderHolder src = providers.get(i);
6484                if (src == null || src.info == null || src.provider == null) {
6485                    continue;
6486                }
6487                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6488                if (DEBUG_MU)
6489                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6490                if (dst != null) {
6491                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6492                    mProviderMap.putProviderByClass(comp, dst);
6493                    String names[] = dst.info.authority.split(";");
6494                    for (int j = 0; j < names.length; j++) {
6495                        mProviderMap.putProviderByName(names[j], dst);
6496                    }
6497
6498                    int NL = mLaunchingProviders.size();
6499                    int j;
6500                    for (j=0; j<NL; j++) {
6501                        if (mLaunchingProviders.get(j) == dst) {
6502                            mLaunchingProviders.remove(j);
6503                            j--;
6504                            NL--;
6505                        }
6506                    }
6507                    synchronized (dst) {
6508                        dst.provider = src.provider;
6509                        dst.proc = r;
6510                        dst.notifyAll();
6511                    }
6512                    updateOomAdjLocked(r);
6513                }
6514            }
6515
6516            Binder.restoreCallingIdentity(origId);
6517        }
6518    }
6519
6520    public static final void installSystemProviders() {
6521        List<ProviderInfo> providers;
6522        synchronized (mSelf) {
6523            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6524            providers = mSelf.generateApplicationProvidersLocked(app);
6525            if (providers != null) {
6526                for (int i=providers.size()-1; i>=0; i--) {
6527                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6528                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6529                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6530                                + ": not system .apk");
6531                        providers.remove(i);
6532                    }
6533                }
6534            }
6535        }
6536        if (providers != null) {
6537            mSystemThread.installSystemProviders(providers);
6538        }
6539
6540        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6541
6542        mSelf.mUsageStatsService.monitorPackages();
6543    }
6544
6545    /**
6546     * Allows app to retrieve the MIME type of a URI without having permission
6547     * to access its content provider.
6548     *
6549     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6550     *
6551     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6552     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6553     */
6554    public String getProviderMimeType(Uri uri) {
6555        enforceNotIsolatedCaller("getProviderMimeType");
6556        final String name = uri.getAuthority();
6557        final long ident = Binder.clearCallingIdentity();
6558        ContentProviderHolder holder = null;
6559
6560        try {
6561            holder = getContentProviderExternalUnchecked(name, null);
6562            if (holder != null) {
6563                return holder.provider.getType(uri);
6564            }
6565        } catch (RemoteException e) {
6566            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6567            return null;
6568        } finally {
6569            if (holder != null) {
6570                removeContentProviderExternalUnchecked(name, null);
6571            }
6572            Binder.restoreCallingIdentity(ident);
6573        }
6574
6575        return null;
6576    }
6577
6578    // =========================================================
6579    // GLOBAL MANAGEMENT
6580    // =========================================================
6581
6582    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6583            ApplicationInfo info, String customProcess, boolean isolated) {
6584        String proc = customProcess != null ? customProcess : info.processName;
6585        BatteryStatsImpl.Uid.Proc ps = null;
6586        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6587        int uid = info.uid;
6588        if (isolated) {
6589            int userId = UserId.getUserId(uid);
6590            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6591            uid = 0;
6592            while (true) {
6593                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6594                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6595                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6596                }
6597                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6598                mNextIsolatedProcessUid++;
6599                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6600                    // No process for this uid, use it.
6601                    break;
6602                }
6603                stepsLeft--;
6604                if (stepsLeft <= 0) {
6605                    return null;
6606                }
6607            }
6608        }
6609        synchronized (stats) {
6610            ps = stats.getProcessStatsLocked(info.uid, proc);
6611        }
6612        return new ProcessRecord(ps, thread, info, proc, uid);
6613    }
6614
6615    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6616        ProcessRecord app;
6617        if (!isolated) {
6618            app = getProcessRecordLocked(info.processName, info.uid);
6619        } else {
6620            app = null;
6621        }
6622
6623        if (app == null) {
6624            app = newProcessRecordLocked(null, info, null, isolated);
6625            mProcessNames.put(info.processName, app.uid, app);
6626            if (isolated) {
6627                mIsolatedProcesses.put(app.uid, app);
6628            }
6629            updateLruProcessLocked(app, true, true);
6630        }
6631
6632        // This package really, really can not be stopped.
6633        try {
6634            AppGlobals.getPackageManager().setPackageStoppedState(
6635                    info.packageName, false, UserId.getUserId(app.uid));
6636        } catch (RemoteException e) {
6637        } catch (IllegalArgumentException e) {
6638            Slog.w(TAG, "Failed trying to unstop package "
6639                    + info.packageName + ": " + e);
6640        }
6641
6642        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6643                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6644            app.persistent = true;
6645            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6646        }
6647        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6648            mPersistentStartingProcesses.add(app);
6649            startProcessLocked(app, "added application", app.processName);
6650        }
6651
6652        return app;
6653    }
6654
6655    public void unhandledBack() {
6656        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6657                "unhandledBack()");
6658
6659        synchronized(this) {
6660            int count = mMainStack.mHistory.size();
6661            if (DEBUG_SWITCH) Slog.d(
6662                TAG, "Performing unhandledBack(): stack size = " + count);
6663            if (count > 1) {
6664                final long origId = Binder.clearCallingIdentity();
6665                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6666                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6667                Binder.restoreCallingIdentity(origId);
6668            }
6669        }
6670    }
6671
6672    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6673        enforceNotIsolatedCaller("openContentUri");
6674        String name = uri.getAuthority();
6675        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6676        ParcelFileDescriptor pfd = null;
6677        if (cph != null) {
6678            // We record the binder invoker's uid in thread-local storage before
6679            // going to the content provider to open the file.  Later, in the code
6680            // that handles all permissions checks, we look for this uid and use
6681            // that rather than the Activity Manager's own uid.  The effect is that
6682            // we do the check against the caller's permissions even though it looks
6683            // to the content provider like the Activity Manager itself is making
6684            // the request.
6685            sCallerIdentity.set(new Identity(
6686                    Binder.getCallingPid(), Binder.getCallingUid()));
6687            try {
6688                pfd = cph.provider.openFile(uri, "r");
6689            } catch (FileNotFoundException e) {
6690                // do nothing; pfd will be returned null
6691            } finally {
6692                // Ensure that whatever happens, we clean up the identity state
6693                sCallerIdentity.remove();
6694            }
6695
6696            // We've got the fd now, so we're done with the provider.
6697            removeContentProviderExternalUnchecked(name, null);
6698        } else {
6699            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6700        }
6701        return pfd;
6702    }
6703
6704    // Actually is sleeping or shutting down or whatever else in the future
6705    // is an inactive state.
6706    public boolean isSleeping() {
6707        return mSleeping || mShuttingDown;
6708    }
6709
6710    public void goingToSleep() {
6711        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6712                != PackageManager.PERMISSION_GRANTED) {
6713            throw new SecurityException("Requires permission "
6714                    + android.Manifest.permission.DEVICE_POWER);
6715        }
6716
6717        synchronized(this) {
6718            mWentToSleep = true;
6719            updateEventDispatchingLocked();
6720
6721            if (!mSleeping) {
6722                mSleeping = true;
6723                mMainStack.stopIfSleepingLocked();
6724
6725                // Initialize the wake times of all processes.
6726                checkExcessivePowerUsageLocked(false);
6727                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6728                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6729                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6730            }
6731        }
6732    }
6733
6734    public boolean shutdown(int timeout) {
6735        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6736                != PackageManager.PERMISSION_GRANTED) {
6737            throw new SecurityException("Requires permission "
6738                    + android.Manifest.permission.SHUTDOWN);
6739        }
6740
6741        boolean timedout = false;
6742
6743        synchronized(this) {
6744            mShuttingDown = true;
6745            updateEventDispatchingLocked();
6746
6747            if (mMainStack.mResumedActivity != null) {
6748                mMainStack.stopIfSleepingLocked();
6749                final long endTime = System.currentTimeMillis() + timeout;
6750                while (mMainStack.mResumedActivity != null
6751                        || mMainStack.mPausingActivity != null) {
6752                    long delay = endTime - System.currentTimeMillis();
6753                    if (delay <= 0) {
6754                        Slog.w(TAG, "Activity manager shutdown timed out");
6755                        timedout = true;
6756                        break;
6757                    }
6758                    try {
6759                        this.wait();
6760                    } catch (InterruptedException e) {
6761                    }
6762                }
6763            }
6764        }
6765
6766        mUsageStatsService.shutdown();
6767        mBatteryStatsService.shutdown();
6768
6769        return timedout;
6770    }
6771
6772    public final void activitySlept(IBinder token) {
6773        if (localLOGV) Slog.v(
6774            TAG, "Activity slept: token=" + token);
6775
6776        ActivityRecord r = null;
6777
6778        final long origId = Binder.clearCallingIdentity();
6779
6780        synchronized (this) {
6781            r = mMainStack.isInStackLocked(token);
6782            if (r != null) {
6783                mMainStack.activitySleptLocked(r);
6784            }
6785        }
6786
6787        Binder.restoreCallingIdentity(origId);
6788    }
6789
6790    private void comeOutOfSleepIfNeededLocked() {
6791        if (!mWentToSleep && !mLockScreenShown) {
6792            if (mSleeping) {
6793                mSleeping = false;
6794                mMainStack.awakeFromSleepingLocked();
6795                mMainStack.resumeTopActivityLocked(null);
6796            }
6797        }
6798    }
6799
6800    public void wakingUp() {
6801        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6802                != PackageManager.PERMISSION_GRANTED) {
6803            throw new SecurityException("Requires permission "
6804                    + android.Manifest.permission.DEVICE_POWER);
6805        }
6806
6807        synchronized(this) {
6808            mWentToSleep = false;
6809            updateEventDispatchingLocked();
6810            comeOutOfSleepIfNeededLocked();
6811        }
6812    }
6813
6814    private void updateEventDispatchingLocked() {
6815        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6816    }
6817
6818    public void setLockScreenShown(boolean shown) {
6819        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6820                != PackageManager.PERMISSION_GRANTED) {
6821            throw new SecurityException("Requires permission "
6822                    + android.Manifest.permission.DEVICE_POWER);
6823        }
6824
6825        synchronized(this) {
6826            mLockScreenShown = shown;
6827            comeOutOfSleepIfNeededLocked();
6828        }
6829    }
6830
6831    public void stopAppSwitches() {
6832        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6833                != PackageManager.PERMISSION_GRANTED) {
6834            throw new SecurityException("Requires permission "
6835                    + android.Manifest.permission.STOP_APP_SWITCHES);
6836        }
6837
6838        synchronized(this) {
6839            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6840                    + APP_SWITCH_DELAY_TIME;
6841            mDidAppSwitch = false;
6842            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6843            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6844            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6845        }
6846    }
6847
6848    public void resumeAppSwitches() {
6849        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6850                != PackageManager.PERMISSION_GRANTED) {
6851            throw new SecurityException("Requires permission "
6852                    + android.Manifest.permission.STOP_APP_SWITCHES);
6853        }
6854
6855        synchronized(this) {
6856            // Note that we don't execute any pending app switches... we will
6857            // let those wait until either the timeout, or the next start
6858            // activity request.
6859            mAppSwitchesAllowedTime = 0;
6860        }
6861    }
6862
6863    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6864            String name) {
6865        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6866            return true;
6867        }
6868
6869        final int perm = checkComponentPermission(
6870                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
6871                callingUid, -1, true);
6872        if (perm == PackageManager.PERMISSION_GRANTED) {
6873            return true;
6874        }
6875
6876        Slog.w(TAG, name + " request from " + callingUid + " stopped");
6877        return false;
6878    }
6879
6880    public void setDebugApp(String packageName, boolean waitForDebugger,
6881            boolean persistent) {
6882        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6883                "setDebugApp()");
6884
6885        // Note that this is not really thread safe if there are multiple
6886        // callers into it at the same time, but that's not a situation we
6887        // care about.
6888        if (persistent) {
6889            final ContentResolver resolver = mContext.getContentResolver();
6890            Settings.System.putString(
6891                resolver, Settings.System.DEBUG_APP,
6892                packageName);
6893            Settings.System.putInt(
6894                resolver, Settings.System.WAIT_FOR_DEBUGGER,
6895                waitForDebugger ? 1 : 0);
6896        }
6897
6898        synchronized (this) {
6899            if (!persistent) {
6900                mOrigDebugApp = mDebugApp;
6901                mOrigWaitForDebugger = mWaitForDebugger;
6902            }
6903            mDebugApp = packageName;
6904            mWaitForDebugger = waitForDebugger;
6905            mDebugTransient = !persistent;
6906            if (packageName != null) {
6907                final long origId = Binder.clearCallingIdentity();
6908                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
6909                Binder.restoreCallingIdentity(origId);
6910            }
6911        }
6912    }
6913
6914    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
6915        synchronized (this) {
6916            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6917            if (!isDebuggable) {
6918                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6919                    throw new SecurityException("Process not debuggable: " + app.packageName);
6920                }
6921            }
6922
6923            mOpenGlTraceApp = processName;
6924        }
6925    }
6926
6927    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6928            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6929        synchronized (this) {
6930            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6931            if (!isDebuggable) {
6932                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6933                    throw new SecurityException("Process not debuggable: " + app.packageName);
6934                }
6935            }
6936            mProfileApp = processName;
6937            mProfileFile = profileFile;
6938            if (mProfileFd != null) {
6939                try {
6940                    mProfileFd.close();
6941                } catch (IOException e) {
6942                }
6943                mProfileFd = null;
6944            }
6945            mProfileFd = profileFd;
6946            mProfileType = 0;
6947            mAutoStopProfiler = autoStopProfiler;
6948        }
6949    }
6950
6951    public void setAlwaysFinish(boolean enabled) {
6952        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6953                "setAlwaysFinish()");
6954
6955        Settings.System.putInt(
6956                mContext.getContentResolver(),
6957                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6958
6959        synchronized (this) {
6960            mAlwaysFinishActivities = enabled;
6961        }
6962    }
6963
6964    public void setActivityController(IActivityController controller) {
6965        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
6966                "setActivityController()");
6967        synchronized (this) {
6968            mController = controller;
6969        }
6970    }
6971
6972    public boolean isUserAMonkey() {
6973        // For now the fact that there is a controller implies
6974        // we have a monkey.
6975        synchronized (this) {
6976            return mController != null;
6977        }
6978    }
6979
6980    public void registerProcessObserver(IProcessObserver observer) {
6981        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
6982                "registerProcessObserver()");
6983        synchronized (this) {
6984            mProcessObservers.register(observer);
6985        }
6986    }
6987
6988    public void unregisterProcessObserver(IProcessObserver observer) {
6989        synchronized (this) {
6990            mProcessObservers.unregister(observer);
6991        }
6992    }
6993
6994    public void setImmersive(IBinder token, boolean immersive) {
6995        synchronized(this) {
6996            ActivityRecord r = mMainStack.isInStackLocked(token);
6997            if (r == null) {
6998                throw new IllegalArgumentException();
6999            }
7000            r.immersive = immersive;
7001        }
7002    }
7003
7004    public boolean isImmersive(IBinder token) {
7005        synchronized (this) {
7006            ActivityRecord r = mMainStack.isInStackLocked(token);
7007            if (r == null) {
7008                throw new IllegalArgumentException();
7009            }
7010            return r.immersive;
7011        }
7012    }
7013
7014    public boolean isTopActivityImmersive() {
7015        enforceNotIsolatedCaller("startActivity");
7016        synchronized (this) {
7017            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7018            return (r != null) ? r.immersive : false;
7019        }
7020    }
7021
7022    public final void enterSafeMode() {
7023        synchronized(this) {
7024            // It only makes sense to do this before the system is ready
7025            // and started launching other packages.
7026            if (!mSystemReady) {
7027                try {
7028                    AppGlobals.getPackageManager().enterSafeMode();
7029                } catch (RemoteException e) {
7030                }
7031            }
7032        }
7033    }
7034
7035    public final void showSafeModeOverlay() {
7036        View v = LayoutInflater.from(mContext).inflate(
7037                com.android.internal.R.layout.safe_mode, null);
7038        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7039        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7040        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7041        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7042        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7043        lp.format = v.getBackground().getOpacity();
7044        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7045                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7046        ((WindowManager)mContext.getSystemService(
7047                Context.WINDOW_SERVICE)).addView(v, lp);
7048    }
7049
7050    public void noteWakeupAlarm(IIntentSender sender) {
7051        if (!(sender instanceof PendingIntentRecord)) {
7052            return;
7053        }
7054        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7055        synchronized (stats) {
7056            if (mBatteryStatsService.isOnBattery()) {
7057                mBatteryStatsService.enforceCallingPermission();
7058                PendingIntentRecord rec = (PendingIntentRecord)sender;
7059                int MY_UID = Binder.getCallingUid();
7060                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7061                BatteryStatsImpl.Uid.Pkg pkg =
7062                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7063                pkg.incWakeupsLocked();
7064            }
7065        }
7066    }
7067
7068    public boolean killPids(int[] pids, String pReason, boolean secure) {
7069        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7070            throw new SecurityException("killPids only available to the system");
7071        }
7072        String reason = (pReason == null) ? "Unknown" : pReason;
7073        // XXX Note: don't acquire main activity lock here, because the window
7074        // manager calls in with its locks held.
7075
7076        boolean killed = false;
7077        synchronized (mPidsSelfLocked) {
7078            int[] types = new int[pids.length];
7079            int worstType = 0;
7080            for (int i=0; i<pids.length; i++) {
7081                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7082                if (proc != null) {
7083                    int type = proc.setAdj;
7084                    types[i] = type;
7085                    if (type > worstType) {
7086                        worstType = type;
7087                    }
7088                }
7089            }
7090
7091            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7092            // then constrain it so we will kill all hidden procs.
7093            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7094                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7095                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7096            }
7097
7098            // If this is not a secure call, don't let it kill processes that
7099            // are important.
7100            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7101                worstType = ProcessList.SERVICE_ADJ;
7102            }
7103
7104            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7105            for (int i=0; i<pids.length; i++) {
7106                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7107                if (proc == null) {
7108                    continue;
7109                }
7110                int adj = proc.setAdj;
7111                if (adj >= worstType && !proc.killedBackground) {
7112                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7113                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7114                            proc.processName, adj, reason);
7115                    killed = true;
7116                    proc.killedBackground = true;
7117                    Process.killProcessQuiet(pids[i]);
7118                }
7119            }
7120        }
7121        return killed;
7122    }
7123
7124    @Override
7125    public boolean killProcessesBelowForeground(String reason) {
7126        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7127            throw new SecurityException("killProcessesBelowForeground() only available to system");
7128        }
7129
7130        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7131    }
7132
7133    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7134        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7135            throw new SecurityException("killProcessesBelowAdj() only available to system");
7136        }
7137
7138        boolean killed = false;
7139        synchronized (mPidsSelfLocked) {
7140            final int size = mPidsSelfLocked.size();
7141            for (int i = 0; i < size; i++) {
7142                final int pid = mPidsSelfLocked.keyAt(i);
7143                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7144                if (proc == null) continue;
7145
7146                final int adj = proc.setAdj;
7147                if (adj > belowAdj && !proc.killedBackground) {
7148                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7149                    EventLog.writeEvent(
7150                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7151                    killed = true;
7152                    proc.killedBackground = true;
7153                    Process.killProcessQuiet(pid);
7154                }
7155            }
7156        }
7157        return killed;
7158    }
7159
7160    public final void startRunning(String pkg, String cls, String action,
7161            String data) {
7162        synchronized(this) {
7163            if (mStartRunning) {
7164                return;
7165            }
7166            mStartRunning = true;
7167            mTopComponent = pkg != null && cls != null
7168                    ? new ComponentName(pkg, cls) : null;
7169            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7170            mTopData = data;
7171            if (!mSystemReady) {
7172                return;
7173            }
7174        }
7175
7176        systemReady(null);
7177    }
7178
7179    private void retrieveSettings() {
7180        final ContentResolver resolver = mContext.getContentResolver();
7181        String debugApp = Settings.System.getString(
7182            resolver, Settings.System.DEBUG_APP);
7183        boolean waitForDebugger = Settings.System.getInt(
7184            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7185        boolean alwaysFinishActivities = Settings.System.getInt(
7186            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7187
7188        Configuration configuration = new Configuration();
7189        Settings.System.getConfiguration(resolver, configuration);
7190
7191        synchronized (this) {
7192            mDebugApp = mOrigDebugApp = debugApp;
7193            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7194            mAlwaysFinishActivities = alwaysFinishActivities;
7195            // This happens before any activities are started, so we can
7196            // change mConfiguration in-place.
7197            updateConfigurationLocked(configuration, null, false, true);
7198            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7199        }
7200    }
7201
7202    public boolean testIsSystemReady() {
7203        // no need to synchronize(this) just to read & return the value
7204        return mSystemReady;
7205    }
7206
7207    private static File getCalledPreBootReceiversFile() {
7208        File dataDir = Environment.getDataDirectory();
7209        File systemDir = new File(dataDir, "system");
7210        File fname = new File(systemDir, "called_pre_boots.dat");
7211        return fname;
7212    }
7213
7214    static final int LAST_DONE_VERSION = 10000;
7215
7216    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7217        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7218        File file = getCalledPreBootReceiversFile();
7219        FileInputStream fis = null;
7220        try {
7221            fis = new FileInputStream(file);
7222            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7223            int fvers = dis.readInt();
7224            if (fvers == LAST_DONE_VERSION) {
7225                String vers = dis.readUTF();
7226                String codename = dis.readUTF();
7227                String build = dis.readUTF();
7228                if (android.os.Build.VERSION.RELEASE.equals(vers)
7229                        && android.os.Build.VERSION.CODENAME.equals(codename)
7230                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7231                    int num = dis.readInt();
7232                    while (num > 0) {
7233                        num--;
7234                        String pkg = dis.readUTF();
7235                        String cls = dis.readUTF();
7236                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7237                    }
7238                }
7239            }
7240        } catch (FileNotFoundException e) {
7241        } catch (IOException e) {
7242            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7243        } finally {
7244            if (fis != null) {
7245                try {
7246                    fis.close();
7247                } catch (IOException e) {
7248                }
7249            }
7250        }
7251        return lastDoneReceivers;
7252    }
7253
7254    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7255        File file = getCalledPreBootReceiversFile();
7256        FileOutputStream fos = null;
7257        DataOutputStream dos = null;
7258        try {
7259            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7260            fos = new FileOutputStream(file);
7261            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7262            dos.writeInt(LAST_DONE_VERSION);
7263            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7264            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7265            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7266            dos.writeInt(list.size());
7267            for (int i=0; i<list.size(); i++) {
7268                dos.writeUTF(list.get(i).getPackageName());
7269                dos.writeUTF(list.get(i).getClassName());
7270            }
7271        } catch (IOException e) {
7272            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7273            file.delete();
7274        } finally {
7275            FileUtils.sync(fos);
7276            if (dos != null) {
7277                try {
7278                    dos.close();
7279                } catch (IOException e) {
7280                    // TODO Auto-generated catch block
7281                    e.printStackTrace();
7282                }
7283            }
7284        }
7285    }
7286
7287    public void systemReady(final Runnable goingCallback) {
7288        synchronized(this) {
7289            if (mSystemReady) {
7290                if (goingCallback != null) goingCallback.run();
7291                return;
7292            }
7293
7294            // Check to see if there are any update receivers to run.
7295            if (!mDidUpdate) {
7296                if (mWaitingUpdate) {
7297                    return;
7298                }
7299                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7300                List<ResolveInfo> ris = null;
7301                try {
7302                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7303                            intent, null, 0, 0);
7304                } catch (RemoteException e) {
7305                }
7306                if (ris != null) {
7307                    for (int i=ris.size()-1; i>=0; i--) {
7308                        if ((ris.get(i).activityInfo.applicationInfo.flags
7309                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7310                            ris.remove(i);
7311                        }
7312                    }
7313                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7314
7315                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7316
7317                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7318                    for (int i=0; i<ris.size(); i++) {
7319                        ActivityInfo ai = ris.get(i).activityInfo;
7320                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7321                        if (lastDoneReceivers.contains(comp)) {
7322                            ris.remove(i);
7323                            i--;
7324                        }
7325                    }
7326
7327                    for (int i=0; i<ris.size(); i++) {
7328                        ActivityInfo ai = ris.get(i).activityInfo;
7329                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7330                        doneReceivers.add(comp);
7331                        intent.setComponent(comp);
7332                        IIntentReceiver finisher = null;
7333                        if (i == ris.size()-1) {
7334                            finisher = new IIntentReceiver.Stub() {
7335                                public void performReceive(Intent intent, int resultCode,
7336                                        String data, Bundle extras, boolean ordered,
7337                                        boolean sticky) {
7338                                    // The raw IIntentReceiver interface is called
7339                                    // with the AM lock held, so redispatch to
7340                                    // execute our code without the lock.
7341                                    mHandler.post(new Runnable() {
7342                                        public void run() {
7343                                            synchronized (ActivityManagerService.this) {
7344                                                mDidUpdate = true;
7345                                            }
7346                                            writeLastDonePreBootReceivers(doneReceivers);
7347                                            showBootMessage(mContext.getText(
7348                                                    R.string.android_upgrading_complete),
7349                                                    false);
7350                                            systemReady(goingCallback);
7351                                        }
7352                                    });
7353                                }
7354                            };
7355                        }
7356                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7357                        /* TODO: Send this to all users */
7358                        broadcastIntentLocked(null, null, intent, null, finisher,
7359                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7360                                0 /* UserId zero */);
7361                        if (finisher != null) {
7362                            mWaitingUpdate = true;
7363                        }
7364                    }
7365                }
7366                if (mWaitingUpdate) {
7367                    return;
7368                }
7369                mDidUpdate = true;
7370            }
7371
7372            mSystemReady = true;
7373            if (!mStartRunning) {
7374                return;
7375            }
7376        }
7377
7378        ArrayList<ProcessRecord> procsToKill = null;
7379        synchronized(mPidsSelfLocked) {
7380            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7381                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7382                if (!isAllowedWhileBooting(proc.info)){
7383                    if (procsToKill == null) {
7384                        procsToKill = new ArrayList<ProcessRecord>();
7385                    }
7386                    procsToKill.add(proc);
7387                }
7388            }
7389        }
7390
7391        synchronized(this) {
7392            if (procsToKill != null) {
7393                for (int i=procsToKill.size()-1; i>=0; i--) {
7394                    ProcessRecord proc = procsToKill.get(i);
7395                    Slog.i(TAG, "Removing system update proc: " + proc);
7396                    removeProcessLocked(proc, true, false, "system update done");
7397                }
7398            }
7399
7400            // Now that we have cleaned up any update processes, we
7401            // are ready to start launching real processes and know that
7402            // we won't trample on them any more.
7403            mProcessesReady = true;
7404        }
7405
7406        Slog.i(TAG, "System now ready");
7407        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7408            SystemClock.uptimeMillis());
7409
7410        synchronized(this) {
7411            // Make sure we have no pre-ready processes sitting around.
7412
7413            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7414                ResolveInfo ri = mContext.getPackageManager()
7415                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7416                                STOCK_PM_FLAGS);
7417                CharSequence errorMsg = null;
7418                if (ri != null) {
7419                    ActivityInfo ai = ri.activityInfo;
7420                    ApplicationInfo app = ai.applicationInfo;
7421                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7422                        mTopAction = Intent.ACTION_FACTORY_TEST;
7423                        mTopData = null;
7424                        mTopComponent = new ComponentName(app.packageName,
7425                                ai.name);
7426                    } else {
7427                        errorMsg = mContext.getResources().getText(
7428                                com.android.internal.R.string.factorytest_not_system);
7429                    }
7430                } else {
7431                    errorMsg = mContext.getResources().getText(
7432                            com.android.internal.R.string.factorytest_no_action);
7433                }
7434                if (errorMsg != null) {
7435                    mTopAction = null;
7436                    mTopData = null;
7437                    mTopComponent = null;
7438                    Message msg = Message.obtain();
7439                    msg.what = SHOW_FACTORY_ERROR_MSG;
7440                    msg.getData().putCharSequence("msg", errorMsg);
7441                    mHandler.sendMessage(msg);
7442                }
7443            }
7444        }
7445
7446        retrieveSettings();
7447
7448        if (goingCallback != null) goingCallback.run();
7449
7450        synchronized (this) {
7451            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7452                try {
7453                    List apps = AppGlobals.getPackageManager().
7454                        getPersistentApplications(STOCK_PM_FLAGS);
7455                    if (apps != null) {
7456                        int N = apps.size();
7457                        int i;
7458                        for (i=0; i<N; i++) {
7459                            ApplicationInfo info
7460                                = (ApplicationInfo)apps.get(i);
7461                            if (info != null &&
7462                                    !info.packageName.equals("android")) {
7463                                addAppLocked(info, false);
7464                            }
7465                        }
7466                    }
7467                } catch (RemoteException ex) {
7468                    // pm is in same process, this will never happen.
7469                }
7470            }
7471
7472            // Start up initial activity.
7473            mBooting = true;
7474
7475            try {
7476                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7477                    Message msg = Message.obtain();
7478                    msg.what = SHOW_UID_ERROR_MSG;
7479                    mHandler.sendMessage(msg);
7480                }
7481            } catch (RemoteException e) {
7482            }
7483
7484            mMainStack.resumeTopActivityLocked(null);
7485        }
7486    }
7487
7488    private boolean makeAppCrashingLocked(ProcessRecord app,
7489            String shortMsg, String longMsg, String stackTrace) {
7490        app.crashing = true;
7491        app.crashingReport = generateProcessError(app,
7492                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7493        startAppProblemLocked(app);
7494        app.stopFreezingAllLocked();
7495        return handleAppCrashLocked(app);
7496    }
7497
7498    private void makeAppNotRespondingLocked(ProcessRecord app,
7499            String activity, String shortMsg, String longMsg) {
7500        app.notResponding = true;
7501        app.notRespondingReport = generateProcessError(app,
7502                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7503                activity, shortMsg, longMsg, null);
7504        startAppProblemLocked(app);
7505        app.stopFreezingAllLocked();
7506    }
7507
7508    /**
7509     * Generate a process error record, suitable for attachment to a ProcessRecord.
7510     *
7511     * @param app The ProcessRecord in which the error occurred.
7512     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7513     *                      ActivityManager.AppErrorStateInfo
7514     * @param activity The activity associated with the crash, if known.
7515     * @param shortMsg Short message describing the crash.
7516     * @param longMsg Long message describing the crash.
7517     * @param stackTrace Full crash stack trace, may be null.
7518     *
7519     * @return Returns a fully-formed AppErrorStateInfo record.
7520     */
7521    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7522            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7523        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7524
7525        report.condition = condition;
7526        report.processName = app.processName;
7527        report.pid = app.pid;
7528        report.uid = app.info.uid;
7529        report.tag = activity;
7530        report.shortMsg = shortMsg;
7531        report.longMsg = longMsg;
7532        report.stackTrace = stackTrace;
7533
7534        return report;
7535    }
7536
7537    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7538        synchronized (this) {
7539            app.crashing = false;
7540            app.crashingReport = null;
7541            app.notResponding = false;
7542            app.notRespondingReport = null;
7543            if (app.anrDialog == fromDialog) {
7544                app.anrDialog = null;
7545            }
7546            if (app.waitDialog == fromDialog) {
7547                app.waitDialog = null;
7548            }
7549            if (app.pid > 0 && app.pid != MY_PID) {
7550                handleAppCrashLocked(app);
7551                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7552                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7553                        app.processName, app.setAdj, "user's request after error");
7554                Process.killProcessQuiet(app.pid);
7555            }
7556        }
7557    }
7558
7559    private boolean handleAppCrashLocked(ProcessRecord app) {
7560        if (mHeadless) {
7561            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7562            return false;
7563        }
7564        long now = SystemClock.uptimeMillis();
7565
7566        Long crashTime;
7567        if (!app.isolated) {
7568            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7569        } else {
7570            crashTime = null;
7571        }
7572        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7573            // This process loses!
7574            Slog.w(TAG, "Process " + app.info.processName
7575                    + " has crashed too many times: killing!");
7576            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7577                    app.info.processName, app.uid);
7578            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7579                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7580                if (r.app == app) {
7581                    Slog.w(TAG, "  Force finishing activity "
7582                        + r.intent.getComponent().flattenToShortString());
7583                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7584                }
7585            }
7586            if (!app.persistent) {
7587                // We don't want to start this process again until the user
7588                // explicitly does so...  but for persistent process, we really
7589                // need to keep it running.  If a persistent process is actually
7590                // repeatedly crashing, then badness for everyone.
7591                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7592                        app.info.processName);
7593                if (!app.isolated) {
7594                    // XXX We don't have a way to mark isolated processes
7595                    // as bad, since they don't have a peristent identity.
7596                    mBadProcesses.put(app.info.processName, app.uid, now);
7597                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7598                }
7599                app.bad = true;
7600                app.removed = true;
7601                // Don't let services in this process be restarted and potentially
7602                // annoy the user repeatedly.  Unless it is persistent, since those
7603                // processes run critical code.
7604                removeProcessLocked(app, false, false, "crash");
7605                mMainStack.resumeTopActivityLocked(null);
7606                return false;
7607            }
7608            mMainStack.resumeTopActivityLocked(null);
7609        } else {
7610            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7611            if (r != null && r.app == app) {
7612                // If the top running activity is from this crashing
7613                // process, then terminate it to avoid getting in a loop.
7614                Slog.w(TAG, "  Force finishing activity "
7615                        + r.intent.getComponent().flattenToShortString());
7616                int index = mMainStack.indexOfActivityLocked(r);
7617                r.stack.finishActivityLocked(r, index,
7618                        Activity.RESULT_CANCELED, null, "crashed");
7619                // Also terminate any activities below it that aren't yet
7620                // stopped, to avoid a situation where one will get
7621                // re-start our crashing activity once it gets resumed again.
7622                index--;
7623                if (index >= 0) {
7624                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7625                    if (r.state == ActivityState.RESUMED
7626                            || r.state == ActivityState.PAUSING
7627                            || r.state == ActivityState.PAUSED) {
7628                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7629                            Slog.w(TAG, "  Force finishing activity "
7630                                    + r.intent.getComponent().flattenToShortString());
7631                            r.stack.finishActivityLocked(r, index,
7632                                    Activity.RESULT_CANCELED, null, "crashed");
7633                        }
7634                    }
7635                }
7636            }
7637        }
7638
7639        // Bump up the crash count of any services currently running in the proc.
7640        if (app.services.size() != 0) {
7641            // Any services running in the application need to be placed
7642            // back in the pending list.
7643            Iterator<ServiceRecord> it = app.services.iterator();
7644            while (it.hasNext()) {
7645                ServiceRecord sr = it.next();
7646                sr.crashCount++;
7647            }
7648        }
7649
7650        // If the crashing process is what we consider to be the "home process" and it has been
7651        // replaced by a third-party app, clear the package preferred activities from packages
7652        // with a home activity running in the process to prevent a repeatedly crashing app
7653        // from blocking the user to manually clear the list.
7654        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7655                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7656            Iterator it = mHomeProcess.activities.iterator();
7657            while (it.hasNext()) {
7658                ActivityRecord r = (ActivityRecord)it.next();
7659                if (r.isHomeActivity) {
7660                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7661                    try {
7662                        ActivityThread.getPackageManager()
7663                                .clearPackagePreferredActivities(r.packageName);
7664                    } catch (RemoteException c) {
7665                        // pm is in same process, this will never happen.
7666                    }
7667                }
7668            }
7669        }
7670
7671        if (!app.isolated) {
7672            // XXX Can't keep track of crash times for isolated processes,
7673            // because they don't have a perisistent identity.
7674            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7675        }
7676
7677        return true;
7678    }
7679
7680    void startAppProblemLocked(ProcessRecord app) {
7681        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7682                mContext, app.info.packageName, app.info.flags);
7683        skipCurrentReceiverLocked(app);
7684    }
7685
7686    void skipCurrentReceiverLocked(ProcessRecord app) {
7687        for (BroadcastQueue queue : mBroadcastQueues) {
7688            queue.skipCurrentReceiverLocked(app);
7689        }
7690    }
7691
7692    /**
7693     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7694     * The application process will exit immediately after this call returns.
7695     * @param app object of the crashing app, null for the system server
7696     * @param crashInfo describing the exception
7697     */
7698    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7699        ProcessRecord r = findAppProcess(app, "Crash");
7700        final String processName = app == null ? "system_server"
7701                : (r == null ? "unknown" : r.processName);
7702
7703        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7704                processName,
7705                r == null ? -1 : r.info.flags,
7706                crashInfo.exceptionClassName,
7707                crashInfo.exceptionMessage,
7708                crashInfo.throwFileName,
7709                crashInfo.throwLineNumber);
7710
7711        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7712
7713        crashApplication(r, crashInfo);
7714    }
7715
7716    public void handleApplicationStrictModeViolation(
7717            IBinder app,
7718            int violationMask,
7719            StrictMode.ViolationInfo info) {
7720        ProcessRecord r = findAppProcess(app, "StrictMode");
7721        if (r == null) {
7722            return;
7723        }
7724
7725        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7726            Integer stackFingerprint = info.hashCode();
7727            boolean logIt = true;
7728            synchronized (mAlreadyLoggedViolatedStacks) {
7729                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7730                    logIt = false;
7731                    // TODO: sub-sample into EventLog for these, with
7732                    // the info.durationMillis?  Then we'd get
7733                    // the relative pain numbers, without logging all
7734                    // the stack traces repeatedly.  We'd want to do
7735                    // likewise in the client code, which also does
7736                    // dup suppression, before the Binder call.
7737                } else {
7738                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7739                        mAlreadyLoggedViolatedStacks.clear();
7740                    }
7741                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7742                }
7743            }
7744            if (logIt) {
7745                logStrictModeViolationToDropBox(r, info);
7746            }
7747        }
7748
7749        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7750            AppErrorResult result = new AppErrorResult();
7751            synchronized (this) {
7752                final long origId = Binder.clearCallingIdentity();
7753
7754                Message msg = Message.obtain();
7755                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7756                HashMap<String, Object> data = new HashMap<String, Object>();
7757                data.put("result", result);
7758                data.put("app", r);
7759                data.put("violationMask", violationMask);
7760                data.put("info", info);
7761                msg.obj = data;
7762                mHandler.sendMessage(msg);
7763
7764                Binder.restoreCallingIdentity(origId);
7765            }
7766            int res = result.get();
7767            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7768        }
7769    }
7770
7771    // Depending on the policy in effect, there could be a bunch of
7772    // these in quick succession so we try to batch these together to
7773    // minimize disk writes, number of dropbox entries, and maximize
7774    // compression, by having more fewer, larger records.
7775    private void logStrictModeViolationToDropBox(
7776            ProcessRecord process,
7777            StrictMode.ViolationInfo info) {
7778        if (info == null) {
7779            return;
7780        }
7781        final boolean isSystemApp = process == null ||
7782                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7783                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7784        final String processName = process == null ? "unknown" : process.processName;
7785        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7786        final DropBoxManager dbox = (DropBoxManager)
7787                mContext.getSystemService(Context.DROPBOX_SERVICE);
7788
7789        // Exit early if the dropbox isn't configured to accept this report type.
7790        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7791
7792        boolean bufferWasEmpty;
7793        boolean needsFlush;
7794        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7795        synchronized (sb) {
7796            bufferWasEmpty = sb.length() == 0;
7797            appendDropBoxProcessHeaders(process, processName, sb);
7798            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7799            sb.append("System-App: ").append(isSystemApp).append("\n");
7800            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7801            if (info.violationNumThisLoop != 0) {
7802                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7803            }
7804            if (info.numAnimationsRunning != 0) {
7805                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7806            }
7807            if (info.broadcastIntentAction != null) {
7808                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7809            }
7810            if (info.durationMillis != -1) {
7811                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7812            }
7813            if (info.numInstances != -1) {
7814                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7815            }
7816            if (info.tags != null) {
7817                for (String tag : info.tags) {
7818                    sb.append("Span-Tag: ").append(tag).append("\n");
7819                }
7820            }
7821            sb.append("\n");
7822            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7823                sb.append(info.crashInfo.stackTrace);
7824            }
7825            sb.append("\n");
7826
7827            // Only buffer up to ~64k.  Various logging bits truncate
7828            // things at 128k.
7829            needsFlush = (sb.length() > 64 * 1024);
7830        }
7831
7832        // Flush immediately if the buffer's grown too large, or this
7833        // is a non-system app.  Non-system apps are isolated with a
7834        // different tag & policy and not batched.
7835        //
7836        // Batching is useful during internal testing with
7837        // StrictMode settings turned up high.  Without batching,
7838        // thousands of separate files could be created on boot.
7839        if (!isSystemApp || needsFlush) {
7840            new Thread("Error dump: " + dropboxTag) {
7841                @Override
7842                public void run() {
7843                    String report;
7844                    synchronized (sb) {
7845                        report = sb.toString();
7846                        sb.delete(0, sb.length());
7847                        sb.trimToSize();
7848                    }
7849                    if (report.length() != 0) {
7850                        dbox.addText(dropboxTag, report);
7851                    }
7852                }
7853            }.start();
7854            return;
7855        }
7856
7857        // System app batching:
7858        if (!bufferWasEmpty) {
7859            // An existing dropbox-writing thread is outstanding, so
7860            // we don't need to start it up.  The existing thread will
7861            // catch the buffer appends we just did.
7862            return;
7863        }
7864
7865        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7866        // (After this point, we shouldn't access AMS internal data structures.)
7867        new Thread("Error dump: " + dropboxTag) {
7868            @Override
7869            public void run() {
7870                // 5 second sleep to let stacks arrive and be batched together
7871                try {
7872                    Thread.sleep(5000);  // 5 seconds
7873                } catch (InterruptedException e) {}
7874
7875                String errorReport;
7876                synchronized (mStrictModeBuffer) {
7877                    errorReport = mStrictModeBuffer.toString();
7878                    if (errorReport.length() == 0) {
7879                        return;
7880                    }
7881                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7882                    mStrictModeBuffer.trimToSize();
7883                }
7884                dbox.addText(dropboxTag, errorReport);
7885            }
7886        }.start();
7887    }
7888
7889    /**
7890     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7891     * @param app object of the crashing app, null for the system server
7892     * @param tag reported by the caller
7893     * @param crashInfo describing the context of the error
7894     * @return true if the process should exit immediately (WTF is fatal)
7895     */
7896    public boolean handleApplicationWtf(IBinder app, String tag,
7897            ApplicationErrorReport.CrashInfo crashInfo) {
7898        ProcessRecord r = findAppProcess(app, "WTF");
7899        final String processName = app == null ? "system_server"
7900                : (r == null ? "unknown" : r.processName);
7901
7902        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7903                processName,
7904                r == null ? -1 : r.info.flags,
7905                tag, crashInfo.exceptionMessage);
7906
7907        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
7908
7909        if (r != null && r.pid != Process.myPid() &&
7910                Settings.Secure.getInt(mContext.getContentResolver(),
7911                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
7912            crashApplication(r, crashInfo);
7913            return true;
7914        } else {
7915            return false;
7916        }
7917    }
7918
7919    /**
7920     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7921     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7922     */
7923    private ProcessRecord findAppProcess(IBinder app, String reason) {
7924        if (app == null) {
7925            return null;
7926        }
7927
7928        synchronized (this) {
7929            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7930                final int NA = apps.size();
7931                for (int ia=0; ia<NA; ia++) {
7932                    ProcessRecord p = apps.valueAt(ia);
7933                    if (p.thread != null && p.thread.asBinder() == app) {
7934                        return p;
7935                    }
7936                }
7937            }
7938
7939            Slog.w(TAG, "Can't find mystery application for " + reason
7940                    + " from pid=" + Binder.getCallingPid()
7941                    + " uid=" + Binder.getCallingUid() + ": " + app);
7942            return null;
7943        }
7944    }
7945
7946    /**
7947     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7948     * to append various headers to the dropbox log text.
7949     */
7950    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7951            StringBuilder sb) {
7952        // Watchdog thread ends up invoking this function (with
7953        // a null ProcessRecord) to add the stack file to dropbox.
7954        // Do not acquire a lock on this (am) in such cases, as it
7955        // could cause a potential deadlock, if and when watchdog
7956        // is invoked due to unavailability of lock on am and it
7957        // would prevent watchdog from killing system_server.
7958        if (process == null) {
7959            sb.append("Process: ").append(processName).append("\n");
7960            return;
7961        }
7962        // Note: ProcessRecord 'process' is guarded by the service
7963        // instance.  (notably process.pkgList, which could otherwise change
7964        // concurrently during execution of this method)
7965        synchronized (this) {
7966            sb.append("Process: ").append(processName).append("\n");
7967            int flags = process.info.flags;
7968            IPackageManager pm = AppGlobals.getPackageManager();
7969            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7970            for (String pkg : process.pkgList) {
7971                sb.append("Package: ").append(pkg);
7972                try {
7973                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
7974                    if (pi != null) {
7975                        sb.append(" v").append(pi.versionCode);
7976                        if (pi.versionName != null) {
7977                            sb.append(" (").append(pi.versionName).append(")");
7978                        }
7979                    }
7980                } catch (RemoteException e) {
7981                    Slog.e(TAG, "Error getting package info: " + pkg, e);
7982                }
7983                sb.append("\n");
7984            }
7985        }
7986    }
7987
7988    private static String processClass(ProcessRecord process) {
7989        if (process == null || process.pid == MY_PID) {
7990            return "system_server";
7991        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7992            return "system_app";
7993        } else {
7994            return "data_app";
7995        }
7996    }
7997
7998    /**
7999     * Write a description of an error (crash, WTF, ANR) to the drop box.
8000     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8001     * @param process which caused the error, null means the system server
8002     * @param activity which triggered the error, null if unknown
8003     * @param parent activity related to the error, null if unknown
8004     * @param subject line related to the error, null if absent
8005     * @param report in long form describing the error, null if absent
8006     * @param logFile to include in the report, null if none
8007     * @param crashInfo giving an application stack trace, null if absent
8008     */
8009    public void addErrorToDropBox(String eventType,
8010            ProcessRecord process, String processName, ActivityRecord activity,
8011            ActivityRecord parent, String subject,
8012            final String report, final File logFile,
8013            final ApplicationErrorReport.CrashInfo crashInfo) {
8014        // NOTE -- this must never acquire the ActivityManagerService lock,
8015        // otherwise the watchdog may be prevented from resetting the system.
8016
8017        final String dropboxTag = processClass(process) + "_" + eventType;
8018        final DropBoxManager dbox = (DropBoxManager)
8019                mContext.getSystemService(Context.DROPBOX_SERVICE);
8020
8021        // Exit early if the dropbox isn't configured to accept this report type.
8022        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8023
8024        final StringBuilder sb = new StringBuilder(1024);
8025        appendDropBoxProcessHeaders(process, processName, sb);
8026        if (activity != null) {
8027            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8028        }
8029        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8030            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8031        }
8032        if (parent != null && parent != activity) {
8033            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8034        }
8035        if (subject != null) {
8036            sb.append("Subject: ").append(subject).append("\n");
8037        }
8038        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8039        if (Debug.isDebuggerConnected()) {
8040            sb.append("Debugger: Connected\n");
8041        }
8042        sb.append("\n");
8043
8044        // Do the rest in a worker thread to avoid blocking the caller on I/O
8045        // (After this point, we shouldn't access AMS internal data structures.)
8046        Thread worker = new Thread("Error dump: " + dropboxTag) {
8047            @Override
8048            public void run() {
8049                if (report != null) {
8050                    sb.append(report);
8051                }
8052                if (logFile != null) {
8053                    try {
8054                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8055                    } catch (IOException e) {
8056                        Slog.e(TAG, "Error reading " + logFile, e);
8057                    }
8058                }
8059                if (crashInfo != null && crashInfo.stackTrace != null) {
8060                    sb.append(crashInfo.stackTrace);
8061                }
8062
8063                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8064                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8065                if (lines > 0) {
8066                    sb.append("\n");
8067
8068                    // Merge several logcat streams, and take the last N lines
8069                    InputStreamReader input = null;
8070                    try {
8071                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8072                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8073                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8074
8075                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8076                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8077                        input = new InputStreamReader(logcat.getInputStream());
8078
8079                        int num;
8080                        char[] buf = new char[8192];
8081                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8082                    } catch (IOException e) {
8083                        Slog.e(TAG, "Error running logcat", e);
8084                    } finally {
8085                        if (input != null) try { input.close(); } catch (IOException e) {}
8086                    }
8087                }
8088
8089                dbox.addText(dropboxTag, sb.toString());
8090            }
8091        };
8092
8093        if (process == null) {
8094            // If process is null, we are being called from some internal code
8095            // and may be about to die -- run this synchronously.
8096            worker.run();
8097        } else {
8098            worker.start();
8099        }
8100    }
8101
8102    /**
8103     * Bring up the "unexpected error" dialog box for a crashing app.
8104     * Deal with edge cases (intercepts from instrumented applications,
8105     * ActivityController, error intent receivers, that sort of thing).
8106     * @param r the application crashing
8107     * @param crashInfo describing the failure
8108     */
8109    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8110        long timeMillis = System.currentTimeMillis();
8111        String shortMsg = crashInfo.exceptionClassName;
8112        String longMsg = crashInfo.exceptionMessage;
8113        String stackTrace = crashInfo.stackTrace;
8114        if (shortMsg != null && longMsg != null) {
8115            longMsg = shortMsg + ": " + longMsg;
8116        } else if (shortMsg != null) {
8117            longMsg = shortMsg;
8118        }
8119
8120        AppErrorResult result = new AppErrorResult();
8121        synchronized (this) {
8122            if (mController != null) {
8123                try {
8124                    String name = r != null ? r.processName : null;
8125                    int pid = r != null ? r.pid : Binder.getCallingPid();
8126                    if (!mController.appCrashed(name, pid,
8127                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8128                        Slog.w(TAG, "Force-killing crashed app " + name
8129                                + " at watcher's request");
8130                        Process.killProcess(pid);
8131                        return;
8132                    }
8133                } catch (RemoteException e) {
8134                    mController = null;
8135                }
8136            }
8137
8138            final long origId = Binder.clearCallingIdentity();
8139
8140            // If this process is running instrumentation, finish it.
8141            if (r != null && r.instrumentationClass != null) {
8142                Slog.w(TAG, "Error in app " + r.processName
8143                      + " running instrumentation " + r.instrumentationClass + ":");
8144                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8145                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8146                Bundle info = new Bundle();
8147                info.putString("shortMsg", shortMsg);
8148                info.putString("longMsg", longMsg);
8149                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8150                Binder.restoreCallingIdentity(origId);
8151                return;
8152            }
8153
8154            // If we can't identify the process or it's already exceeded its crash quota,
8155            // quit right away without showing a crash dialog.
8156            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8157                Binder.restoreCallingIdentity(origId);
8158                return;
8159            }
8160
8161            Message msg = Message.obtain();
8162            msg.what = SHOW_ERROR_MSG;
8163            HashMap data = new HashMap();
8164            data.put("result", result);
8165            data.put("app", r);
8166            msg.obj = data;
8167            mHandler.sendMessage(msg);
8168
8169            Binder.restoreCallingIdentity(origId);
8170        }
8171
8172        int res = result.get();
8173
8174        Intent appErrorIntent = null;
8175        synchronized (this) {
8176            if (r != null && !r.isolated) {
8177                // XXX Can't keep track of crash time for isolated processes,
8178                // since they don't have a persistent identity.
8179                mProcessCrashTimes.put(r.info.processName, r.uid,
8180                        SystemClock.uptimeMillis());
8181            }
8182            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8183                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8184            }
8185        }
8186
8187        if (appErrorIntent != null) {
8188            try {
8189                mContext.startActivity(appErrorIntent);
8190            } catch (ActivityNotFoundException e) {
8191                Slog.w(TAG, "bug report receiver dissappeared", e);
8192            }
8193        }
8194    }
8195
8196    Intent createAppErrorIntentLocked(ProcessRecord r,
8197            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8198        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8199        if (report == null) {
8200            return null;
8201        }
8202        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8203        result.setComponent(r.errorReportReceiver);
8204        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8205        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8206        return result;
8207    }
8208
8209    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8210            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8211        if (r.errorReportReceiver == null) {
8212            return null;
8213        }
8214
8215        if (!r.crashing && !r.notResponding) {
8216            return null;
8217        }
8218
8219        ApplicationErrorReport report = new ApplicationErrorReport();
8220        report.packageName = r.info.packageName;
8221        report.installerPackageName = r.errorReportReceiver.getPackageName();
8222        report.processName = r.processName;
8223        report.time = timeMillis;
8224        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8225
8226        if (r.crashing) {
8227            report.type = ApplicationErrorReport.TYPE_CRASH;
8228            report.crashInfo = crashInfo;
8229        } else if (r.notResponding) {
8230            report.type = ApplicationErrorReport.TYPE_ANR;
8231            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8232
8233            report.anrInfo.activity = r.notRespondingReport.tag;
8234            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8235            report.anrInfo.info = r.notRespondingReport.longMsg;
8236        }
8237
8238        return report;
8239    }
8240
8241    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8242        enforceNotIsolatedCaller("getProcessesInErrorState");
8243        // assume our apps are happy - lazy create the list
8244        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8245
8246        synchronized (this) {
8247
8248            // iterate across all processes
8249            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8250                ProcessRecord app = mLruProcesses.get(i);
8251                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8252                    // This one's in trouble, so we'll generate a report for it
8253                    // crashes are higher priority (in case there's a crash *and* an anr)
8254                    ActivityManager.ProcessErrorStateInfo report = null;
8255                    if (app.crashing) {
8256                        report = app.crashingReport;
8257                    } else if (app.notResponding) {
8258                        report = app.notRespondingReport;
8259                    }
8260
8261                    if (report != null) {
8262                        if (errList == null) {
8263                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8264                        }
8265                        errList.add(report);
8266                    } else {
8267                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8268                                " crashing = " + app.crashing +
8269                                " notResponding = " + app.notResponding);
8270                    }
8271                }
8272            }
8273        }
8274
8275        return errList;
8276    }
8277
8278    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8279        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8280            if (currApp != null) {
8281                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8282            }
8283            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8284        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8285            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8286        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8287            if (currApp != null) {
8288                currApp.lru = 0;
8289            }
8290            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8291        } else if (adj >= ProcessList.SERVICE_ADJ) {
8292            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8293        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8294            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8295        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8296            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8297        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8298            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8299        } else {
8300            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8301        }
8302    }
8303
8304    private void fillInProcMemInfo(ProcessRecord app,
8305            ActivityManager.RunningAppProcessInfo outInfo) {
8306        outInfo.pid = app.pid;
8307        outInfo.uid = app.info.uid;
8308        if (mHeavyWeightProcess == app) {
8309            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8310        }
8311        if (app.persistent) {
8312            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8313        }
8314        outInfo.lastTrimLevel = app.trimMemoryLevel;
8315        int adj = app.curAdj;
8316        outInfo.importance = oomAdjToImportance(adj, outInfo);
8317        outInfo.importanceReasonCode = app.adjTypeCode;
8318    }
8319
8320    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8321        enforceNotIsolatedCaller("getRunningAppProcesses");
8322        // Lazy instantiation of list
8323        List<ActivityManager.RunningAppProcessInfo> runList = null;
8324        synchronized (this) {
8325            // Iterate across all processes
8326            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8327                ProcessRecord app = mLruProcesses.get(i);
8328                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8329                    // Generate process state info for running application
8330                    ActivityManager.RunningAppProcessInfo currApp =
8331                        new ActivityManager.RunningAppProcessInfo(app.processName,
8332                                app.pid, app.getPackageList());
8333                    fillInProcMemInfo(app, currApp);
8334                    if (app.adjSource instanceof ProcessRecord) {
8335                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8336                        currApp.importanceReasonImportance = oomAdjToImportance(
8337                                app.adjSourceOom, null);
8338                    } else if (app.adjSource instanceof ActivityRecord) {
8339                        ActivityRecord r = (ActivityRecord)app.adjSource;
8340                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8341                    }
8342                    if (app.adjTarget instanceof ComponentName) {
8343                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8344                    }
8345                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8346                    //        + " lru=" + currApp.lru);
8347                    if (runList == null) {
8348                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8349                    }
8350                    runList.add(currApp);
8351                }
8352            }
8353        }
8354        return runList;
8355    }
8356
8357    public List<ApplicationInfo> getRunningExternalApplications() {
8358        enforceNotIsolatedCaller("getRunningExternalApplications");
8359        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8360        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8361        if (runningApps != null && runningApps.size() > 0) {
8362            Set<String> extList = new HashSet<String>();
8363            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8364                if (app.pkgList != null) {
8365                    for (String pkg : app.pkgList) {
8366                        extList.add(pkg);
8367                    }
8368                }
8369            }
8370            IPackageManager pm = AppGlobals.getPackageManager();
8371            for (String pkg : extList) {
8372                try {
8373                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8374                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8375                        retList.add(info);
8376                    }
8377                } catch (RemoteException e) {
8378                }
8379            }
8380        }
8381        return retList;
8382    }
8383
8384    @Override
8385    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8386        enforceNotIsolatedCaller("getMyMemoryState");
8387        synchronized (this) {
8388            ProcessRecord proc;
8389            synchronized (mPidsSelfLocked) {
8390                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8391            }
8392            fillInProcMemInfo(proc, outInfo);
8393        }
8394    }
8395
8396    @Override
8397    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8398        if (checkCallingPermission(android.Manifest.permission.DUMP)
8399                != PackageManager.PERMISSION_GRANTED) {
8400            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8401                    + Binder.getCallingPid()
8402                    + ", uid=" + Binder.getCallingUid()
8403                    + " without permission "
8404                    + android.Manifest.permission.DUMP);
8405            return;
8406        }
8407
8408        boolean dumpAll = false;
8409        boolean dumpClient = false;
8410        String dumpPackage = null;
8411
8412        int opti = 0;
8413        while (opti < args.length) {
8414            String opt = args[opti];
8415            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8416                break;
8417            }
8418            opti++;
8419            if ("-a".equals(opt)) {
8420                dumpAll = true;
8421            } else if ("-c".equals(opt)) {
8422                dumpClient = true;
8423            } else if ("-h".equals(opt)) {
8424                pw.println("Activity manager dump options:");
8425                pw.println("  [-a] [-c] [-h] [cmd] ...");
8426                pw.println("  cmd may be one of:");
8427                pw.println("    a[ctivities]: activity stack state");
8428                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8429                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8430                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8431                pw.println("    o[om]: out of memory management");
8432                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8433                pw.println("    provider [COMP_SPEC]: provider client-side state");
8434                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8435                pw.println("    service [COMP_SPEC]: service client-side state");
8436                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8437                pw.println("    all: dump all activities");
8438                pw.println("    top: dump the top activity");
8439                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8440                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8441                pw.println("    a partial substring in a component name, a");
8442                pw.println("    hex object identifier.");
8443                pw.println("  -a: include all available server state.");
8444                pw.println("  -c: include client state.");
8445                return;
8446            } else {
8447                pw.println("Unknown argument: " + opt + "; use -h for help");
8448            }
8449        }
8450
8451        long origId = Binder.clearCallingIdentity();
8452        boolean more = false;
8453        // Is the caller requesting to dump a particular piece of data?
8454        if (opti < args.length) {
8455            String cmd = args[opti];
8456            opti++;
8457            if ("activities".equals(cmd) || "a".equals(cmd)) {
8458                synchronized (this) {
8459                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8460                }
8461            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8462                String[] newArgs;
8463                String name;
8464                if (opti >= args.length) {
8465                    name = null;
8466                    newArgs = EMPTY_STRING_ARRAY;
8467                } else {
8468                    name = args[opti];
8469                    opti++;
8470                    newArgs = new String[args.length - opti];
8471                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8472                            args.length - opti);
8473                }
8474                synchronized (this) {
8475                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8476                }
8477            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8478                String[] newArgs;
8479                String name;
8480                if (opti >= args.length) {
8481                    name = null;
8482                    newArgs = EMPTY_STRING_ARRAY;
8483                } else {
8484                    name = args[opti];
8485                    opti++;
8486                    newArgs = new String[args.length - opti];
8487                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8488                            args.length - opti);
8489                }
8490                synchronized (this) {
8491                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8492                }
8493            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8494                String[] newArgs;
8495                String name;
8496                if (opti >= args.length) {
8497                    name = null;
8498                    newArgs = EMPTY_STRING_ARRAY;
8499                } else {
8500                    name = args[opti];
8501                    opti++;
8502                    newArgs = new String[args.length - opti];
8503                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8504                            args.length - opti);
8505                }
8506                synchronized (this) {
8507                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8508                }
8509            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8510                synchronized (this) {
8511                    dumpOomLocked(fd, pw, args, opti, true);
8512                }
8513            } else if ("provider".equals(cmd)) {
8514                String[] newArgs;
8515                String name;
8516                if (opti >= args.length) {
8517                    name = null;
8518                    newArgs = EMPTY_STRING_ARRAY;
8519                } else {
8520                    name = args[opti];
8521                    opti++;
8522                    newArgs = new String[args.length - opti];
8523                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8524                }
8525                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8526                    pw.println("No providers match: " + name);
8527                    pw.println("Use -h for help.");
8528                }
8529            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8530                synchronized (this) {
8531                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8532                }
8533            } else if ("service".equals(cmd)) {
8534                String[] newArgs;
8535                String name;
8536                if (opti >= args.length) {
8537                    name = null;
8538                    newArgs = EMPTY_STRING_ARRAY;
8539                } else {
8540                    name = args[opti];
8541                    opti++;
8542                    newArgs = new String[args.length - opti];
8543                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8544                            args.length - opti);
8545                }
8546                if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8547                    pw.println("No services match: " + name);
8548                    pw.println("Use -h for help.");
8549                }
8550            } else if ("package".equals(cmd)) {
8551                String[] newArgs;
8552                if (opti >= args.length) {
8553                    pw.println("package: no package name specified");
8554                    pw.println("Use -h for help.");
8555                } else {
8556                    dumpPackage = args[opti];
8557                    opti++;
8558                    newArgs = new String[args.length - opti];
8559                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8560                            args.length - opti);
8561                    args = newArgs;
8562                    opti = 0;
8563                    more = true;
8564                }
8565            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8566                synchronized (this) {
8567                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8568                }
8569            } else {
8570                // Dumping a single activity?
8571                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8572                    pw.println("Bad activity command, or no activities match: " + cmd);
8573                    pw.println("Use -h for help.");
8574                }
8575            }
8576            if (!more) {
8577                Binder.restoreCallingIdentity(origId);
8578                return;
8579            }
8580        }
8581
8582        // No piece of data specified, dump everything.
8583        synchronized (this) {
8584            boolean needSep;
8585            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8586            if (needSep) {
8587                pw.println(" ");
8588            }
8589            if (dumpAll) {
8590                pw.println("-------------------------------------------------------------------------------");
8591            }
8592            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8593            if (needSep) {
8594                pw.println(" ");
8595            }
8596            if (dumpAll) {
8597                pw.println("-------------------------------------------------------------------------------");
8598            }
8599            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8600            if (needSep) {
8601                pw.println(" ");
8602            }
8603            if (dumpAll) {
8604                pw.println("-------------------------------------------------------------------------------");
8605            }
8606            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8607            if (needSep) {
8608                pw.println(" ");
8609            }
8610            if (dumpAll) {
8611                pw.println("-------------------------------------------------------------------------------");
8612            }
8613            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8614            if (needSep) {
8615                pw.println(" ");
8616            }
8617            if (dumpAll) {
8618                pw.println("-------------------------------------------------------------------------------");
8619            }
8620            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8621        }
8622        Binder.restoreCallingIdentity(origId);
8623    }
8624
8625    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8626            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8627        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8628        pw.println("  Main stack:");
8629        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8630                dumpPackage);
8631        pw.println(" ");
8632        pw.println("  Running activities (most recent first):");
8633        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8634                dumpPackage);
8635        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8636            pw.println(" ");
8637            pw.println("  Activities waiting for another to become visible:");
8638            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8639                    !dumpAll, false, dumpPackage);
8640        }
8641        if (mMainStack.mStoppingActivities.size() > 0) {
8642            pw.println(" ");
8643            pw.println("  Activities waiting to stop:");
8644            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8645                    !dumpAll, false, dumpPackage);
8646        }
8647        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8648            pw.println(" ");
8649            pw.println("  Activities waiting to sleep:");
8650            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8651                    !dumpAll, false, dumpPackage);
8652        }
8653        if (mMainStack.mFinishingActivities.size() > 0) {
8654            pw.println(" ");
8655            pw.println("  Activities waiting to finish:");
8656            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8657                    !dumpAll, false, dumpPackage);
8658        }
8659
8660        pw.println(" ");
8661        if (mMainStack.mPausingActivity != null) {
8662            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8663        }
8664        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8665        pw.println("  mFocusedActivity: " + mFocusedActivity);
8666        if (dumpAll) {
8667            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8668            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8669            pw.println("  mDismissKeyguardOnNextActivity: "
8670                    + mMainStack.mDismissKeyguardOnNextActivity);
8671        }
8672
8673        if (mRecentTasks.size() > 0) {
8674            pw.println();
8675            pw.println("  Recent tasks:");
8676
8677            final int N = mRecentTasks.size();
8678            for (int i=0; i<N; i++) {
8679                TaskRecord tr = mRecentTasks.get(i);
8680                if (dumpPackage != null) {
8681                    if (tr.realActivity == null ||
8682                            !dumpPackage.equals(tr.realActivity)) {
8683                        continue;
8684                    }
8685                }
8686                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8687                        pw.println(tr);
8688                if (dumpAll) {
8689                    mRecentTasks.get(i).dump(pw, "    ");
8690                }
8691            }
8692        }
8693
8694        if (dumpAll) {
8695            pw.println(" ");
8696            pw.println("  mCurTask: " + mCurTask);
8697        }
8698
8699        return true;
8700    }
8701
8702    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8703            int opti, boolean dumpAll, String dumpPackage) {
8704        boolean needSep = false;
8705        int numPers = 0;
8706
8707        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8708
8709        if (dumpAll) {
8710            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8711                final int NA = procs.size();
8712                for (int ia=0; ia<NA; ia++) {
8713                    ProcessRecord r = procs.valueAt(ia);
8714                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8715                        continue;
8716                    }
8717                    if (!needSep) {
8718                        pw.println("  All known processes:");
8719                        needSep = true;
8720                    }
8721                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8722                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8723                        pw.print(" "); pw.println(r);
8724                    r.dump(pw, "    ");
8725                    if (r.persistent) {
8726                        numPers++;
8727                    }
8728                }
8729            }
8730        }
8731
8732        if (mIsolatedProcesses.size() > 0) {
8733            if (needSep) pw.println(" ");
8734            needSep = true;
8735            pw.println("  Isolated process list (sorted by uid):");
8736            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8737                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8738                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8739                    continue;
8740                }
8741                pw.println(String.format("%sIsolated #%2d: %s",
8742                        "    ", i, r.toString()));
8743            }
8744        }
8745
8746        if (mLruProcesses.size() > 0) {
8747            if (needSep) pw.println(" ");
8748            needSep = true;
8749            pw.println("  Process LRU list (sorted by oom_adj):");
8750            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8751                    "Proc", "PERS", false, dumpPackage);
8752            needSep = true;
8753        }
8754
8755        if (dumpAll) {
8756            synchronized (mPidsSelfLocked) {
8757                boolean printed = false;
8758                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8759                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8760                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8761                        continue;
8762                    }
8763                    if (!printed) {
8764                        if (needSep) pw.println(" ");
8765                        needSep = true;
8766                        pw.println("  PID mappings:");
8767                        printed = true;
8768                    }
8769                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8770                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8771                }
8772            }
8773        }
8774
8775        if (mForegroundProcesses.size() > 0) {
8776            synchronized (mPidsSelfLocked) {
8777                boolean printed = false;
8778                for (int i=0; i<mForegroundProcesses.size(); i++) {
8779                    ProcessRecord r = mPidsSelfLocked.get(
8780                            mForegroundProcesses.valueAt(i).pid);
8781                    if (dumpPackage != null && (r == null
8782                            || !dumpPackage.equals(r.info.packageName))) {
8783                        continue;
8784                    }
8785                    if (!printed) {
8786                        if (needSep) pw.println(" ");
8787                        needSep = true;
8788                        pw.println("  Foreground Processes:");
8789                        printed = true;
8790                    }
8791                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8792                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8793                }
8794            }
8795        }
8796
8797        if (mPersistentStartingProcesses.size() > 0) {
8798            if (needSep) pw.println(" ");
8799            needSep = true;
8800            pw.println("  Persisent processes that are starting:");
8801            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8802                    "Starting Norm", "Restarting PERS", dumpPackage);
8803        }
8804
8805        if (mRemovedProcesses.size() > 0) {
8806            if (needSep) pw.println(" ");
8807            needSep = true;
8808            pw.println("  Processes that are being removed:");
8809            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8810                    "Removed Norm", "Removed PERS", dumpPackage);
8811        }
8812
8813        if (mProcessesOnHold.size() > 0) {
8814            if (needSep) pw.println(" ");
8815            needSep = true;
8816            pw.println("  Processes that are on old until the system is ready:");
8817            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8818                    "OnHold Norm", "OnHold PERS", dumpPackage);
8819        }
8820
8821        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8822
8823        if (mProcessCrashTimes.getMap().size() > 0) {
8824            boolean printed = false;
8825            long now = SystemClock.uptimeMillis();
8826            for (Map.Entry<String, SparseArray<Long>> procs
8827                    : mProcessCrashTimes.getMap().entrySet()) {
8828                String pname = procs.getKey();
8829                SparseArray<Long> uids = procs.getValue();
8830                final int N = uids.size();
8831                for (int i=0; i<N; i++) {
8832                    int puid = uids.keyAt(i);
8833                    ProcessRecord r = mProcessNames.get(pname, puid);
8834                    if (dumpPackage != null && (r == null
8835                            || !dumpPackage.equals(r.info.packageName))) {
8836                        continue;
8837                    }
8838                    if (!printed) {
8839                        if (needSep) pw.println(" ");
8840                        needSep = true;
8841                        pw.println("  Time since processes crashed:");
8842                        printed = true;
8843                    }
8844                    pw.print("    Process "); pw.print(pname);
8845                            pw.print(" uid "); pw.print(puid);
8846                            pw.print(": last crashed ");
8847                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
8848                            pw.println(" ago");
8849                }
8850            }
8851        }
8852
8853        if (mBadProcesses.getMap().size() > 0) {
8854            boolean printed = false;
8855            for (Map.Entry<String, SparseArray<Long>> procs
8856                    : mBadProcesses.getMap().entrySet()) {
8857                String pname = procs.getKey();
8858                SparseArray<Long> uids = procs.getValue();
8859                final int N = uids.size();
8860                for (int i=0; i<N; i++) {
8861                    int puid = uids.keyAt(i);
8862                    ProcessRecord r = mProcessNames.get(pname, puid);
8863                    if (dumpPackage != null && (r == null
8864                            || !dumpPackage.equals(r.info.packageName))) {
8865                        continue;
8866                    }
8867                    if (!printed) {
8868                        if (needSep) pw.println(" ");
8869                        needSep = true;
8870                        pw.println("  Bad processes:");
8871                    }
8872                    pw.print("    Bad process "); pw.print(pname);
8873                            pw.print(" uid "); pw.print(puid);
8874                            pw.print(": crashed at time ");
8875                            pw.println(uids.valueAt(i));
8876                }
8877            }
8878        }
8879
8880        pw.println();
8881        pw.println("  mHomeProcess: " + mHomeProcess);
8882        pw.println("  mPreviousProcess: " + mPreviousProcess);
8883        if (dumpAll) {
8884            StringBuilder sb = new StringBuilder(128);
8885            sb.append("  mPreviousProcessVisibleTime: ");
8886            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
8887            pw.println(sb);
8888        }
8889        if (mHeavyWeightProcess != null) {
8890            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
8891        }
8892        pw.println("  mConfiguration: " + mConfiguration);
8893        if (dumpAll) {
8894            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
8895            if (mCompatModePackages.getPackages().size() > 0) {
8896                boolean printed = false;
8897                for (Map.Entry<String, Integer> entry
8898                        : mCompatModePackages.getPackages().entrySet()) {
8899                    String pkg = entry.getKey();
8900                    int mode = entry.getValue();
8901                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8902                        continue;
8903                    }
8904                    if (!printed) {
8905                        pw.println("  mScreenCompatPackages:");
8906                        printed = true;
8907                    }
8908                    pw.print("    "); pw.print(pkg); pw.print(": ");
8909                            pw.print(mode); pw.println();
8910                }
8911            }
8912        }
8913        if (mSleeping || mWentToSleep || mLockScreenShown) {
8914            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
8915                    + " mLockScreenShown " + mLockScreenShown);
8916        }
8917        if (mShuttingDown) {
8918            pw.println("  mShuttingDown=" + mShuttingDown);
8919        }
8920        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8921                || mOrigWaitForDebugger) {
8922            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8923                    + " mDebugTransient=" + mDebugTransient
8924                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8925        }
8926        if (mOpenGlTraceApp != null) {
8927            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
8928        }
8929        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8930                || mProfileFd != null) {
8931            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8932            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8933            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
8934                    + mAutoStopProfiler);
8935        }
8936        if (mAlwaysFinishActivities || mController != null) {
8937            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
8938                    + " mController=" + mController);
8939        }
8940        if (dumpAll) {
8941            pw.println("  Total persistent processes: " + numPers);
8942            pw.println("  mStartRunning=" + mStartRunning
8943                    + " mProcessesReady=" + mProcessesReady
8944                    + " mSystemReady=" + mSystemReady);
8945            pw.println("  mBooting=" + mBooting
8946                    + " mBooted=" + mBooted
8947                    + " mFactoryTest=" + mFactoryTest);
8948            pw.print("  mLastPowerCheckRealtime=");
8949                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8950                    pw.println("");
8951            pw.print("  mLastPowerCheckUptime=");
8952                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8953                    pw.println("");
8954            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
8955            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
8956            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
8957            pw.println("  mNumServiceProcs=" + mNumServiceProcs
8958                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
8959        }
8960
8961        return true;
8962    }
8963
8964    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8965            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
8966        if (mProcessesToGc.size() > 0) {
8967            boolean printed = false;
8968            long now = SystemClock.uptimeMillis();
8969            for (int i=0; i<mProcessesToGc.size(); i++) {
8970                ProcessRecord proc = mProcessesToGc.get(i);
8971                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8972                    continue;
8973                }
8974                if (!printed) {
8975                    if (needSep) pw.println(" ");
8976                    needSep = true;
8977                    pw.println("  Processes that are waiting to GC:");
8978                    printed = true;
8979                }
8980                pw.print("    Process "); pw.println(proc);
8981                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
8982                        pw.print(", last gced=");
8983                        pw.print(now-proc.lastRequestedGc);
8984                        pw.print(" ms ago, last lowMem=");
8985                        pw.print(now-proc.lastLowMemory);
8986                        pw.println(" ms ago");
8987
8988            }
8989        }
8990        return needSep;
8991    }
8992
8993    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8994            int opti, boolean dumpAll) {
8995        boolean needSep = false;
8996
8997        if (mLruProcesses.size() > 0) {
8998            if (needSep) pw.println(" ");
8999            needSep = true;
9000            pw.println("  OOM levels:");
9001            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9002            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9003            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9004            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9005            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9006            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9007            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9008            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9009            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9010            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9011            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9012            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9013            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9014
9015            if (needSep) pw.println(" ");
9016            needSep = true;
9017            pw.println("  Process OOM control:");
9018            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9019                    "Proc", "PERS", true, null);
9020            needSep = true;
9021        }
9022
9023        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9024
9025        pw.println();
9026        pw.println("  mHomeProcess: " + mHomeProcess);
9027        pw.println("  mPreviousProcess: " + mPreviousProcess);
9028        if (mHeavyWeightProcess != null) {
9029            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9030        }
9031
9032        return true;
9033    }
9034
9035    /**
9036     * There are three ways to call this:
9037     *  - no service specified: dump all the services
9038     *  - a flattened component name that matched an existing service was specified as the
9039     *    first arg: dump that one service
9040     *  - the first arg isn't the flattened component name of an existing service:
9041     *    dump all services whose component contains the first arg as a substring
9042     */
9043    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9044            int opti, boolean dumpAll) {
9045        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
9046
9047        if ("all".equals(name)) {
9048            synchronized (this) {
9049                try {
9050                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9051                    for (UserInfo user : users) {
9052                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9053                            services.add(r1);
9054                        }
9055                    }
9056                } catch (RemoteException re) {
9057                }
9058            }
9059        } else {
9060            ComponentName componentName = name != null
9061                    ? ComponentName.unflattenFromString(name) : null;
9062            int objectId = 0;
9063            if (componentName == null) {
9064                // Not a '/' separated full component name; maybe an object ID?
9065                try {
9066                    objectId = Integer.parseInt(name, 16);
9067                    name = null;
9068                    componentName = null;
9069                } catch (RuntimeException e) {
9070                }
9071            }
9072
9073            synchronized (this) {
9074                try {
9075                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9076                    for (UserInfo user : users) {
9077                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9078                            if (componentName != null) {
9079                                if (r1.name.equals(componentName)) {
9080                                    services.add(r1);
9081                                }
9082                            } else if (name != null) {
9083                                if (r1.name.flattenToString().contains(name)) {
9084                                    services.add(r1);
9085                                }
9086                            } else if (System.identityHashCode(r1) == objectId) {
9087                                services.add(r1);
9088                            }
9089                        }
9090                    }
9091                } catch (RemoteException re) {
9092                }
9093            }
9094        }
9095
9096        if (services.size() <= 0) {
9097            return false;
9098        }
9099
9100        boolean needSep = false;
9101        for (int i=0; i<services.size(); i++) {
9102            if (needSep) {
9103                pw.println();
9104            }
9105            needSep = true;
9106            dumpService("", fd, pw, services.get(i), args, dumpAll);
9107        }
9108        return true;
9109    }
9110
9111    /**
9112     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9113     * there is a thread associated with the service.
9114     */
9115    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9116            final ServiceRecord r, String[] args, boolean dumpAll) {
9117        String innerPrefix = prefix + "  ";
9118        synchronized (this) {
9119            pw.print(prefix); pw.print("SERVICE ");
9120                    pw.print(r.shortName); pw.print(" ");
9121                    pw.print(Integer.toHexString(System.identityHashCode(r)));
9122                    pw.print(" pid=");
9123                    if (r.app != null) pw.println(r.app.pid);
9124                    else pw.println("(not running)");
9125            if (dumpAll) {
9126                r.dump(pw, innerPrefix);
9127            }
9128        }
9129        if (r.app != null && r.app.thread != null) {
9130            pw.print(prefix); pw.println("  Client:");
9131            pw.flush();
9132            try {
9133                TransferPipe tp = new TransferPipe();
9134                try {
9135                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9136                    tp.setBufferPrefix(prefix + "    ");
9137                    tp.go(fd);
9138                } finally {
9139                    tp.kill();
9140                }
9141            } catch (IOException e) {
9142                pw.println(prefix + "    Failure while dumping the service: " + e);
9143            } catch (RemoteException e) {
9144                pw.println(prefix + "    Got a RemoteException while dumping the service");
9145            }
9146        }
9147    }
9148
9149    /**
9150     * There are three ways to call this:
9151     *  - no provider specified: dump all the providers
9152     *  - a flattened component name that matched an existing provider was specified as the
9153     *    first arg: dump that one provider
9154     *  - the first arg isn't the flattened component name of an existing provider:
9155     *    dump all providers whose component contains the first arg as a substring
9156     */
9157    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9158            int opti, boolean dumpAll) {
9159        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9160    }
9161
9162    static class ItemMatcher {
9163        ArrayList<ComponentName> components;
9164        ArrayList<String> strings;
9165        ArrayList<Integer> objects;
9166        boolean all;
9167
9168        ItemMatcher() {
9169            all = true;
9170        }
9171
9172        void build(String name) {
9173            ComponentName componentName = ComponentName.unflattenFromString(name);
9174            if (componentName != null) {
9175                if (components == null) {
9176                    components = new ArrayList<ComponentName>();
9177                }
9178                components.add(componentName);
9179                all = false;
9180            } else {
9181                int objectId = 0;
9182                // Not a '/' separated full component name; maybe an object ID?
9183                try {
9184                    objectId = Integer.parseInt(name, 16);
9185                    if (objects == null) {
9186                        objects = new ArrayList<Integer>();
9187                    }
9188                    objects.add(objectId);
9189                    all = false;
9190                } catch (RuntimeException e) {
9191                    // Not an integer; just do string match.
9192                    if (strings == null) {
9193                        strings = new ArrayList<String>();
9194                    }
9195                    strings.add(name);
9196                    all = false;
9197                }
9198            }
9199        }
9200
9201        int build(String[] args, int opti) {
9202            for (; opti<args.length; opti++) {
9203                String name = args[opti];
9204                if ("--".equals(name)) {
9205                    return opti+1;
9206                }
9207                build(name);
9208            }
9209            return opti;
9210        }
9211
9212        boolean match(Object object, ComponentName comp) {
9213            if (all) {
9214                return true;
9215            }
9216            if (components != null) {
9217                for (int i=0; i<components.size(); i++) {
9218                    if (components.get(i).equals(comp)) {
9219                        return true;
9220                    }
9221                }
9222            }
9223            if (objects != null) {
9224                for (int i=0; i<objects.size(); i++) {
9225                    if (System.identityHashCode(object) == objects.get(i)) {
9226                        return true;
9227                    }
9228                }
9229            }
9230            if (strings != null) {
9231                String flat = comp.flattenToString();
9232                for (int i=0; i<strings.size(); i++) {
9233                    if (flat.contains(strings.get(i))) {
9234                        return true;
9235                    }
9236                }
9237            }
9238            return false;
9239        }
9240    }
9241
9242    /**
9243     * There are three things that cmd can be:
9244     *  - a flattened component name that matches an existing activity
9245     *  - the cmd arg isn't the flattened component name of an existing activity:
9246     *    dump all activity whose component contains the cmd as a substring
9247     *  - A hex number of the ActivityRecord object instance.
9248     */
9249    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9250            int opti, boolean dumpAll) {
9251        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9252
9253        if ("all".equals(name)) {
9254            synchronized (this) {
9255                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9256                    activities.add(r1);
9257                }
9258            }
9259        } else if ("top".equals(name)) {
9260            synchronized (this) {
9261                final int N = mMainStack.mHistory.size();
9262                if (N > 0) {
9263                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9264                }
9265            }
9266        } else {
9267            ItemMatcher matcher = new ItemMatcher();
9268            matcher.build(name);
9269
9270            synchronized (this) {
9271                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9272                    if (matcher.match(r1, r1.intent.getComponent())) {
9273                        activities.add(r1);
9274                    }
9275                }
9276            }
9277        }
9278
9279        if (activities.size() <= 0) {
9280            return false;
9281        }
9282
9283        String[] newArgs = new String[args.length - opti];
9284        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9285
9286        TaskRecord lastTask = null;
9287        boolean needSep = false;
9288        for (int i=activities.size()-1; i>=0; i--) {
9289            ActivityRecord r = (ActivityRecord)activities.get(i);
9290            if (needSep) {
9291                pw.println();
9292            }
9293            needSep = true;
9294            synchronized (this) {
9295                if (lastTask != r.task) {
9296                    lastTask = r.task;
9297                    pw.print("TASK "); pw.print(lastTask.affinity);
9298                            pw.print(" id="); pw.println(lastTask.taskId);
9299                    if (dumpAll) {
9300                        lastTask.dump(pw, "  ");
9301                    }
9302                }
9303            }
9304            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9305        }
9306        return true;
9307    }
9308
9309    /**
9310     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9311     * there is a thread associated with the activity.
9312     */
9313    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9314            final ActivityRecord r, String[] args, boolean dumpAll) {
9315        String innerPrefix = prefix + "  ";
9316        synchronized (this) {
9317            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9318                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9319                    pw.print(" pid=");
9320                    if (r.app != null) pw.println(r.app.pid);
9321                    else pw.println("(not running)");
9322            if (dumpAll) {
9323                r.dump(pw, innerPrefix);
9324            }
9325        }
9326        if (r.app != null && r.app.thread != null) {
9327            // flush anything that is already in the PrintWriter since the thread is going
9328            // to write to the file descriptor directly
9329            pw.flush();
9330            try {
9331                TransferPipe tp = new TransferPipe();
9332                try {
9333                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9334                            r.appToken, innerPrefix, args);
9335                    tp.go(fd);
9336                } finally {
9337                    tp.kill();
9338                }
9339            } catch (IOException e) {
9340                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9341            } catch (RemoteException e) {
9342                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9343            }
9344        }
9345    }
9346
9347    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9348            int opti, boolean dumpAll, String dumpPackage) {
9349        boolean needSep = false;
9350
9351        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9352        if (dumpAll) {
9353            if (mRegisteredReceivers.size() > 0) {
9354                boolean printed = false;
9355                Iterator it = mRegisteredReceivers.values().iterator();
9356                while (it.hasNext()) {
9357                    ReceiverList r = (ReceiverList)it.next();
9358                    if (dumpPackage != null && (r.app == null ||
9359                            !dumpPackage.equals(r.app.info.packageName))) {
9360                        continue;
9361                    }
9362                    if (!printed) {
9363                        pw.println("  Registered Receivers:");
9364                        needSep = true;
9365                        printed = true;
9366                    }
9367                    pw.print("  * "); pw.println(r);
9368                    r.dump(pw, "    ");
9369                }
9370            }
9371
9372            if (mReceiverResolver.dump(pw, needSep ?
9373                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9374                    "    ", dumpPackage, false)) {
9375                needSep = true;
9376            }
9377        }
9378
9379        for (BroadcastQueue q : mBroadcastQueues) {
9380            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9381        }
9382
9383        needSep = true;
9384
9385        if (mStickyBroadcasts != null && dumpPackage == null) {
9386            if (needSep) {
9387                pw.println();
9388            }
9389            needSep = true;
9390            pw.println("  Sticky broadcasts:");
9391            StringBuilder sb = new StringBuilder(128);
9392            for (Map.Entry<String, ArrayList<Intent>> ent
9393                    : mStickyBroadcasts.entrySet()) {
9394                pw.print("  * Sticky action "); pw.print(ent.getKey());
9395                if (dumpAll) {
9396                    pw.println(":");
9397                    ArrayList<Intent> intents = ent.getValue();
9398                    final int N = intents.size();
9399                    for (int i=0; i<N; i++) {
9400                        sb.setLength(0);
9401                        sb.append("    Intent: ");
9402                        intents.get(i).toShortString(sb, false, true, false, false);
9403                        pw.println(sb.toString());
9404                        Bundle bundle = intents.get(i).getExtras();
9405                        if (bundle != null) {
9406                            pw.print("      ");
9407                            pw.println(bundle.toString());
9408                        }
9409                    }
9410                } else {
9411                    pw.println("");
9412                }
9413            }
9414            needSep = true;
9415        }
9416
9417        if (dumpAll) {
9418            pw.println();
9419            for (BroadcastQueue queue : mBroadcastQueues) {
9420                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9421                        + queue.mBroadcastsScheduled);
9422            }
9423            pw.println("  mHandler:");
9424            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9425            needSep = true;
9426        }
9427
9428        return needSep;
9429    }
9430
9431    /**
9432     * Prints a list of ServiceRecords (dumpsys activity services)
9433     */
9434    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9435            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9436        boolean needSep = false;
9437
9438        ItemMatcher matcher = new ItemMatcher();
9439        matcher.build(args, opti);
9440
9441        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9442        try {
9443            List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9444            for (UserInfo user : users) {
9445                if (mServiceMap.getAllServices(user.id).size() > 0) {
9446                    boolean printed = false;
9447                    long nowReal = SystemClock.elapsedRealtime();
9448                    Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9449                            user.id).iterator();
9450                    needSep = false;
9451                    while (it.hasNext()) {
9452                        ServiceRecord r = it.next();
9453                        if (!matcher.match(r, r.name)) {
9454                            continue;
9455                        }
9456                        if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9457                            continue;
9458                        }
9459                        if (!printed) {
9460                            pw.println("  Active services:");
9461                            printed = true;
9462                        }
9463                        if (needSep) {
9464                            pw.println();
9465                        }
9466                        pw.print("  * ");
9467                        pw.println(r);
9468                        if (dumpAll) {
9469                            r.dump(pw, "    ");
9470                            needSep = true;
9471                        } else {
9472                            pw.print("    app=");
9473                            pw.println(r.app);
9474                            pw.print("    created=");
9475                            TimeUtils.formatDuration(r.createTime, nowReal, pw);
9476                            pw.print(" started=");
9477                            pw.print(r.startRequested);
9478                            pw.print(" connections=");
9479                            pw.println(r.connections.size());
9480                            if (r.connections.size() > 0) {
9481                                pw.println("    Connections:");
9482                                for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9483                                    for (int i = 0; i < clist.size(); i++) {
9484                                        ConnectionRecord conn = clist.get(i);
9485                                        pw.print("      ");
9486                                        pw.print(conn.binding.intent.intent.getIntent()
9487                                                .toShortString(false, false, false, false));
9488                                        pw.print(" -> ");
9489                                        ProcessRecord proc = conn.binding.client;
9490                                        pw.println(proc != null ? proc.toShortString() : "null");
9491                                    }
9492                                }
9493                            }
9494                        }
9495                        if (dumpClient && r.app != null && r.app.thread != null) {
9496                            pw.println("    Client:");
9497                            pw.flush();
9498                            try {
9499                                TransferPipe tp = new TransferPipe();
9500                                try {
9501                                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
9502                                            r, args);
9503                                    tp.setBufferPrefix("      ");
9504                                    // Short timeout, since blocking here can
9505                                    // deadlock with the application.
9506                                    tp.go(fd, 2000);
9507                                } finally {
9508                                    tp.kill();
9509                                }
9510                            } catch (IOException e) {
9511                                pw.println("      Failure while dumping the service: " + e);
9512                            } catch (RemoteException e) {
9513                                pw.println("      Got a RemoteException while dumping the service");
9514                            }
9515                            needSep = true;
9516                        }
9517                    }
9518                    needSep = printed;
9519                }
9520            }
9521        } catch (RemoteException re) {
9522
9523        }
9524
9525        if (mPendingServices.size() > 0) {
9526            boolean printed = false;
9527            for (int i=0; i<mPendingServices.size(); i++) {
9528                ServiceRecord r = mPendingServices.get(i);
9529                if (!matcher.match(r, r.name)) {
9530                    continue;
9531                }
9532                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9533                    continue;
9534                }
9535                if (!printed) {
9536                    if (needSep) pw.println(" ");
9537                    needSep = true;
9538                    pw.println("  Pending services:");
9539                    printed = true;
9540                }
9541                pw.print("  * Pending "); pw.println(r);
9542                r.dump(pw, "    ");
9543            }
9544            needSep = true;
9545        }
9546
9547        if (mRestartingServices.size() > 0) {
9548            boolean printed = false;
9549            for (int i=0; i<mRestartingServices.size(); i++) {
9550                ServiceRecord r = mRestartingServices.get(i);
9551                if (!matcher.match(r, r.name)) {
9552                    continue;
9553                }
9554                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9555                    continue;
9556                }
9557                if (!printed) {
9558                    if (needSep) pw.println(" ");
9559                    needSep = true;
9560                    pw.println("  Restarting services:");
9561                    printed = true;
9562                }
9563                pw.print("  * Restarting "); pw.println(r);
9564                r.dump(pw, "    ");
9565            }
9566            needSep = true;
9567        }
9568
9569        if (mStoppingServices.size() > 0) {
9570            boolean printed = false;
9571            for (int i=0; i<mStoppingServices.size(); i++) {
9572                ServiceRecord r = mStoppingServices.get(i);
9573                if (!matcher.match(r, r.name)) {
9574                    continue;
9575                }
9576                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9577                    continue;
9578                }
9579                if (!printed) {
9580                    if (needSep) pw.println(" ");
9581                    needSep = true;
9582                    pw.println("  Stopping services:");
9583                    printed = true;
9584                }
9585                pw.print("  * Stopping "); pw.println(r);
9586                r.dump(pw, "    ");
9587            }
9588            needSep = true;
9589        }
9590
9591        if (dumpAll) {
9592            if (mServiceConnections.size() > 0) {
9593                boolean printed = false;
9594                Iterator<ArrayList<ConnectionRecord>> it
9595                        = mServiceConnections.values().iterator();
9596                while (it.hasNext()) {
9597                    ArrayList<ConnectionRecord> r = it.next();
9598                    for (int i=0; i<r.size(); i++) {
9599                        ConnectionRecord cr = r.get(i);
9600                        if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9601                            continue;
9602                        }
9603                        if (dumpPackage != null && (cr.binding.client == null
9604                                || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9605                            continue;
9606                        }
9607                        if (!printed) {
9608                            if (needSep) pw.println(" ");
9609                            needSep = true;
9610                            pw.println("  Connection bindings to services:");
9611                            printed = true;
9612                        }
9613                        pw.print("  * "); pw.println(cr);
9614                        cr.dump(pw, "    ");
9615                    }
9616                }
9617                needSep = true;
9618            }
9619        }
9620
9621        return needSep;
9622    }
9623
9624    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9625            int opti, boolean dumpAll, String dumpPackage) {
9626        boolean needSep = true;
9627
9628        ItemMatcher matcher = new ItemMatcher();
9629        matcher.build(args, opti);
9630
9631        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9632
9633        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9634
9635        if (mLaunchingProviders.size() > 0) {
9636            boolean printed = false;
9637            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9638                ContentProviderRecord r = mLaunchingProviders.get(i);
9639                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9640                    continue;
9641                }
9642                if (!printed) {
9643                    if (needSep) pw.println(" ");
9644                    needSep = true;
9645                    pw.println("  Launching content providers:");
9646                    printed = true;
9647                }
9648                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9649                        pw.println(r);
9650            }
9651        }
9652
9653        if (mGrantedUriPermissions.size() > 0) {
9654            if (needSep) pw.println();
9655            needSep = true;
9656            pw.println("Granted Uri Permissions:");
9657            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9658                int uid = mGrantedUriPermissions.keyAt(i);
9659                HashMap<Uri, UriPermission> perms
9660                        = mGrantedUriPermissions.valueAt(i);
9661                pw.print("  * UID "); pw.print(uid);
9662                        pw.println(" holds:");
9663                for (UriPermission perm : perms.values()) {
9664                    pw.print("    "); pw.println(perm);
9665                    if (dumpAll) {
9666                        perm.dump(pw, "      ");
9667                    }
9668                }
9669            }
9670            needSep = true;
9671        }
9672
9673        return needSep;
9674    }
9675
9676    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9677            int opti, boolean dumpAll, String dumpPackage) {
9678        boolean needSep = false;
9679
9680        if (mIntentSenderRecords.size() > 0) {
9681            boolean printed = false;
9682            Iterator<WeakReference<PendingIntentRecord>> it
9683                    = mIntentSenderRecords.values().iterator();
9684            while (it.hasNext()) {
9685                WeakReference<PendingIntentRecord> ref = it.next();
9686                PendingIntentRecord rec = ref != null ? ref.get(): null;
9687                if (dumpPackage != null && (rec == null
9688                        || !dumpPackage.equals(rec.key.packageName))) {
9689                    continue;
9690                }
9691                if (!printed) {
9692                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9693                    printed = true;
9694                }
9695                needSep = true;
9696                if (rec != null) {
9697                    pw.print("  * "); pw.println(rec);
9698                    if (dumpAll) {
9699                        rec.dump(pw, "    ");
9700                    }
9701                } else {
9702                    pw.print("  * "); pw.println(ref);
9703                }
9704            }
9705        }
9706
9707        return needSep;
9708    }
9709
9710    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9711            String prefix, String label, boolean complete, boolean brief, boolean client,
9712            String dumpPackage) {
9713        TaskRecord lastTask = null;
9714        boolean needNL = false;
9715        final String innerPrefix = prefix + "      ";
9716        final String[] args = new String[0];
9717        for (int i=list.size()-1; i>=0; i--) {
9718            final ActivityRecord r = (ActivityRecord)list.get(i);
9719            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9720                continue;
9721            }
9722            final boolean full = !brief && (complete || !r.isInHistory());
9723            if (needNL) {
9724                pw.println(" ");
9725                needNL = false;
9726            }
9727            if (lastTask != r.task) {
9728                lastTask = r.task;
9729                pw.print(prefix);
9730                pw.print(full ? "* " : "  ");
9731                pw.println(lastTask);
9732                if (full) {
9733                    lastTask.dump(pw, prefix + "  ");
9734                } else if (complete) {
9735                    // Complete + brief == give a summary.  Isn't that obvious?!?
9736                    if (lastTask.intent != null) {
9737                        pw.print(prefix); pw.print("  ");
9738                                pw.println(lastTask.intent.toInsecureStringWithClip());
9739                    }
9740                }
9741            }
9742            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9743            pw.print(" #"); pw.print(i); pw.print(": ");
9744            pw.println(r);
9745            if (full) {
9746                r.dump(pw, innerPrefix);
9747            } else if (complete) {
9748                // Complete + brief == give a summary.  Isn't that obvious?!?
9749                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9750                if (r.app != null) {
9751                    pw.print(innerPrefix); pw.println(r.app);
9752                }
9753            }
9754            if (client && r.app != null && r.app.thread != null) {
9755                // flush anything that is already in the PrintWriter since the thread is going
9756                // to write to the file descriptor directly
9757                pw.flush();
9758                try {
9759                    TransferPipe tp = new TransferPipe();
9760                    try {
9761                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9762                                r.appToken, innerPrefix, args);
9763                        // Short timeout, since blocking here can
9764                        // deadlock with the application.
9765                        tp.go(fd, 2000);
9766                    } finally {
9767                        tp.kill();
9768                    }
9769                } catch (IOException e) {
9770                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9771                } catch (RemoteException e) {
9772                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9773                }
9774                needNL = true;
9775            }
9776        }
9777    }
9778
9779    private static String buildOomTag(String prefix, String space, int val, int base) {
9780        if (val == base) {
9781            if (space == null) return prefix;
9782            return prefix + "  ";
9783        }
9784        return prefix + "+" + Integer.toString(val-base);
9785    }
9786
9787    private static final int dumpProcessList(PrintWriter pw,
9788            ActivityManagerService service, List list,
9789            String prefix, String normalLabel, String persistentLabel,
9790            String dumpPackage) {
9791        int numPers = 0;
9792        final int N = list.size()-1;
9793        for (int i=N; i>=0; i--) {
9794            ProcessRecord r = (ProcessRecord)list.get(i);
9795            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9796                continue;
9797            }
9798            pw.println(String.format("%s%s #%2d: %s",
9799                    prefix, (r.persistent ? persistentLabel : normalLabel),
9800                    i, r.toString()));
9801            if (r.persistent) {
9802                numPers++;
9803            }
9804        }
9805        return numPers;
9806    }
9807
9808    private static final boolean dumpProcessOomList(PrintWriter pw,
9809            ActivityManagerService service, List<ProcessRecord> origList,
9810            String prefix, String normalLabel, String persistentLabel,
9811            boolean inclDetails, String dumpPackage) {
9812
9813        ArrayList<Pair<ProcessRecord, Integer>> list
9814                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9815        for (int i=0; i<origList.size(); i++) {
9816            ProcessRecord r = origList.get(i);
9817            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9818                continue;
9819            }
9820            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9821        }
9822
9823        if (list.size() <= 0) {
9824            return false;
9825        }
9826
9827        Comparator<Pair<ProcessRecord, Integer>> comparator
9828                = new Comparator<Pair<ProcessRecord, Integer>>() {
9829            @Override
9830            public int compare(Pair<ProcessRecord, Integer> object1,
9831                    Pair<ProcessRecord, Integer> object2) {
9832                if (object1.first.setAdj != object2.first.setAdj) {
9833                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9834                }
9835                if (object1.second.intValue() != object2.second.intValue()) {
9836                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9837                }
9838                return 0;
9839            }
9840        };
9841
9842        Collections.sort(list, comparator);
9843
9844        final long curRealtime = SystemClock.elapsedRealtime();
9845        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9846        final long curUptime = SystemClock.uptimeMillis();
9847        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9848
9849        for (int i=list.size()-1; i>=0; i--) {
9850            ProcessRecord r = list.get(i).first;
9851            String oomAdj;
9852            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9853                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9854            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9855                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9856            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9857                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9858            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9859                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9860            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9861                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9862            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9863                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9864            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9865                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9866            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9867                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9868            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9869                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9870            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9871                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9872            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9873                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9874            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9875                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9876            } else {
9877                oomAdj = Integer.toString(r.setAdj);
9878            }
9879            String schedGroup;
9880            switch (r.setSchedGroup) {
9881                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9882                    schedGroup = "B";
9883                    break;
9884                case Process.THREAD_GROUP_DEFAULT:
9885                    schedGroup = "F";
9886                    break;
9887                default:
9888                    schedGroup = Integer.toString(r.setSchedGroup);
9889                    break;
9890            }
9891            String foreground;
9892            if (r.foregroundActivities) {
9893                foreground = "A";
9894            } else if (r.foregroundServices) {
9895                foreground = "S";
9896            } else {
9897                foreground = " ";
9898            }
9899            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9900                    prefix, (r.persistent ? persistentLabel : normalLabel),
9901                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9902                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9903            if (r.adjSource != null || r.adjTarget != null) {
9904                pw.print(prefix);
9905                pw.print("    ");
9906                if (r.adjTarget instanceof ComponentName) {
9907                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9908                } else if (r.adjTarget != null) {
9909                    pw.print(r.adjTarget.toString());
9910                } else {
9911                    pw.print("{null}");
9912                }
9913                pw.print("<=");
9914                if (r.adjSource instanceof ProcessRecord) {
9915                    pw.print("Proc{");
9916                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9917                    pw.println("}");
9918                } else if (r.adjSource != null) {
9919                    pw.println(r.adjSource.toString());
9920                } else {
9921                    pw.println("{null}");
9922                }
9923            }
9924            if (inclDetails) {
9925                pw.print(prefix);
9926                pw.print("    ");
9927                pw.print("oom: max="); pw.print(r.maxAdj);
9928                pw.print(" hidden="); pw.print(r.hiddenAdj);
9929                pw.print(" curRaw="); pw.print(r.curRawAdj);
9930                pw.print(" setRaw="); pw.print(r.setRawAdj);
9931                pw.print(" cur="); pw.print(r.curAdj);
9932                pw.print(" set="); pw.println(r.setAdj);
9933                pw.print(prefix);
9934                pw.print("    ");
9935                pw.print("keeping="); pw.print(r.keeping);
9936                pw.print(" hidden="); pw.print(r.hidden);
9937                pw.print(" empty="); pw.print(r.empty);
9938                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9939
9940                if (!r.keeping) {
9941                    if (r.lastWakeTime != 0) {
9942                        long wtime;
9943                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9944                        synchronized (stats) {
9945                            wtime = stats.getProcessWakeTime(r.info.uid,
9946                                    r.pid, curRealtime);
9947                        }
9948                        long timeUsed = wtime - r.lastWakeTime;
9949                        pw.print(prefix);
9950                        pw.print("    ");
9951                        pw.print("keep awake over ");
9952                        TimeUtils.formatDuration(realtimeSince, pw);
9953                        pw.print(" used ");
9954                        TimeUtils.formatDuration(timeUsed, pw);
9955                        pw.print(" (");
9956                        pw.print((timeUsed*100)/realtimeSince);
9957                        pw.println("%)");
9958                    }
9959                    if (r.lastCpuTime != 0) {
9960                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9961                        pw.print(prefix);
9962                        pw.print("    ");
9963                        pw.print("run cpu over ");
9964                        TimeUtils.formatDuration(uptimeSince, pw);
9965                        pw.print(" used ");
9966                        TimeUtils.formatDuration(timeUsed, pw);
9967                        pw.print(" (");
9968                        pw.print((timeUsed*100)/uptimeSince);
9969                        pw.println("%)");
9970                    }
9971                }
9972            }
9973        }
9974        return true;
9975    }
9976
9977    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9978        ArrayList<ProcessRecord> procs;
9979        synchronized (this) {
9980            if (args != null && args.length > start
9981                    && args[start].charAt(0) != '-') {
9982                procs = new ArrayList<ProcessRecord>();
9983                int pid = -1;
9984                try {
9985                    pid = Integer.parseInt(args[start]);
9986                } catch (NumberFormatException e) {
9987
9988                }
9989                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9990                    ProcessRecord proc = mLruProcesses.get(i);
9991                    if (proc.pid == pid) {
9992                        procs.add(proc);
9993                    } else if (proc.processName.equals(args[start])) {
9994                        procs.add(proc);
9995                    }
9996                }
9997                if (procs.size() <= 0) {
9998                    pw.println("No process found for: " + args[start]);
9999                    return null;
10000                }
10001            } else {
10002                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10003            }
10004        }
10005        return procs;
10006    }
10007
10008    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10009            PrintWriter pw, String[] args) {
10010        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10011        if (procs == null) {
10012            return;
10013        }
10014
10015        long uptime = SystemClock.uptimeMillis();
10016        long realtime = SystemClock.elapsedRealtime();
10017        pw.println("Applications Graphics Acceleration Info:");
10018        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10019
10020        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10021            ProcessRecord r = procs.get(i);
10022            if (r.thread != null) {
10023                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10024                pw.flush();
10025                try {
10026                    TransferPipe tp = new TransferPipe();
10027                    try {
10028                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10029                        tp.go(fd);
10030                    } finally {
10031                        tp.kill();
10032                    }
10033                } catch (IOException e) {
10034                    pw.println("Failure while dumping the app: " + r);
10035                    pw.flush();
10036                } catch (RemoteException e) {
10037                    pw.println("Got a RemoteException while dumping the app " + r);
10038                    pw.flush();
10039                }
10040            }
10041        }
10042    }
10043
10044    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10045        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10046        if (procs == null) {
10047            return;
10048        }
10049
10050        pw.println("Applications Database Info:");
10051
10052        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10053            ProcessRecord r = procs.get(i);
10054            if (r.thread != null) {
10055                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10056                pw.flush();
10057                try {
10058                    TransferPipe tp = new TransferPipe();
10059                    try {
10060                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10061                        tp.go(fd);
10062                    } finally {
10063                        tp.kill();
10064                    }
10065                } catch (IOException e) {
10066                    pw.println("Failure while dumping the app: " + r);
10067                    pw.flush();
10068                } catch (RemoteException e) {
10069                    pw.println("Got a RemoteException while dumping the app " + r);
10070                    pw.flush();
10071                }
10072            }
10073        }
10074    }
10075
10076    final static class MemItem {
10077        final String label;
10078        final String shortLabel;
10079        final long pss;
10080        final int id;
10081        ArrayList<MemItem> subitems;
10082
10083        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10084            label = _label;
10085            shortLabel = _shortLabel;
10086            pss = _pss;
10087            id = _id;
10088        }
10089    }
10090
10091    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10092            boolean sort) {
10093        if (sort) {
10094            Collections.sort(items, new Comparator<MemItem>() {
10095                @Override
10096                public int compare(MemItem lhs, MemItem rhs) {
10097                    if (lhs.pss < rhs.pss) {
10098                        return 1;
10099                    } else if (lhs.pss > rhs.pss) {
10100                        return -1;
10101                    }
10102                    return 0;
10103                }
10104            });
10105        }
10106
10107        for (int i=0; i<items.size(); i++) {
10108            MemItem mi = items.get(i);
10109            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10110            if (mi.subitems != null) {
10111                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10112            }
10113        }
10114    }
10115
10116    // These are in KB.
10117    static final long[] DUMP_MEM_BUCKETS = new long[] {
10118        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10119        120*1024, 160*1024, 200*1024,
10120        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10121        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10122    };
10123
10124    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10125            boolean stackLike) {
10126        int start = label.lastIndexOf('.');
10127        if (start >= 0) start++;
10128        else start = 0;
10129        int end = label.length();
10130        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10131            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10132                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10133                out.append(bucket);
10134                out.append(stackLike ? "MB." : "MB ");
10135                out.append(label, start, end);
10136                return;
10137            }
10138        }
10139        out.append(memKB/1024);
10140        out.append(stackLike ? "MB." : "MB ");
10141        out.append(label, start, end);
10142    }
10143
10144    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10145            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10146            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10147            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10148            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10149    };
10150    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10151            "System", "Persistent", "Foreground",
10152            "Visible", "Perceptible", "Heavy Weight",
10153            "Backup", "A Services", "Home", "Previous",
10154            "B Services", "Background"
10155    };
10156
10157    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10158            PrintWriter pw, String prefix, String[] args, boolean brief,
10159            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10160        boolean dumpAll = false;
10161        boolean oomOnly = false;
10162
10163        int opti = 0;
10164        while (opti < args.length) {
10165            String opt = args[opti];
10166            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10167                break;
10168            }
10169            opti++;
10170            if ("-a".equals(opt)) {
10171                dumpAll = true;
10172            } else if ("--oom".equals(opt)) {
10173                oomOnly = true;
10174            } else if ("-h".equals(opt)) {
10175                pw.println("meminfo dump options: [-a] [--oom] [process]");
10176                pw.println("  -a: include all available information for each process.");
10177                pw.println("  --oom: only show processes organized by oom adj.");
10178                pw.println("If [process] is specified it can be the name or ");
10179                pw.println("pid of a specific process to dump.");
10180                return;
10181            } else {
10182                pw.println("Unknown argument: " + opt + "; use -h for help");
10183            }
10184        }
10185
10186        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10187        if (procs == null) {
10188            return;
10189        }
10190
10191        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10192        long uptime = SystemClock.uptimeMillis();
10193        long realtime = SystemClock.elapsedRealtime();
10194
10195        if (procs.size() == 1 || isCheckinRequest) {
10196            dumpAll = true;
10197        }
10198
10199        if (isCheckinRequest) {
10200            // short checkin version
10201            pw.println(uptime + "," + realtime);
10202            pw.flush();
10203        } else {
10204            pw.println("Applications Memory Usage (kB):");
10205            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10206        }
10207
10208        String[] innerArgs = new String[args.length-opti];
10209        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10210
10211        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10212        long nativePss=0, dalvikPss=0, otherPss=0;
10213        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10214
10215        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10216        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10217                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10218
10219        long totalPss = 0;
10220
10221        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10222            ProcessRecord r = procs.get(i);
10223            if (r.thread != null) {
10224                if (!isCheckinRequest && dumpAll) {
10225                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10226                    pw.flush();
10227                }
10228                Debug.MemoryInfo mi = null;
10229                if (dumpAll) {
10230                    try {
10231                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10232                    } catch (RemoteException e) {
10233                        if (!isCheckinRequest) {
10234                            pw.println("Got RemoteException!");
10235                            pw.flush();
10236                        }
10237                    }
10238                } else {
10239                    mi = new Debug.MemoryInfo();
10240                    Debug.getMemoryInfo(r.pid, mi);
10241                }
10242
10243                if (!isCheckinRequest && mi != null) {
10244                    long myTotalPss = mi.getTotalPss();
10245                    totalPss += myTotalPss;
10246                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10247                            r.processName, myTotalPss, 0);
10248                    procMems.add(pssItem);
10249
10250                    nativePss += mi.nativePss;
10251                    dalvikPss += mi.dalvikPss;
10252                    otherPss += mi.otherPss;
10253                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10254                        long mem = mi.getOtherPss(j);
10255                        miscPss[j] += mem;
10256                        otherPss -= mem;
10257                    }
10258
10259                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10260                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10261                                || oomIndex == (oomPss.length-1)) {
10262                            oomPss[oomIndex] += myTotalPss;
10263                            if (oomProcs[oomIndex] == null) {
10264                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10265                            }
10266                            oomProcs[oomIndex].add(pssItem);
10267                            break;
10268                        }
10269                    }
10270                }
10271            }
10272        }
10273
10274        if (!isCheckinRequest && procs.size() > 1) {
10275            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10276
10277            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10278            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10279            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10280            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10281                String label = Debug.MemoryInfo.getOtherLabel(j);
10282                catMems.add(new MemItem(label, label, miscPss[j], j));
10283            }
10284
10285            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10286            for (int j=0; j<oomPss.length; j++) {
10287                if (oomPss[j] != 0) {
10288                    String label = DUMP_MEM_OOM_LABEL[j];
10289                    MemItem item = new MemItem(label, label, oomPss[j],
10290                            DUMP_MEM_OOM_ADJ[j]);
10291                    item.subitems = oomProcs[j];
10292                    oomMems.add(item);
10293                }
10294            }
10295
10296            if (outTag != null || outStack != null) {
10297                if (outTag != null) {
10298                    appendMemBucket(outTag, totalPss, "total", false);
10299                }
10300                if (outStack != null) {
10301                    appendMemBucket(outStack, totalPss, "total", true);
10302                }
10303                boolean firstLine = true;
10304                for (int i=0; i<oomMems.size(); i++) {
10305                    MemItem miCat = oomMems.get(i);
10306                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10307                        continue;
10308                    }
10309                    if (miCat.id < ProcessList.SERVICE_ADJ
10310                            || miCat.id == ProcessList.HOME_APP_ADJ
10311                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10312                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10313                            outTag.append(" / ");
10314                        }
10315                        if (outStack != null) {
10316                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10317                                if (firstLine) {
10318                                    outStack.append(":");
10319                                    firstLine = false;
10320                                }
10321                                outStack.append("\n\t at ");
10322                            } else {
10323                                outStack.append("$");
10324                            }
10325                        }
10326                        for (int j=0; j<miCat.subitems.size(); j++) {
10327                            MemItem mi = miCat.subitems.get(j);
10328                            if (j > 0) {
10329                                if (outTag != null) {
10330                                    outTag.append(" ");
10331                                }
10332                                if (outStack != null) {
10333                                    outStack.append("$");
10334                                }
10335                            }
10336                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10337                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10338                            }
10339                            if (outStack != null) {
10340                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10341                            }
10342                        }
10343                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10344                            outStack.append("(");
10345                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10346                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10347                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10348                                    outStack.append(":");
10349                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10350                                }
10351                            }
10352                            outStack.append(")");
10353                        }
10354                    }
10355                }
10356            }
10357
10358            if (!brief && !oomOnly) {
10359                pw.println();
10360                pw.println("Total PSS by process:");
10361                dumpMemItems(pw, "  ", procMems, true);
10362                pw.println();
10363            }
10364            pw.println("Total PSS by OOM adjustment:");
10365            dumpMemItems(pw, "  ", oomMems, false);
10366            if (!oomOnly) {
10367                PrintWriter out = categoryPw != null ? categoryPw : pw;
10368                out.println();
10369                out.println("Total PSS by category:");
10370                dumpMemItems(out, "  ", catMems, true);
10371            }
10372            pw.println();
10373            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10374            final int[] SINGLE_LONG_FORMAT = new int[] {
10375                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10376            };
10377            long[] longOut = new long[1];
10378            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10379                    SINGLE_LONG_FORMAT, null, longOut, null);
10380            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10381            longOut[0] = 0;
10382            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10383                    SINGLE_LONG_FORMAT, null, longOut, null);
10384            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10385            longOut[0] = 0;
10386            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10387                    SINGLE_LONG_FORMAT, null, longOut, null);
10388            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10389            longOut[0] = 0;
10390            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10391                    SINGLE_LONG_FORMAT, null, longOut, null);
10392            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10393            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10394                    pw.print(shared); pw.println(" kB");
10395            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10396                    pw.print(voltile); pw.println(" kB volatile");
10397        }
10398    }
10399
10400    /**
10401     * Searches array of arguments for the specified string
10402     * @param args array of argument strings
10403     * @param value value to search for
10404     * @return true if the value is contained in the array
10405     */
10406    private static boolean scanArgs(String[] args, String value) {
10407        if (args != null) {
10408            for (String arg : args) {
10409                if (value.equals(arg)) {
10410                    return true;
10411                }
10412            }
10413        }
10414        return false;
10415    }
10416
10417    private final void killServicesLocked(ProcessRecord app,
10418            boolean allowRestart) {
10419        // Report disconnected services.
10420        if (false) {
10421            // XXX we are letting the client link to the service for
10422            // death notifications.
10423            if (app.services.size() > 0) {
10424                Iterator<ServiceRecord> it = app.services.iterator();
10425                while (it.hasNext()) {
10426                    ServiceRecord r = it.next();
10427                    if (r.connections.size() > 0) {
10428                        Iterator<ArrayList<ConnectionRecord>> jt
10429                                = r.connections.values().iterator();
10430                        while (jt.hasNext()) {
10431                            ArrayList<ConnectionRecord> cl = jt.next();
10432                            for (int i=0; i<cl.size(); i++) {
10433                                ConnectionRecord c = cl.get(i);
10434                                if (c.binding.client != app) {
10435                                    try {
10436                                        //c.conn.connected(r.className, null);
10437                                    } catch (Exception e) {
10438                                        // todo: this should be asynchronous!
10439                                        Slog.w(TAG, "Exception thrown disconnected servce "
10440                                              + r.shortName
10441                                              + " from app " + app.processName, e);
10442                                    }
10443                                }
10444                            }
10445                        }
10446                    }
10447                }
10448            }
10449        }
10450
10451        // Clean up any connections this application has to other services.
10452        if (app.connections.size() > 0) {
10453            Iterator<ConnectionRecord> it = app.connections.iterator();
10454            while (it.hasNext()) {
10455                ConnectionRecord r = it.next();
10456                removeConnectionLocked(r, app, null);
10457            }
10458        }
10459        app.connections.clear();
10460
10461        if (app.services.size() != 0) {
10462            // Any services running in the application need to be placed
10463            // back in the pending list.
10464            Iterator<ServiceRecord> it = app.services.iterator();
10465            while (it.hasNext()) {
10466                ServiceRecord sr = it.next();
10467                synchronized (sr.stats.getBatteryStats()) {
10468                    sr.stats.stopLaunchedLocked();
10469                }
10470                sr.app = null;
10471                sr.isolatedProc = null;
10472                sr.executeNesting = 0;
10473                if (mStoppingServices.remove(sr)) {
10474                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10475                }
10476
10477                boolean hasClients = sr.bindings.size() > 0;
10478                if (hasClients) {
10479                    Iterator<IntentBindRecord> bindings
10480                            = sr.bindings.values().iterator();
10481                    while (bindings.hasNext()) {
10482                        IntentBindRecord b = bindings.next();
10483                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
10484                                + ": shouldUnbind=" + b.hasBound);
10485                        b.binder = null;
10486                        b.requested = b.received = b.hasBound = false;
10487                    }
10488                }
10489
10490                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10491                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
10492                    Slog.w(TAG, "Service crashed " + sr.crashCount
10493                            + " times, stopping: " + sr);
10494                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
10495                            sr.crashCount, sr.shortName, app.pid);
10496                    bringDownServiceLocked(sr, true);
10497                } else if (!allowRestart) {
10498                    bringDownServiceLocked(sr, true);
10499                } else {
10500                    boolean canceled = scheduleServiceRestartLocked(sr, true);
10501
10502                    // Should the service remain running?  Note that in the
10503                    // extreme case of so many attempts to deliver a command
10504                    // that it failed we also will stop it here.
10505                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10506                        if (sr.pendingStarts.size() == 0) {
10507                            sr.startRequested = false;
10508                            if (!hasClients) {
10509                                // Whoops, no reason to restart!
10510                                bringDownServiceLocked(sr, true);
10511                            }
10512                        }
10513                    }
10514                }
10515            }
10516
10517            if (!allowRestart) {
10518                app.services.clear();
10519            }
10520        }
10521
10522        // Make sure we have no more records on the stopping list.
10523        int i = mStoppingServices.size();
10524        while (i > 0) {
10525            i--;
10526            ServiceRecord sr = mStoppingServices.get(i);
10527            if (sr.app == app) {
10528                mStoppingServices.remove(i);
10529                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10530            }
10531        }
10532
10533        app.executingServices.clear();
10534    }
10535
10536    private final void removeDyingProviderLocked(ProcessRecord proc,
10537            ContentProviderRecord cpr) {
10538        synchronized (cpr) {
10539            cpr.launchingApp = null;
10540            cpr.notifyAll();
10541        }
10542
10543        mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10544        String names[] = cpr.info.authority.split(";");
10545        for (int j = 0; j < names.length; j++) {
10546            mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10547        }
10548
10549        Iterator<ProcessRecord> cit = cpr.clients.iterator();
10550        while (cit.hasNext()) {
10551            ProcessRecord capp = cit.next();
10552            if (!capp.persistent && capp.thread != null
10553                    && capp.pid != 0
10554                    && capp.pid != MY_PID) {
10555                Slog.i(TAG, "Kill " + capp.processName
10556                        + " (pid " + capp.pid + "): provider " + cpr.info.name
10557                        + " in dying process " + (proc != null ? proc.processName : "??"));
10558                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10559                        capp.processName, capp.setAdj, "dying provider "
10560                                + cpr.name.toShortString());
10561                Process.killProcessQuiet(capp.pid);
10562            }
10563        }
10564
10565        mLaunchingProviders.remove(cpr);
10566    }
10567
10568    /**
10569     * Main code for cleaning up a process when it has gone away.  This is
10570     * called both as a result of the process dying, or directly when stopping
10571     * a process when running in single process mode.
10572     */
10573    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10574            boolean restarting, boolean allowRestart, int index) {
10575        if (index >= 0) {
10576            mLruProcesses.remove(index);
10577        }
10578
10579        mProcessesToGc.remove(app);
10580
10581        // Dismiss any open dialogs.
10582        if (app.crashDialog != null) {
10583            app.crashDialog.dismiss();
10584            app.crashDialog = null;
10585        }
10586        if (app.anrDialog != null) {
10587            app.anrDialog.dismiss();
10588            app.anrDialog = null;
10589        }
10590        if (app.waitDialog != null) {
10591            app.waitDialog.dismiss();
10592            app.waitDialog = null;
10593        }
10594
10595        app.crashing = false;
10596        app.notResponding = false;
10597
10598        app.resetPackageList();
10599        app.unlinkDeathRecipient();
10600        app.thread = null;
10601        app.forcingToForeground = null;
10602        app.foregroundServices = false;
10603        app.foregroundActivities = false;
10604        app.hasShownUi = false;
10605        app.hasAboveClient = false;
10606
10607        killServicesLocked(app, allowRestart);
10608
10609        boolean restart = false;
10610
10611        int NL = mLaunchingProviders.size();
10612
10613        // Remove published content providers.
10614        if (!app.pubProviders.isEmpty()) {
10615            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10616            while (it.hasNext()) {
10617                ContentProviderRecord cpr = it.next();
10618                cpr.provider = null;
10619                cpr.proc = null;
10620
10621                // See if someone is waiting for this provider...  in which
10622                // case we don't remove it, but just let it restart.
10623                int i = 0;
10624                if (!app.bad && allowRestart) {
10625                    for (; i<NL; i++) {
10626                        if (mLaunchingProviders.get(i) == cpr) {
10627                            restart = true;
10628                            break;
10629                        }
10630                    }
10631                } else {
10632                    i = NL;
10633                }
10634
10635                if (i >= NL) {
10636                    removeDyingProviderLocked(app, cpr);
10637                    NL = mLaunchingProviders.size();
10638                }
10639            }
10640            app.pubProviders.clear();
10641        }
10642
10643        // Take care of any launching providers waiting for this process.
10644        if (checkAppInLaunchingProvidersLocked(app, false)) {
10645            restart = true;
10646        }
10647
10648        // Unregister from connected content providers.
10649        if (!app.conProviders.isEmpty()) {
10650            Iterator it = app.conProviders.keySet().iterator();
10651            while (it.hasNext()) {
10652                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10653                cpr.clients.remove(app);
10654            }
10655            app.conProviders.clear();
10656        }
10657
10658        // At this point there may be remaining entries in mLaunchingProviders
10659        // where we were the only one waiting, so they are no longer of use.
10660        // Look for these and clean up if found.
10661        // XXX Commented out for now.  Trying to figure out a way to reproduce
10662        // the actual situation to identify what is actually going on.
10663        if (false) {
10664            for (int i=0; i<NL; i++) {
10665                ContentProviderRecord cpr = (ContentProviderRecord)
10666                        mLaunchingProviders.get(i);
10667                if (cpr.clients.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10668                    synchronized (cpr) {
10669                        cpr.launchingApp = null;
10670                        cpr.notifyAll();
10671                    }
10672                }
10673            }
10674        }
10675
10676        skipCurrentReceiverLocked(app);
10677
10678        // Unregister any receivers.
10679        if (app.receivers.size() > 0) {
10680            Iterator<ReceiverList> it = app.receivers.iterator();
10681            while (it.hasNext()) {
10682                removeReceiverLocked(it.next());
10683            }
10684            app.receivers.clear();
10685        }
10686
10687        // If the app is undergoing backup, tell the backup manager about it
10688        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10689            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10690            try {
10691                IBackupManager bm = IBackupManager.Stub.asInterface(
10692                        ServiceManager.getService(Context.BACKUP_SERVICE));
10693                bm.agentDisconnected(app.info.packageName);
10694            } catch (RemoteException e) {
10695                // can't happen; backup manager is local
10696            }
10697        }
10698
10699        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10700
10701        // If the caller is restarting this app, then leave it in its
10702        // current lists and let the caller take care of it.
10703        if (restarting) {
10704            return;
10705        }
10706
10707        if (!app.persistent || app.isolated) {
10708            if (DEBUG_PROCESSES) Slog.v(TAG,
10709                    "Removing non-persistent process during cleanup: " + app);
10710            mProcessNames.remove(app.processName, app.uid);
10711            mIsolatedProcesses.remove(app.uid);
10712            if (mHeavyWeightProcess == app) {
10713                mHeavyWeightProcess = null;
10714                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10715            }
10716        } else if (!app.removed) {
10717            // This app is persistent, so we need to keep its record around.
10718            // If it is not already on the pending app list, add it there
10719            // and start a new process for it.
10720            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10721                mPersistentStartingProcesses.add(app);
10722                restart = true;
10723            }
10724        }
10725        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10726                "Clean-up removing on hold: " + app);
10727        mProcessesOnHold.remove(app);
10728
10729        if (app == mHomeProcess) {
10730            mHomeProcess = null;
10731        }
10732        if (app == mPreviousProcess) {
10733            mPreviousProcess = null;
10734        }
10735
10736        if (restart && !app.isolated) {
10737            // We have components that still need to be running in the
10738            // process, so re-launch it.
10739            mProcessNames.put(app.processName, app.uid, app);
10740            startProcessLocked(app, "restart", app.processName);
10741        } else if (app.pid > 0 && app.pid != MY_PID) {
10742            // Goodbye!
10743            synchronized (mPidsSelfLocked) {
10744                mPidsSelfLocked.remove(app.pid);
10745                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10746            }
10747            app.setPid(0);
10748        }
10749    }
10750
10751    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10752        // Look through the content providers we are waiting to have launched,
10753        // and if any run in this process then either schedule a restart of
10754        // the process or kill the client waiting for it if this process has
10755        // gone bad.
10756        int NL = mLaunchingProviders.size();
10757        boolean restart = false;
10758        for (int i=0; i<NL; i++) {
10759            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10760            if (cpr.launchingApp == app) {
10761                if (!alwaysBad && !app.bad) {
10762                    restart = true;
10763                } else {
10764                    removeDyingProviderLocked(app, cpr);
10765                    NL = mLaunchingProviders.size();
10766                }
10767            }
10768        }
10769        return restart;
10770    }
10771
10772    // =========================================================
10773    // SERVICES
10774    // =========================================================
10775
10776    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10777        ActivityManager.RunningServiceInfo info =
10778            new ActivityManager.RunningServiceInfo();
10779        info.service = r.name;
10780        if (r.app != null) {
10781            info.pid = r.app.pid;
10782        }
10783        info.uid = r.appInfo.uid;
10784        info.process = r.processName;
10785        info.foreground = r.isForeground;
10786        info.activeSince = r.createTime;
10787        info.started = r.startRequested;
10788        info.clientCount = r.connections.size();
10789        info.crashCount = r.crashCount;
10790        info.lastActivityTime = r.lastActivity;
10791        if (r.isForeground) {
10792            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10793        }
10794        if (r.startRequested) {
10795            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10796        }
10797        if (r.app != null && r.app.pid == MY_PID) {
10798            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10799        }
10800        if (r.app != null && r.app.persistent) {
10801            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10802        }
10803
10804        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10805            for (int i=0; i<connl.size(); i++) {
10806                ConnectionRecord conn = connl.get(i);
10807                if (conn.clientLabel != 0) {
10808                    info.clientPackage = conn.binding.client.info.packageName;
10809                    info.clientLabel = conn.clientLabel;
10810                    return info;
10811                }
10812            }
10813        }
10814        return info;
10815    }
10816
10817    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10818            int flags) {
10819        enforceNotIsolatedCaller("getServices");
10820        synchronized (this) {
10821            ArrayList<ActivityManager.RunningServiceInfo> res
10822                    = new ArrayList<ActivityManager.RunningServiceInfo>();
10823
10824            int userId = UserId.getUserId(Binder.getCallingUid());
10825            if (mServiceMap.getAllServices(userId).size() > 0) {
10826                Iterator<ServiceRecord> it
10827                        = mServiceMap.getAllServices(userId).iterator();
10828                while (it.hasNext() && res.size() < maxNum) {
10829                    res.add(makeRunningServiceInfoLocked(it.next()));
10830                }
10831            }
10832
10833            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10834                ServiceRecord r = mRestartingServices.get(i);
10835                ActivityManager.RunningServiceInfo info =
10836                        makeRunningServiceInfoLocked(r);
10837                info.restarting = r.nextRestartTime;
10838                res.add(info);
10839            }
10840
10841            return res;
10842        }
10843    }
10844
10845    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10846        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10847        synchronized (this) {
10848            int userId = UserId.getUserId(Binder.getCallingUid());
10849            ServiceRecord r = mServiceMap.getServiceByName(name, userId);
10850            if (r != null) {
10851                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10852                    for (int i=0; i<conn.size(); i++) {
10853                        if (conn.get(i).clientIntent != null) {
10854                            return conn.get(i).clientIntent;
10855                        }
10856                    }
10857                }
10858            }
10859        }
10860        return null;
10861    }
10862
10863    private final ServiceRecord findServiceLocked(ComponentName name,
10864            IBinder token) {
10865        ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
10866        return r == token ? r : null;
10867    }
10868
10869    private final class ServiceLookupResult {
10870        final ServiceRecord record;
10871        final String permission;
10872
10873        ServiceLookupResult(ServiceRecord _record, String _permission) {
10874            record = _record;
10875            permission = _permission;
10876        }
10877    };
10878
10879    private ServiceLookupResult findServiceLocked(Intent service,
10880            String resolvedType, int userId) {
10881        ServiceRecord r = null;
10882        if (service.getComponent() != null) {
10883            r = mServiceMap.getServiceByName(service.getComponent(), userId);
10884        }
10885        if (r == null) {
10886            Intent.FilterComparison filter = new Intent.FilterComparison(service);
10887            r = mServiceMap.getServiceByIntent(filter, userId);
10888        }
10889
10890        if (r == null) {
10891            try {
10892                ResolveInfo rInfo =
10893                    AppGlobals.getPackageManager().resolveService(
10894                                service, resolvedType, 0, userId);
10895                ServiceInfo sInfo =
10896                    rInfo != null ? rInfo.serviceInfo : null;
10897                if (sInfo == null) {
10898                    return null;
10899                }
10900
10901                ComponentName name = new ComponentName(
10902                        sInfo.applicationInfo.packageName, sInfo.name);
10903                r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
10904            } catch (RemoteException ex) {
10905                // pm is in same process, this will never happen.
10906            }
10907        }
10908        if (r != null) {
10909            int callingPid = Binder.getCallingPid();
10910            int callingUid = Binder.getCallingUid();
10911            if (checkComponentPermission(r.permission,
10912                    callingPid, callingUid, r.appInfo.uid, r.exported)
10913                    != PackageManager.PERMISSION_GRANTED) {
10914                if (!r.exported) {
10915                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10916                            + " from pid=" + callingPid
10917                            + ", uid=" + callingUid
10918                            + " that is not exported from uid " + r.appInfo.uid);
10919                    return new ServiceLookupResult(null, "not exported from uid "
10920                            + r.appInfo.uid);
10921                }
10922                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10923                        + " from pid=" + callingPid
10924                        + ", uid=" + callingUid
10925                        + " requires " + r.permission);
10926                return new ServiceLookupResult(null, r.permission);
10927            }
10928            return new ServiceLookupResult(r, null);
10929        }
10930        return null;
10931    }
10932
10933    private class ServiceRestarter implements Runnable {
10934        private ServiceRecord mService;
10935
10936        void setService(ServiceRecord service) {
10937            mService = service;
10938        }
10939
10940        public void run() {
10941            synchronized(ActivityManagerService.this) {
10942                performServiceRestartLocked(mService);
10943            }
10944        }
10945    }
10946
10947    private ServiceLookupResult retrieveServiceLocked(Intent service,
10948            String resolvedType, int callingPid, int callingUid, int userId) {
10949        ServiceRecord r = null;
10950        if (DEBUG_SERVICE)
10951            Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
10952                    + " callingUid=" + callingUid);
10953
10954        if (service.getComponent() != null) {
10955            r = mServiceMap.getServiceByName(service.getComponent(), userId);
10956        }
10957        if (r == null) {
10958            Intent.FilterComparison filter = new Intent.FilterComparison(service);
10959            r = mServiceMap.getServiceByIntent(filter, userId);
10960        }
10961        if (r == null) {
10962            try {
10963                ResolveInfo rInfo =
10964                    AppGlobals.getPackageManager().resolveService(
10965                                service, resolvedType, STOCK_PM_FLAGS, userId);
10966                ServiceInfo sInfo =
10967                    rInfo != null ? rInfo.serviceInfo : null;
10968                if (sInfo == null) {
10969                    Slog.w(TAG, "Unable to start service " + service +
10970                          ": not found");
10971                    return null;
10972                }
10973                if (userId > 0) {
10974                    if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
10975                        userId = 0;
10976                    }
10977                    sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
10978                }
10979                ComponentName name = new ComponentName(
10980                        sInfo.applicationInfo.packageName, sInfo.name);
10981                r = mServiceMap.getServiceByName(name, userId);
10982                if (r == null) {
10983                    Intent.FilterComparison filter = new Intent.FilterComparison(
10984                            service.cloneFilter());
10985                    ServiceRestarter res = new ServiceRestarter();
10986                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10987                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10988                    synchronized (stats) {
10989                        ss = stats.getServiceStatsLocked(
10990                                sInfo.applicationInfo.uid, sInfo.packageName,
10991                                sInfo.name);
10992                    }
10993                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
10994                    res.setService(r);
10995                    mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
10996                    mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
10997
10998                    // Make sure this component isn't in the pending list.
10999                    int N = mPendingServices.size();
11000                    for (int i=0; i<N; i++) {
11001                        ServiceRecord pr = mPendingServices.get(i);
11002                        if (pr.name.equals(name)) {
11003                            mPendingServices.remove(i);
11004                            i--;
11005                            N--;
11006                        }
11007                    }
11008                }
11009            } catch (RemoteException ex) {
11010                // pm is in same process, this will never happen.
11011            }
11012        }
11013        if (r != null) {
11014            if (checkComponentPermission(r.permission,
11015                    callingPid, callingUid, r.appInfo.uid, r.exported)
11016                    != PackageManager.PERMISSION_GRANTED) {
11017                if (!r.exported) {
11018                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11019                            + " from pid=" + callingPid
11020                            + ", uid=" + callingUid
11021                            + " that is not exported from uid " + r.appInfo.uid);
11022                    return new ServiceLookupResult(null, "not exported from uid "
11023                            + r.appInfo.uid);
11024                }
11025                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11026                        + " from pid=" + callingPid
11027                        + ", uid=" + callingUid
11028                        + " requires " + r.permission);
11029                return new ServiceLookupResult(null, r.permission);
11030            }
11031            return new ServiceLookupResult(r, null);
11032        }
11033        return null;
11034    }
11035
11036    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11037        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11038                + why + " of " + r + " in app " + r.app);
11039        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11040                + why + " of " + r.shortName);
11041        long now = SystemClock.uptimeMillis();
11042        if (r.executeNesting == 0 && r.app != null) {
11043            if (r.app.executingServices.size() == 0) {
11044                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11045                msg.obj = r.app;
11046                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11047            }
11048            r.app.executingServices.add(r);
11049        }
11050        r.executeNesting++;
11051        r.executingStart = now;
11052    }
11053
11054    private final void sendServiceArgsLocked(ServiceRecord r,
11055            boolean oomAdjusted) {
11056        final int N = r.pendingStarts.size();
11057        if (N == 0) {
11058            return;
11059        }
11060
11061        while (r.pendingStarts.size() > 0) {
11062            try {
11063                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
11064                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11065                        + r + " " + r.intent + " args=" + si.intent);
11066                if (si.intent == null && N > 1) {
11067                    // If somehow we got a dummy null intent in the middle,
11068                    // then skip it.  DO NOT skip a null intent when it is
11069                    // the only one in the list -- this is to support the
11070                    // onStartCommand(null) case.
11071                    continue;
11072                }
11073                si.deliveredTime = SystemClock.uptimeMillis();
11074                r.deliveredStarts.add(si);
11075                si.deliveryCount++;
11076                if (si.neededGrants != null) {
11077                    grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
11078                            si.getUriPermissionsLocked());
11079                }
11080                bumpServiceExecutingLocked(r, "start");
11081                if (!oomAdjusted) {
11082                    oomAdjusted = true;
11083                    updateOomAdjLocked(r.app);
11084                }
11085                int flags = 0;
11086                if (si.deliveryCount > 1) {
11087                    flags |= Service.START_FLAG_RETRY;
11088                }
11089                if (si.doneExecutingCount > 0) {
11090                    flags |= Service.START_FLAG_REDELIVERY;
11091                }
11092                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
11093            } catch (RemoteException e) {
11094                // Remote process gone...  we'll let the normal cleanup take
11095                // care of this.
11096                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
11097                break;
11098            } catch (Exception e) {
11099                Slog.w(TAG, "Unexpected exception", e);
11100                break;
11101            }
11102        }
11103    }
11104
11105    private final boolean requestServiceBindingLocked(ServiceRecord r,
11106            IntentBindRecord i, boolean rebind) {
11107        if (r.app == null || r.app.thread == null) {
11108            // If service is not currently running, can't yet bind.
11109            return false;
11110        }
11111        if ((!i.requested || rebind) && i.apps.size() > 0) {
11112            try {
11113                bumpServiceExecutingLocked(r, "bind");
11114                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11115                if (!rebind) {
11116                    i.requested = true;
11117                }
11118                i.hasBound = true;
11119                i.doRebind = false;
11120            } catch (RemoteException e) {
11121                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
11122                return false;
11123            }
11124        }
11125        return true;
11126    }
11127
11128    private final void requestServiceBindingsLocked(ServiceRecord r) {
11129        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11130        while (bindings.hasNext()) {
11131            IntentBindRecord i = bindings.next();
11132            if (!requestServiceBindingLocked(r, i, false)) {
11133                break;
11134            }
11135        }
11136    }
11137
11138    private final void realStartServiceLocked(ServiceRecord r,
11139            ProcessRecord app) throws RemoteException {
11140        if (app.thread == null) {
11141            throw new RemoteException();
11142        }
11143        if (DEBUG_MU)
11144            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
11145                    + ", ProcessRecord.uid = " + app.uid);
11146        r.app = app;
11147        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
11148
11149        app.services.add(r);
11150        bumpServiceExecutingLocked(r, "create");
11151        updateLruProcessLocked(app, true, true);
11152
11153        boolean created = false;
11154        try {
11155            mStringBuilder.setLength(0);
11156            r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false);
11157            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
11158                    System.identityHashCode(r), r.shortName,
11159                    mStringBuilder.toString(), r.app.pid);
11160            synchronized (r.stats.getBatteryStats()) {
11161                r.stats.startLaunchedLocked();
11162            }
11163            ensurePackageDexOpt(r.serviceInfo.packageName);
11164            app.thread.scheduleCreateService(r, r.serviceInfo,
11165                    compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
11166            r.postNotification();
11167            created = true;
11168        } finally {
11169            if (!created) {
11170                app.services.remove(r);
11171                scheduleServiceRestartLocked(r, false);
11172            }
11173        }
11174
11175        requestServiceBindingsLocked(r);
11176
11177        // If the service is in the started state, and there are no
11178        // pending arguments, then fake up one so its onStartCommand() will
11179        // be called.
11180        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
11181            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11182                    null, null));
11183        }
11184
11185        sendServiceArgsLocked(r, true);
11186    }
11187
11188    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11189            boolean allowCancel) {
11190        boolean canceled = false;
11191
11192        final long now = SystemClock.uptimeMillis();
11193        long minDuration = SERVICE_RESTART_DURATION;
11194        long resetTime = SERVICE_RESET_RUN_DURATION;
11195
11196        if ((r.serviceInfo.applicationInfo.flags
11197                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11198            minDuration /= 4;
11199        }
11200
11201        // Any delivered but not yet finished starts should be put back
11202        // on the pending list.
11203        final int N = r.deliveredStarts.size();
11204        if (N > 0) {
11205            for (int i=N-1; i>=0; i--) {
11206                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
11207                si.removeUriPermissionsLocked();
11208                if (si.intent == null) {
11209                    // We'll generate this again if needed.
11210                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11211                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11212                    r.pendingStarts.add(0, si);
11213                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11214                    dur *= 2;
11215                    if (minDuration < dur) minDuration = dur;
11216                    if (resetTime < dur) resetTime = dur;
11217                } else {
11218                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
11219                            + r.name);
11220                    canceled = true;
11221                }
11222            }
11223            r.deliveredStarts.clear();
11224        }
11225
11226        r.totalRestartCount++;
11227        if (r.restartDelay == 0) {
11228            r.restartCount++;
11229            r.restartDelay = minDuration;
11230        } else {
11231            // If it has been a "reasonably long time" since the service
11232            // was started, then reset our restart duration back to
11233            // the beginning, so we don't infinitely increase the duration
11234            // on a service that just occasionally gets killed (which is
11235            // a normal case, due to process being killed to reclaim memory).
11236            if (now > (r.restartTime+resetTime)) {
11237                r.restartCount = 1;
11238                r.restartDelay = minDuration;
11239            } else {
11240                if ((r.serviceInfo.applicationInfo.flags
11241                        &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11242                    // Services in peristent processes will restart much more
11243                    // quickly, since they are pretty important.  (Think SystemUI).
11244                    r.restartDelay += minDuration/2;
11245                } else {
11246                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11247                    if (r.restartDelay < minDuration) {
11248                        r.restartDelay = minDuration;
11249                    }
11250                }
11251            }
11252        }
11253
11254        r.nextRestartTime = now + r.restartDelay;
11255
11256        // Make sure that we don't end up restarting a bunch of services
11257        // all at the same time.
11258        boolean repeat;
11259        do {
11260            repeat = false;
11261            for (int i=mRestartingServices.size()-1; i>=0; i--) {
11262                ServiceRecord r2 = mRestartingServices.get(i);
11263                if (r2 != r && r.nextRestartTime
11264                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11265                        && r.nextRestartTime
11266                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11267                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11268                    r.restartDelay = r.nextRestartTime - now;
11269                    repeat = true;
11270                    break;
11271                }
11272            }
11273        } while (repeat);
11274
11275        if (!mRestartingServices.contains(r)) {
11276            mRestartingServices.add(r);
11277        }
11278
11279        r.cancelNotification();
11280
11281        mHandler.removeCallbacks(r.restarter);
11282        mHandler.postAtTime(r.restarter, r.nextRestartTime);
11283        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
11284        Slog.w(TAG, "Scheduling restart of crashed service "
11285                + r.shortName + " in " + r.restartDelay + "ms");
11286        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
11287                r.shortName, r.restartDelay);
11288
11289        return canceled;
11290    }
11291
11292    final void performServiceRestartLocked(ServiceRecord r) {
11293        if (!mRestartingServices.contains(r)) {
11294            return;
11295        }
11296        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11297    }
11298
11299    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11300        if (r.restartDelay == 0) {
11301            return false;
11302        }
11303        r.resetRestartCounter();
11304        mRestartingServices.remove(r);
11305        mHandler.removeCallbacks(r.restarter);
11306        return true;
11307    }
11308
11309    private final boolean bringUpServiceLocked(ServiceRecord r,
11310            int intentFlags, boolean whileRestarting) {
11311        //Slog.i(TAG, "Bring up service:");
11312        //r.dump("  ");
11313
11314        if (r.app != null && r.app.thread != null) {
11315            sendServiceArgsLocked(r, false);
11316            return true;
11317        }
11318
11319        if (!whileRestarting && r.restartDelay > 0) {
11320            // If waiting for a restart, then do nothing.
11321            return true;
11322        }
11323
11324        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
11325
11326        // We are now bringing the service up, so no longer in the
11327        // restarting state.
11328        mRestartingServices.remove(r);
11329
11330        // Service is now being launched, its package can't be stopped.
11331        try {
11332            AppGlobals.getPackageManager().setPackageStoppedState(
11333                    r.packageName, false, r.userId);
11334        } catch (RemoteException e) {
11335        } catch (IllegalArgumentException e) {
11336            Slog.w(TAG, "Failed trying to unstop package "
11337                    + r.packageName + ": " + e);
11338        }
11339
11340        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
11341        final String appName = r.processName;
11342        ProcessRecord app;
11343
11344        if (!isolated) {
11345            app = getProcessRecordLocked(appName, r.appInfo.uid);
11346            if (DEBUG_MU)
11347                Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11348            if (app != null && app.thread != null) {
11349                try {
11350                    app.addPackage(r.appInfo.packageName);
11351                    realStartServiceLocked(r, app);
11352                    return true;
11353                } catch (RemoteException e) {
11354                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11355                }
11356
11357                // If a dead object exception was thrown -- fall through to
11358                // restart the application.
11359            }
11360        } else {
11361            // If this service runs in an isolated process, then each time
11362            // we call startProcessLocked() we will get a new isolated
11363            // process, starting another process if we are currently waiting
11364            // for a previous process to come up.  To deal with this, we store
11365            // in the service any current isolated process it is running in or
11366            // waiting to have come up.
11367            app = r.isolatedProc;
11368        }
11369
11370        // Not running -- get it started, and enqueue this service record
11371        // to be executed when the app comes up.
11372        if (app == null) {
11373            if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11374                    "service", r.name, false, isolated)) == null) {
11375                Slog.w(TAG, "Unable to launch app "
11376                        + r.appInfo.packageName + "/"
11377                        + r.appInfo.uid + " for service "
11378                        + r.intent.getIntent() + ": process is bad");
11379                bringDownServiceLocked(r, true);
11380                return false;
11381            }
11382            if (isolated) {
11383                r.isolatedProc = app;
11384            }
11385        }
11386
11387        if (!mPendingServices.contains(r)) {
11388            mPendingServices.add(r);
11389        }
11390
11391        return true;
11392    }
11393
11394    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
11395        //Slog.i(TAG, "Bring down service:");
11396        //r.dump("  ");
11397
11398        // Does it still need to run?
11399        if (!force && r.startRequested) {
11400            return;
11401        }
11402        if (r.connections.size() > 0) {
11403            if (!force) {
11404                // XXX should probably keep a count of the number of auto-create
11405                // connections directly in the service.
11406                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11407                while (it.hasNext()) {
11408                    ArrayList<ConnectionRecord> cr = it.next();
11409                    for (int i=0; i<cr.size(); i++) {
11410                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11411                            return;
11412                        }
11413                    }
11414                }
11415            }
11416
11417            // Report to all of the connections that the service is no longer
11418            // available.
11419            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11420            while (it.hasNext()) {
11421                ArrayList<ConnectionRecord> c = it.next();
11422                for (int i=0; i<c.size(); i++) {
11423                    ConnectionRecord cr = c.get(i);
11424                    // There is still a connection to the service that is
11425                    // being brought down.  Mark it as dead.
11426                    cr.serviceDead = true;
11427                    try {
11428                        cr.conn.connected(r.name, null);
11429                    } catch (Exception e) {
11430                        Slog.w(TAG, "Failure disconnecting service " + r.name +
11431                              " to connection " + c.get(i).conn.asBinder() +
11432                              " (in " + c.get(i).binding.client.processName + ")", e);
11433                    }
11434                }
11435            }
11436        }
11437
11438        // Tell the service that it has been unbound.
11439        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11440            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11441            while (it.hasNext()) {
11442                IntentBindRecord ibr = it.next();
11443                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
11444                        + ": hasBound=" + ibr.hasBound);
11445                if (r.app != null && r.app.thread != null && ibr.hasBound) {
11446                    try {
11447                        bumpServiceExecutingLocked(r, "bring down unbind");
11448                        updateOomAdjLocked(r.app);
11449                        ibr.hasBound = false;
11450                        r.app.thread.scheduleUnbindService(r,
11451                                ibr.intent.getIntent());
11452                    } catch (Exception e) {
11453                        Slog.w(TAG, "Exception when unbinding service "
11454                                + r.shortName, e);
11455                        serviceDoneExecutingLocked(r, true);
11456                    }
11457                }
11458            }
11459        }
11460
11461        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
11462        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
11463                System.identityHashCode(r), r.shortName,
11464                (r.app != null) ? r.app.pid : -1);
11465
11466        mServiceMap.removeServiceByName(r.name, r.userId);
11467        mServiceMap.removeServiceByIntent(r.intent, r.userId);
11468        r.totalRestartCount = 0;
11469        unscheduleServiceRestartLocked(r);
11470
11471        // Also make sure it is not on the pending list.
11472        int N = mPendingServices.size();
11473        for (int i=0; i<N; i++) {
11474            if (mPendingServices.get(i) == r) {
11475                mPendingServices.remove(i);
11476                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
11477                i--;
11478                N--;
11479            }
11480        }
11481
11482        r.cancelNotification();
11483        r.isForeground = false;
11484        r.foregroundId = 0;
11485        r.foregroundNoti = null;
11486
11487        // Clear start entries.
11488        r.clearDeliveredStartsLocked();
11489        r.pendingStarts.clear();
11490
11491        if (r.app != null) {
11492            synchronized (r.stats.getBatteryStats()) {
11493                r.stats.stopLaunchedLocked();
11494            }
11495            r.app.services.remove(r);
11496            if (r.app.thread != null) {
11497                try {
11498                    bumpServiceExecutingLocked(r, "stop");
11499                    mStoppingServices.add(r);
11500                    updateOomAdjLocked(r.app);
11501                    r.app.thread.scheduleStopService(r);
11502                } catch (Exception e) {
11503                    Slog.w(TAG, "Exception when stopping service "
11504                            + r.shortName, e);
11505                    serviceDoneExecutingLocked(r, true);
11506                }
11507                updateServiceForegroundLocked(r.app, false);
11508            } else {
11509                if (DEBUG_SERVICE) Slog.v(
11510                    TAG, "Removed service that has no process: " + r);
11511            }
11512        } else {
11513            if (DEBUG_SERVICE) Slog.v(
11514                TAG, "Removed service that is not running: " + r);
11515        }
11516
11517        if (r.bindings.size() > 0) {
11518            r.bindings.clear();
11519        }
11520
11521        if (r.restarter instanceof ServiceRestarter) {
11522           ((ServiceRestarter)r.restarter).setService(null);
11523        }
11524    }
11525
11526    ComponentName startServiceLocked(IApplicationThread caller,
11527            Intent service, String resolvedType,
11528            int callingPid, int callingUid) {
11529        synchronized(this) {
11530            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
11531                    + " type=" + resolvedType + " args=" + service.getExtras());
11532
11533            if (caller != null) {
11534                final ProcessRecord callerApp = getRecordForAppLocked(caller);
11535                if (callerApp == null) {
11536                    throw new SecurityException(
11537                            "Unable to find app for caller " + caller
11538                            + " (pid=" + Binder.getCallingPid()
11539                            + ") when starting service " + service);
11540                }
11541            }
11542
11543            ServiceLookupResult res =
11544                retrieveServiceLocked(service, resolvedType,
11545                        callingPid, callingUid, UserId.getUserId(callingUid));
11546            if (res == null) {
11547                return null;
11548            }
11549            if (res.record == null) {
11550                return new ComponentName("!", res.permission != null
11551                        ? res.permission : "private to package");
11552            }
11553            ServiceRecord r = res.record;
11554            NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked(
11555                    callingUid, r.packageName, service, service.getFlags(), null);
11556            if (unscheduleServiceRestartLocked(r)) {
11557                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
11558            }
11559            r.startRequested = true;
11560            r.callStart = false;
11561            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11562                    service, neededGrants));
11563            r.lastActivity = SystemClock.uptimeMillis();
11564            synchronized (r.stats.getBatteryStats()) {
11565                r.stats.startRunningLocked();
11566            }
11567            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11568                return new ComponentName("!", "Service process is bad");
11569            }
11570            return r.name;
11571        }
11572    }
11573
11574    public ComponentName startService(IApplicationThread caller, Intent service,
11575            String resolvedType) {
11576        enforceNotIsolatedCaller("startService");
11577        // Refuse possible leaked file descriptors
11578        if (service != null && service.hasFileDescriptors() == true) {
11579            throw new IllegalArgumentException("File descriptors passed in Intent");
11580        }
11581
11582        if (DEBUG_SERVICE)
11583            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
11584        synchronized(this) {
11585            final int callingPid = Binder.getCallingPid();
11586            final int callingUid = Binder.getCallingUid();
11587            final long origId = Binder.clearCallingIdentity();
11588            ComponentName res = startServiceLocked(caller, service,
11589                    resolvedType, callingPid, callingUid);
11590            Binder.restoreCallingIdentity(origId);
11591            return res;
11592        }
11593    }
11594
11595    ComponentName startServiceInPackage(int uid,
11596            Intent service, String resolvedType) {
11597        synchronized(this) {
11598            if (DEBUG_SERVICE)
11599                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
11600            final long origId = Binder.clearCallingIdentity();
11601            ComponentName res = startServiceLocked(null, service,
11602                    resolvedType, -1, uid);
11603            Binder.restoreCallingIdentity(origId);
11604            return res;
11605        }
11606    }
11607
11608    private void stopServiceLocked(ServiceRecord service) {
11609        synchronized (service.stats.getBatteryStats()) {
11610            service.stats.stopRunningLocked();
11611        }
11612        service.startRequested = false;
11613        service.callStart = false;
11614        bringDownServiceLocked(service, false);
11615    }
11616
11617    public int stopService(IApplicationThread caller, Intent service,
11618            String resolvedType) {
11619        enforceNotIsolatedCaller("stopService");
11620        // Refuse possible leaked file descriptors
11621        if (service != null && service.hasFileDescriptors() == true) {
11622            throw new IllegalArgumentException("File descriptors passed in Intent");
11623        }
11624
11625        synchronized(this) {
11626            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
11627                    + " type=" + resolvedType);
11628
11629            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11630            if (caller != null && callerApp == null) {
11631                throw new SecurityException(
11632                        "Unable to find app for caller " + caller
11633                        + " (pid=" + Binder.getCallingPid()
11634                        + ") when stopping service " + service);
11635            }
11636
11637            // If this service is active, make sure it is stopped.
11638            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11639                    callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
11640            if (r != null) {
11641                if (r.record != null) {
11642                    final long origId = Binder.clearCallingIdentity();
11643                    try {
11644                        stopServiceLocked(r.record);
11645                    } finally {
11646                        Binder.restoreCallingIdentity(origId);
11647                    }
11648                    return 1;
11649                }
11650                return -1;
11651            }
11652        }
11653
11654        return 0;
11655    }
11656
11657    public IBinder peekService(Intent service, String resolvedType) {
11658        enforceNotIsolatedCaller("peekService");
11659        // Refuse possible leaked file descriptors
11660        if (service != null && service.hasFileDescriptors() == true) {
11661            throw new IllegalArgumentException("File descriptors passed in Intent");
11662        }
11663
11664        IBinder ret = null;
11665
11666        synchronized(this) {
11667            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11668                    UserId.getCallingUserId());
11669
11670            if (r != null) {
11671                // r.record is null if findServiceLocked() failed the caller permission check
11672                if (r.record == null) {
11673                    throw new SecurityException(
11674                            "Permission Denial: Accessing service " + r.record.name
11675                            + " from pid=" + Binder.getCallingPid()
11676                            + ", uid=" + Binder.getCallingUid()
11677                            + " requires " + r.permission);
11678                }
11679                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11680                if (ib != null) {
11681                    ret = ib.binder;
11682                }
11683            }
11684        }
11685
11686        return ret;
11687    }
11688
11689    public boolean stopServiceToken(ComponentName className, IBinder token,
11690            int startId) {
11691        synchronized(this) {
11692            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
11693                    + " " + token + " startId=" + startId);
11694            ServiceRecord r = findServiceLocked(className, token);
11695            if (r != null) {
11696                if (startId >= 0) {
11697                    // Asked to only stop if done with all work.  Note that
11698                    // to avoid leaks, we will take this as dropping all
11699                    // start items up to and including this one.
11700                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11701                    if (si != null) {
11702                        while (r.deliveredStarts.size() > 0) {
11703                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11704                            cur.removeUriPermissionsLocked();
11705                            if (cur == si) {
11706                                break;
11707                            }
11708                        }
11709                    }
11710
11711                    if (r.getLastStartId() != startId) {
11712                        return false;
11713                    }
11714
11715                    if (r.deliveredStarts.size() > 0) {
11716                        Slog.w(TAG, "stopServiceToken startId " + startId
11717                                + " is last, but have " + r.deliveredStarts.size()
11718                                + " remaining args");
11719                    }
11720                }
11721
11722                synchronized (r.stats.getBatteryStats()) {
11723                    r.stats.stopRunningLocked();
11724                    r.startRequested = false;
11725                    r.callStart = false;
11726                }
11727                final long origId = Binder.clearCallingIdentity();
11728                bringDownServiceLocked(r, false);
11729                Binder.restoreCallingIdentity(origId);
11730                return true;
11731            }
11732        }
11733        return false;
11734    }
11735
11736    public void setServiceForeground(ComponentName className, IBinder token,
11737            int id, Notification notification, boolean removeNotification) {
11738        final long origId = Binder.clearCallingIdentity();
11739        try {
11740        synchronized(this) {
11741            ServiceRecord r = findServiceLocked(className, token);
11742            if (r != null) {
11743                if (id != 0) {
11744                    if (notification == null) {
11745                        throw new IllegalArgumentException("null notification");
11746                    }
11747                    if (r.foregroundId != id) {
11748                        r.cancelNotification();
11749                        r.foregroundId = id;
11750                    }
11751                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11752                    r.foregroundNoti = notification;
11753                    r.isForeground = true;
11754                    r.postNotification();
11755                    if (r.app != null) {
11756                        updateServiceForegroundLocked(r.app, true);
11757                    }
11758                } else {
11759                    if (r.isForeground) {
11760                        r.isForeground = false;
11761                        if (r.app != null) {
11762                            updateLruProcessLocked(r.app, false, true);
11763                            updateServiceForegroundLocked(r.app, true);
11764                        }
11765                    }
11766                    if (removeNotification) {
11767                        r.cancelNotification();
11768                        r.foregroundId = 0;
11769                        r.foregroundNoti = null;
11770                    }
11771                }
11772            }
11773        }
11774        } finally {
11775            Binder.restoreCallingIdentity(origId);
11776        }
11777    }
11778
11779    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11780        boolean anyForeground = false;
11781        for (ServiceRecord sr : proc.services) {
11782            if (sr.isForeground) {
11783                anyForeground = true;
11784                break;
11785            }
11786        }
11787        if (anyForeground != proc.foregroundServices) {
11788            proc.foregroundServices = anyForeground;
11789            if (oomAdj) {
11790                updateOomAdjLocked();
11791            }
11792        }
11793    }
11794
11795    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) {
11796        boolean result = false;
11797        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11798            result = false;
11799        } else if (componentProcessName == aInfo.packageName) {
11800            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11801        } else if ("system".equals(componentProcessName)) {
11802            result = true;
11803        }
11804        if (DEBUG_MU) {
11805            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result);
11806        }
11807        return result;
11808    }
11809
11810    public int bindService(IApplicationThread caller, IBinder token,
11811            Intent service, String resolvedType,
11812            IServiceConnection connection, int flags, int userId) {
11813        enforceNotIsolatedCaller("bindService");
11814        // Refuse possible leaked file descriptors
11815        if (service != null && service.hasFileDescriptors() == true) {
11816            throw new IllegalArgumentException("File descriptors passed in Intent");
11817        }
11818
11819        checkValidCaller(Binder.getCallingUid(), userId);
11820
11821        synchronized(this) {
11822            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
11823                    + " type=" + resolvedType + " conn=" + connection.asBinder()
11824                    + " flags=0x" + Integer.toHexString(flags));
11825            if (DEBUG_MU)
11826                Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
11827                        + Binder.getOrigCallingUid());
11828            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11829            if (callerApp == null) {
11830                throw new SecurityException(
11831                        "Unable to find app for caller " + caller
11832                        + " (pid=" + Binder.getCallingPid()
11833                        + ") when binding service " + service);
11834            }
11835
11836            ActivityRecord activity = null;
11837            if (token != null) {
11838                activity = mMainStack.isInStackLocked(token);
11839                if (activity == null) {
11840                    Slog.w(TAG, "Binding with unknown activity: " + token);
11841                    return 0;
11842                }
11843            }
11844
11845            int clientLabel = 0;
11846            PendingIntent clientIntent = null;
11847
11848            if (callerApp.info.uid == Process.SYSTEM_UID) {
11849                // Hacky kind of thing -- allow system stuff to tell us
11850                // what they are, so we can report this elsewhere for
11851                // others to know why certain services are running.
11852                try {
11853                    clientIntent = (PendingIntent)service.getParcelableExtra(
11854                            Intent.EXTRA_CLIENT_INTENT);
11855                } catch (RuntimeException e) {
11856                }
11857                if (clientIntent != null) {
11858                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11859                    if (clientLabel != 0) {
11860                        // There are no useful extras in the intent, trash them.
11861                        // System code calling with this stuff just needs to know
11862                        // this will happen.
11863                        service = service.cloneFilter();
11864                    }
11865                }
11866            }
11867
11868            ServiceLookupResult res =
11869                retrieveServiceLocked(service, resolvedType,
11870                        Binder.getCallingPid(), Binder.getCallingUid(), userId);
11871            if (res == null) {
11872                return 0;
11873            }
11874            if (res.record == null) {
11875                return -1;
11876            }
11877            if (isSingleton(res.record.processName, res.record.appInfo)) {
11878                userId = 0;
11879                res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
11880                        Binder.getCallingUid(), 0);
11881            }
11882            ServiceRecord s = res.record;
11883
11884            final long origId = Binder.clearCallingIdentity();
11885
11886            if (unscheduleServiceRestartLocked(s)) {
11887                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
11888                        + s);
11889            }
11890
11891            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11892            ConnectionRecord c = new ConnectionRecord(b, activity,
11893                    connection, flags, clientLabel, clientIntent);
11894
11895            IBinder binder = connection.asBinder();
11896            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11897            if (clist == null) {
11898                clist = new ArrayList<ConnectionRecord>();
11899                s.connections.put(binder, clist);
11900            }
11901            clist.add(c);
11902            b.connections.add(c);
11903            if (activity != null) {
11904                if (activity.connections == null) {
11905                    activity.connections = new HashSet<ConnectionRecord>();
11906                }
11907                activity.connections.add(c);
11908            }
11909            b.client.connections.add(c);
11910            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11911                b.client.hasAboveClient = true;
11912            }
11913            clist = mServiceConnections.get(binder);
11914            if (clist == null) {
11915                clist = new ArrayList<ConnectionRecord>();
11916                mServiceConnections.put(binder, clist);
11917            }
11918            clist.add(c);
11919
11920            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11921                s.lastActivity = SystemClock.uptimeMillis();
11922                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11923                    return 0;
11924                }
11925            }
11926
11927            if (s.app != null) {
11928                // This could have made the service more important.
11929                updateOomAdjLocked(s.app);
11930            }
11931
11932            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
11933                    + ": received=" + b.intent.received
11934                    + " apps=" + b.intent.apps.size()
11935                    + " doRebind=" + b.intent.doRebind);
11936
11937            if (s.app != null && b.intent.received) {
11938                // Service is already running, so we can immediately
11939                // publish the connection.
11940                try {
11941                    c.conn.connected(s.name, b.intent.binder);
11942                } catch (Exception e) {
11943                    Slog.w(TAG, "Failure sending service " + s.shortName
11944                            + " to connection " + c.conn.asBinder()
11945                            + " (in " + c.binding.client.processName + ")", e);
11946                }
11947
11948                // If this is the first app connected back to this binding,
11949                // and the service had previously asked to be told when
11950                // rebound, then do so.
11951                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11952                    requestServiceBindingLocked(s, b.intent, true);
11953                }
11954            } else if (!b.intent.requested) {
11955                requestServiceBindingLocked(s, b.intent, false);
11956            }
11957
11958            Binder.restoreCallingIdentity(origId);
11959        }
11960
11961        return 1;
11962    }
11963
11964    void removeConnectionLocked(
11965        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
11966        IBinder binder = c.conn.asBinder();
11967        AppBindRecord b = c.binding;
11968        ServiceRecord s = b.service;
11969        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11970        if (clist != null) {
11971            clist.remove(c);
11972            if (clist.size() == 0) {
11973                s.connections.remove(binder);
11974            }
11975        }
11976        b.connections.remove(c);
11977        if (c.activity != null && c.activity != skipAct) {
11978            if (c.activity.connections != null) {
11979                c.activity.connections.remove(c);
11980            }
11981        }
11982        if (b.client != skipApp) {
11983            b.client.connections.remove(c);
11984            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11985                b.client.updateHasAboveClientLocked();
11986            }
11987        }
11988        clist = mServiceConnections.get(binder);
11989        if (clist != null) {
11990            clist.remove(c);
11991            if (clist.size() == 0) {
11992                mServiceConnections.remove(binder);
11993            }
11994        }
11995
11996        if (b.connections.size() == 0) {
11997            b.intent.apps.remove(b.client);
11998        }
11999
12000        if (!c.serviceDead) {
12001            if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12002                    + ": shouldUnbind=" + b.intent.hasBound);
12003            if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12004                    && b.intent.hasBound) {
12005                try {
12006                    bumpServiceExecutingLocked(s, "unbind");
12007                    updateOomAdjLocked(s.app);
12008                    b.intent.hasBound = false;
12009                    // Assume the client doesn't want to know about a rebind;
12010                    // we will deal with that later if it asks for one.
12011                    b.intent.doRebind = false;
12012                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12013                } catch (Exception e) {
12014                    Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12015                    serviceDoneExecutingLocked(s, true);
12016                }
12017            }
12018
12019            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12020                bringDownServiceLocked(s, false);
12021            }
12022        }
12023    }
12024
12025    public boolean unbindService(IServiceConnection connection) {
12026        synchronized (this) {
12027            IBinder binder = connection.asBinder();
12028            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
12029            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12030            if (clist == null) {
12031                Slog.w(TAG, "Unbind failed: could not find connection for "
12032                      + connection.asBinder());
12033                return false;
12034            }
12035
12036            final long origId = Binder.clearCallingIdentity();
12037
12038            while (clist.size() > 0) {
12039                ConnectionRecord r = clist.get(0);
12040                removeConnectionLocked(r, null, null);
12041
12042                if (r.binding.service.app != null) {
12043                    // This could have made the service less important.
12044                    updateOomAdjLocked(r.binding.service.app);
12045                }
12046            }
12047
12048            Binder.restoreCallingIdentity(origId);
12049        }
12050
12051        return true;
12052    }
12053
12054    public void publishService(IBinder token, Intent intent, IBinder service) {
12055        // Refuse possible leaked file descriptors
12056        if (intent != null && intent.hasFileDescriptors() == true) {
12057            throw new IllegalArgumentException("File descriptors passed in Intent");
12058        }
12059
12060        synchronized(this) {
12061            if (!(token instanceof ServiceRecord)) {
12062                throw new IllegalArgumentException("Invalid service token");
12063            }
12064            ServiceRecord r = (ServiceRecord)token;
12065
12066            final long origId = Binder.clearCallingIdentity();
12067
12068            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
12069                    + " " + intent + ": " + service);
12070            if (r != null) {
12071                Intent.FilterComparison filter
12072                        = new Intent.FilterComparison(intent);
12073                IntentBindRecord b = r.bindings.get(filter);
12074                if (b != null && !b.received) {
12075                    b.binder = service;
12076                    b.requested = true;
12077                    b.received = true;
12078                    if (r.connections.size() > 0) {
12079                        Iterator<ArrayList<ConnectionRecord>> it
12080                                = r.connections.values().iterator();
12081                        while (it.hasNext()) {
12082                            ArrayList<ConnectionRecord> clist = it.next();
12083                            for (int i=0; i<clist.size(); i++) {
12084                                ConnectionRecord c = clist.get(i);
12085                                if (!filter.equals(c.binding.intent.intent)) {
12086                                    if (DEBUG_SERVICE) Slog.v(
12087                                            TAG, "Not publishing to: " + c);
12088                                    if (DEBUG_SERVICE) Slog.v(
12089                                            TAG, "Bound intent: " + c.binding.intent.intent);
12090                                    if (DEBUG_SERVICE) Slog.v(
12091                                            TAG, "Published intent: " + intent);
12092                                    continue;
12093                                }
12094                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12095                                try {
12096                                    c.conn.connected(r.name, service);
12097                                } catch (Exception e) {
12098                                    Slog.w(TAG, "Failure sending service " + r.name +
12099                                          " to connection " + c.conn.asBinder() +
12100                                          " (in " + c.binding.client.processName + ")", e);
12101                                }
12102                            }
12103                        }
12104                    }
12105                }
12106
12107                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12108
12109                Binder.restoreCallingIdentity(origId);
12110            }
12111        }
12112    }
12113
12114    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12115        // Refuse possible leaked file descriptors
12116        if (intent != null && intent.hasFileDescriptors() == true) {
12117            throw new IllegalArgumentException("File descriptors passed in Intent");
12118        }
12119
12120        synchronized(this) {
12121            if (!(token instanceof ServiceRecord)) {
12122                throw new IllegalArgumentException("Invalid service token");
12123            }
12124            ServiceRecord r = (ServiceRecord)token;
12125
12126            final long origId = Binder.clearCallingIdentity();
12127
12128            if (r != null) {
12129                Intent.FilterComparison filter
12130                        = new Intent.FilterComparison(intent);
12131                IntentBindRecord b = r.bindings.get(filter);
12132                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
12133                        + " at " + b + ": apps="
12134                        + (b != null ? b.apps.size() : 0));
12135
12136                boolean inStopping = mStoppingServices.contains(r);
12137                if (b != null) {
12138                    if (b.apps.size() > 0 && !inStopping) {
12139                        // Applications have already bound since the last
12140                        // unbind, so just rebind right here.
12141                        requestServiceBindingLocked(r, b, true);
12142                    } else {
12143                        // Note to tell the service the next time there is
12144                        // a new client.
12145                        b.doRebind = true;
12146                    }
12147                }
12148
12149                serviceDoneExecutingLocked(r, inStopping);
12150
12151                Binder.restoreCallingIdentity(origId);
12152            }
12153        }
12154    }
12155
12156    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12157        synchronized(this) {
12158            if (!(token instanceof ServiceRecord)) {
12159                throw new IllegalArgumentException("Invalid service token");
12160            }
12161            ServiceRecord r = (ServiceRecord)token;
12162            boolean inStopping = mStoppingServices.contains(token);
12163            if (r != null) {
12164                if (r != token) {
12165                    Slog.w(TAG, "Done executing service " + r.name
12166                          + " with incorrect token: given " + token
12167                          + ", expected " + r);
12168                    return;
12169                }
12170
12171                if (type == 1) {
12172                    // This is a call from a service start...  take care of
12173                    // book-keeping.
12174                    r.callStart = true;
12175                    switch (res) {
12176                        case Service.START_STICKY_COMPATIBILITY:
12177                        case Service.START_STICKY: {
12178                            // We are done with the associated start arguments.
12179                            r.findDeliveredStart(startId, true);
12180                            // Don't stop if killed.
12181                            r.stopIfKilled = false;
12182                            break;
12183                        }
12184                        case Service.START_NOT_STICKY: {
12185                            // We are done with the associated start arguments.
12186                            r.findDeliveredStart(startId, true);
12187                            if (r.getLastStartId() == startId) {
12188                                // There is no more work, and this service
12189                                // doesn't want to hang around if killed.
12190                                r.stopIfKilled = true;
12191                            }
12192                            break;
12193                        }
12194                        case Service.START_REDELIVER_INTENT: {
12195                            // We'll keep this item until they explicitly
12196                            // call stop for it, but keep track of the fact
12197                            // that it was delivered.
12198                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12199                            if (si != null) {
12200                                si.deliveryCount = 0;
12201                                si.doneExecutingCount++;
12202                                // Don't stop if killed.
12203                                r.stopIfKilled = true;
12204                            }
12205                            break;
12206                        }
12207                        case Service.START_TASK_REMOVED_COMPLETE: {
12208                            // Special processing for onTaskRemoved().  Don't
12209                            // impact normal onStartCommand() processing.
12210                            r.findDeliveredStart(startId, true);
12211                            break;
12212                        }
12213                        default:
12214                            throw new IllegalArgumentException(
12215                                    "Unknown service start result: " + res);
12216                    }
12217                    if (res == Service.START_STICKY_COMPATIBILITY) {
12218                        r.callStart = false;
12219                    }
12220                }
12221                if (DEBUG_MU)
12222                    Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12223                            + Binder.getOrigCallingUid());
12224                final long origId = Binder.clearCallingIdentity();
12225                serviceDoneExecutingLocked(r, inStopping);
12226                Binder.restoreCallingIdentity(origId);
12227            } else {
12228                Slog.w(TAG, "Done executing unknown service from pid "
12229                        + Binder.getCallingPid());
12230            }
12231        }
12232    }
12233
12234    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
12235        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12236                + ": nesting=" + r.executeNesting
12237                + ", inStopping=" + inStopping + ", app=" + r.app);
12238        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
12239        r.executeNesting--;
12240        if (r.executeNesting <= 0 && r.app != null) {
12241            if (DEBUG_SERVICE) Slog.v(TAG,
12242                    "Nesting at 0 of " + r.shortName);
12243            r.app.executingServices.remove(r);
12244            if (r.app.executingServices.size() == 0) {
12245                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12246                        "No more executingServices of " + r.shortName);
12247                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12248            }
12249            if (inStopping) {
12250                if (DEBUG_SERVICE) Slog.v(TAG,
12251                        "doneExecuting remove stopping " + r);
12252                mStoppingServices.remove(r);
12253                r.bindings.clear();
12254            }
12255            updateOomAdjLocked(r.app);
12256        }
12257    }
12258
12259    void serviceTimeout(ProcessRecord proc) {
12260        String anrMessage = null;
12261
12262        synchronized(this) {
12263            if (proc.executingServices.size() == 0 || proc.thread == null) {
12264                return;
12265            }
12266            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12267            Iterator<ServiceRecord> it = proc.executingServices.iterator();
12268            ServiceRecord timeout = null;
12269            long nextTime = 0;
12270            while (it.hasNext()) {
12271                ServiceRecord sr = it.next();
12272                if (sr.executingStart < maxTime) {
12273                    timeout = sr;
12274                    break;
12275                }
12276                if (sr.executingStart > nextTime) {
12277                    nextTime = sr.executingStart;
12278                }
12279            }
12280            if (timeout != null && mLruProcesses.contains(proc)) {
12281                Slog.w(TAG, "Timeout executing service: " + timeout);
12282                anrMessage = "Executing service " + timeout.shortName;
12283            } else {
12284                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12285                msg.obj = proc;
12286                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12287            }
12288        }
12289
12290        if (anrMessage != null) {
12291            appNotResponding(proc, null, null, anrMessage);
12292        }
12293    }
12294
12295    // =========================================================
12296    // BACKUP AND RESTORE
12297    // =========================================================
12298
12299    // Cause the target app to be launched if necessary and its backup agent
12300    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12301    // activity manager to announce its creation.
12302    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12303        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
12304        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12305
12306        synchronized(this) {
12307            // !!! TODO: currently no check here that we're already bound
12308            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12309            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12310            synchronized (stats) {
12311                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12312            }
12313
12314            // Backup agent is now in use, its package can't be stopped.
12315            try {
12316                AppGlobals.getPackageManager().setPackageStoppedState(
12317                        app.packageName, false, UserId.getUserId(app.uid));
12318            } catch (RemoteException e) {
12319            } catch (IllegalArgumentException e) {
12320                Slog.w(TAG, "Failed trying to unstop package "
12321                        + app.packageName + ": " + e);
12322            }
12323
12324            BackupRecord r = new BackupRecord(ss, app, backupMode);
12325            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12326                    ? new ComponentName(app.packageName, app.backupAgentName)
12327                    : new ComponentName("android", "FullBackupAgent");
12328            // startProcessLocked() returns existing proc's record if it's already running
12329            ProcessRecord proc = startProcessLocked(app.processName, app,
12330                    false, 0, "backup", hostingName, false, false);
12331            if (proc == null) {
12332                Slog.e(TAG, "Unable to start backup agent process " + r);
12333                return false;
12334            }
12335
12336            r.app = proc;
12337            mBackupTarget = r;
12338            mBackupAppName = app.packageName;
12339
12340            // Try not to kill the process during backup
12341            updateOomAdjLocked(proc);
12342
12343            // If the process is already attached, schedule the creation of the backup agent now.
12344            // If it is not yet live, this will be done when it attaches to the framework.
12345            if (proc.thread != null) {
12346                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12347                try {
12348                    proc.thread.scheduleCreateBackupAgent(app,
12349                            compatibilityInfoForPackageLocked(app), backupMode);
12350                } catch (RemoteException e) {
12351                    // Will time out on the backup manager side
12352                }
12353            } else {
12354                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12355            }
12356            // Invariants: at this point, the target app process exists and the application
12357            // is either already running or in the process of coming up.  mBackupTarget and
12358            // mBackupAppName describe the app, so that when it binds back to the AM we
12359            // know that it's scheduled for a backup-agent operation.
12360        }
12361
12362        return true;
12363    }
12364
12365    // A backup agent has just come up
12366    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12367        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12368                + " = " + agent);
12369
12370        synchronized(this) {
12371            if (!agentPackageName.equals(mBackupAppName)) {
12372                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12373                return;
12374            }
12375        }
12376
12377        long oldIdent = Binder.clearCallingIdentity();
12378        try {
12379            IBackupManager bm = IBackupManager.Stub.asInterface(
12380                    ServiceManager.getService(Context.BACKUP_SERVICE));
12381            bm.agentConnected(agentPackageName, agent);
12382        } catch (RemoteException e) {
12383            // can't happen; the backup manager service is local
12384        } catch (Exception e) {
12385            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12386            e.printStackTrace();
12387        } finally {
12388            Binder.restoreCallingIdentity(oldIdent);
12389        }
12390    }
12391
12392    // done with this agent
12393    public void unbindBackupAgent(ApplicationInfo appInfo) {
12394        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12395        if (appInfo == null) {
12396            Slog.w(TAG, "unbind backup agent for null app");
12397            return;
12398        }
12399
12400        synchronized(this) {
12401            if (mBackupAppName == null) {
12402                Slog.w(TAG, "Unbinding backup agent with no active backup");
12403                return;
12404            }
12405
12406            if (!mBackupAppName.equals(appInfo.packageName)) {
12407                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12408                return;
12409            }
12410
12411            ProcessRecord proc = mBackupTarget.app;
12412            mBackupTarget = null;
12413            mBackupAppName = null;
12414
12415            // Not backing this app up any more; reset its OOM adjustment
12416            updateOomAdjLocked(proc);
12417
12418            // If the app crashed during backup, 'thread' will be null here
12419            if (proc.thread != null) {
12420                try {
12421                    proc.thread.scheduleDestroyBackupAgent(appInfo,
12422                            compatibilityInfoForPackageLocked(appInfo));
12423                } catch (Exception e) {
12424                    Slog.e(TAG, "Exception when unbinding backup agent:");
12425                    e.printStackTrace();
12426                }
12427            }
12428        }
12429    }
12430    // =========================================================
12431    // BROADCASTS
12432    // =========================================================
12433
12434    private final List getStickiesLocked(String action, IntentFilter filter,
12435            List cur) {
12436        final ContentResolver resolver = mContext.getContentResolver();
12437        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12438        if (list == null) {
12439            return cur;
12440        }
12441        int N = list.size();
12442        for (int i=0; i<N; i++) {
12443            Intent intent = list.get(i);
12444            if (filter.match(resolver, intent, true, TAG) >= 0) {
12445                if (cur == null) {
12446                    cur = new ArrayList<Intent>();
12447                }
12448                cur.add(intent);
12449            }
12450        }
12451        return cur;
12452    }
12453
12454    boolean isPendingBroadcastProcessLocked(int pid) {
12455        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12456                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12457    }
12458
12459    void skipPendingBroadcastLocked(int pid) {
12460            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12461            for (BroadcastQueue queue : mBroadcastQueues) {
12462                queue.skipPendingBroadcastLocked(pid);
12463            }
12464    }
12465
12466    // The app just attached; send any pending broadcasts that it should receive
12467    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12468        boolean didSomething = false;
12469        for (BroadcastQueue queue : mBroadcastQueues) {
12470            didSomething |= queue.sendPendingBroadcastsLocked(app);
12471        }
12472        return didSomething;
12473    }
12474
12475    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12476            IIntentReceiver receiver, IntentFilter filter, String permission) {
12477        enforceNotIsolatedCaller("registerReceiver");
12478        synchronized(this) {
12479            ProcessRecord callerApp = null;
12480            if (caller != null) {
12481                callerApp = getRecordForAppLocked(caller);
12482                if (callerApp == null) {
12483                    throw new SecurityException(
12484                            "Unable to find app for caller " + caller
12485                            + " (pid=" + Binder.getCallingPid()
12486                            + ") when registering receiver " + receiver);
12487                }
12488                if (callerApp.info.uid != Process.SYSTEM_UID &&
12489                        !callerApp.pkgList.contains(callerPackage)) {
12490                    throw new SecurityException("Given caller package " + callerPackage
12491                            + " is not running in process " + callerApp);
12492                }
12493            } else {
12494                callerPackage = null;
12495            }
12496
12497            List allSticky = null;
12498
12499            // Look for any matching sticky broadcasts...
12500            Iterator actions = filter.actionsIterator();
12501            if (actions != null) {
12502                while (actions.hasNext()) {
12503                    String action = (String)actions.next();
12504                    allSticky = getStickiesLocked(action, filter, allSticky);
12505                }
12506            } else {
12507                allSticky = getStickiesLocked(null, filter, allSticky);
12508            }
12509
12510            // The first sticky in the list is returned directly back to
12511            // the client.
12512            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12513
12514            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12515                    + ": " + sticky);
12516
12517            if (receiver == null) {
12518                return sticky;
12519            }
12520
12521            ReceiverList rl
12522                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12523            if (rl == null) {
12524                rl = new ReceiverList(this, callerApp,
12525                        Binder.getCallingPid(),
12526                        Binder.getCallingUid(), receiver);
12527                if (rl.app != null) {
12528                    rl.app.receivers.add(rl);
12529                } else {
12530                    try {
12531                        receiver.asBinder().linkToDeath(rl, 0);
12532                    } catch (RemoteException e) {
12533                        return sticky;
12534                    }
12535                    rl.linkedToDeath = true;
12536                }
12537                mRegisteredReceivers.put(receiver.asBinder(), rl);
12538            }
12539            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
12540            rl.add(bf);
12541            if (!bf.debugCheck()) {
12542                Slog.w(TAG, "==> For Dynamic broadast");
12543            }
12544            mReceiverResolver.addFilter(bf);
12545
12546            // Enqueue broadcasts for all existing stickies that match
12547            // this filter.
12548            if (allSticky != null) {
12549                ArrayList receivers = new ArrayList();
12550                receivers.add(bf);
12551
12552                int N = allSticky.size();
12553                for (int i=0; i<N; i++) {
12554                    Intent intent = (Intent)allSticky.get(i);
12555                    BroadcastQueue queue = broadcastQueueForIntent(intent);
12556                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
12557                            null, -1, -1, null, receivers, null, 0, null, null,
12558                            false, true, true);
12559                    queue.enqueueParallelBroadcastLocked(r);
12560                    queue.scheduleBroadcastsLocked();
12561                }
12562            }
12563
12564            return sticky;
12565        }
12566    }
12567
12568    public void unregisterReceiver(IIntentReceiver receiver) {
12569        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
12570
12571        final long origId = Binder.clearCallingIdentity();
12572        try {
12573            boolean doTrim = false;
12574
12575            synchronized(this) {
12576                ReceiverList rl
12577                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12578                if (rl != null) {
12579                    if (rl.curBroadcast != null) {
12580                        BroadcastRecord r = rl.curBroadcast;
12581                        final boolean doNext = finishReceiverLocked(
12582                                receiver.asBinder(), r.resultCode, r.resultData,
12583                                r.resultExtras, r.resultAbort, true);
12584                        if (doNext) {
12585                            doTrim = true;
12586                            r.queue.processNextBroadcast(false);
12587                        }
12588                    }
12589
12590                    if (rl.app != null) {
12591                        rl.app.receivers.remove(rl);
12592                    }
12593                    removeReceiverLocked(rl);
12594                    if (rl.linkedToDeath) {
12595                        rl.linkedToDeath = false;
12596                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
12597                    }
12598                }
12599            }
12600
12601            // If we actually concluded any broadcasts, we might now be able
12602            // to trim the recipients' apps from our working set
12603            if (doTrim) {
12604                trimApplications();
12605                return;
12606            }
12607
12608        } finally {
12609            Binder.restoreCallingIdentity(origId);
12610        }
12611    }
12612
12613    void removeReceiverLocked(ReceiverList rl) {
12614        mRegisteredReceivers.remove(rl.receiver.asBinder());
12615        int N = rl.size();
12616        for (int i=0; i<N; i++) {
12617            mReceiverResolver.removeFilter(rl.get(i));
12618        }
12619    }
12620
12621    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12622        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12623            ProcessRecord r = mLruProcesses.get(i);
12624            if (r.thread != null) {
12625                try {
12626                    r.thread.dispatchPackageBroadcast(cmd, packages);
12627                } catch (RemoteException ex) {
12628                }
12629            }
12630        }
12631    }
12632
12633    private final int broadcastIntentLocked(ProcessRecord callerApp,
12634            String callerPackage, Intent intent, String resolvedType,
12635            IIntentReceiver resultTo, int resultCode, String resultData,
12636            Bundle map, String requiredPermission,
12637            boolean ordered, boolean sticky, int callingPid, int callingUid,
12638            int userId) {
12639        intent = new Intent(intent);
12640
12641        // By default broadcasts do not go to stopped apps.
12642        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12643
12644        if (DEBUG_BROADCAST_LIGHT) Slog.v(
12645            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12646            + " ordered=" + ordered + " userid=" + userId);
12647        if ((resultTo != null) && !ordered) {
12648            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
12649        }
12650
12651        // Handle special intents: if this broadcast is from the package
12652        // manager about a package being removed, we need to remove all of
12653        // its activities from the history stack.
12654        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
12655                intent.getAction());
12656        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12657                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
12658                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
12659                || uidRemoved) {
12660            if (checkComponentPermission(
12661                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
12662                    callingPid, callingUid, -1, true)
12663                    == PackageManager.PERMISSION_GRANTED) {
12664                if (uidRemoved) {
12665                    final Bundle intentExtras = intent.getExtras();
12666                    final int uid = intentExtras != null
12667                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12668                    if (uid >= 0) {
12669                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12670                        synchronized (bs) {
12671                            bs.removeUidStatsLocked(uid);
12672                        }
12673                    }
12674                } else {
12675                    // If resources are unvailble just force stop all
12676                    // those packages and flush the attribute cache as well.
12677                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
12678                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12679                        if (list != null && (list.length > 0)) {
12680                            for (String pkg : list) {
12681                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
12682                            }
12683                            sendPackageBroadcastLocked(
12684                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
12685                        }
12686                    } else {
12687                        Uri data = intent.getData();
12688                        String ssp;
12689                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12690                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12691                                forceStopPackageLocked(ssp,
12692                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
12693                                        false, userId);
12694                            }
12695                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
12696                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12697                                        new String[] {ssp});
12698                            }
12699                        }
12700                    }
12701                }
12702            } else {
12703                String msg = "Permission Denial: " + intent.getAction()
12704                        + " broadcast from " + callerPackage + " (pid=" + callingPid
12705                        + ", uid=" + callingUid + ")"
12706                        + " requires "
12707                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
12708                Slog.w(TAG, msg);
12709                throw new SecurityException(msg);
12710            }
12711
12712        // Special case for adding a package: by default turn on compatibility
12713        // mode.
12714        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12715            Uri data = intent.getData();
12716            String ssp;
12717            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12718                mCompatModePackages.handlePackageAddedLocked(ssp,
12719                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
12720            }
12721        }
12722
12723        /*
12724         * If this is the time zone changed action, queue up a message that will reset the timezone
12725         * of all currently running processes. This message will get queued up before the broadcast
12726         * happens.
12727         */
12728        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12729            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12730        }
12731
12732        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12733            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12734        }
12735
12736        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12737            ProxyProperties proxy = intent.getParcelableExtra("proxy");
12738            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12739        }
12740
12741        /*
12742         * Prevent non-system code (defined here to be non-persistent
12743         * processes) from sending protected broadcasts.
12744         */
12745        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12746                || callingUid == Process.SHELL_UID || callingUid == 0) {
12747            // Always okay.
12748        } else if (callerApp == null || !callerApp.persistent) {
12749            try {
12750                if (AppGlobals.getPackageManager().isProtectedBroadcast(
12751                        intent.getAction())) {
12752                    String msg = "Permission Denial: not allowed to send broadcast "
12753                            + intent.getAction() + " from pid="
12754                            + callingPid + ", uid=" + callingUid;
12755                    Slog.w(TAG, msg);
12756                    throw new SecurityException(msg);
12757                }
12758            } catch (RemoteException e) {
12759                Slog.w(TAG, "Remote exception", e);
12760                return ActivityManager.BROADCAST_SUCCESS;
12761            }
12762        }
12763
12764        // Add to the sticky list if requested.
12765        if (sticky) {
12766            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12767                    callingPid, callingUid)
12768                    != PackageManager.PERMISSION_GRANTED) {
12769                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12770                        + callingPid + ", uid=" + callingUid
12771                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12772                Slog.w(TAG, msg);
12773                throw new SecurityException(msg);
12774            }
12775            if (requiredPermission != null) {
12776                Slog.w(TAG, "Can't broadcast sticky intent " + intent
12777                        + " and enforce permission " + requiredPermission);
12778                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12779            }
12780            if (intent.getComponent() != null) {
12781                throw new SecurityException(
12782                        "Sticky broadcasts can't target a specific component");
12783            }
12784            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12785            if (list == null) {
12786                list = new ArrayList<Intent>();
12787                mStickyBroadcasts.put(intent.getAction(), list);
12788            }
12789            int N = list.size();
12790            int i;
12791            for (i=0; i<N; i++) {
12792                if (intent.filterEquals(list.get(i))) {
12793                    // This sticky already exists, replace it.
12794                    list.set(i, new Intent(intent));
12795                    break;
12796                }
12797            }
12798            if (i >= N) {
12799                list.add(new Intent(intent));
12800            }
12801        }
12802
12803        // Figure out who all will receive this broadcast.
12804        List receivers = null;
12805        List<BroadcastFilter> registeredReceivers = null;
12806        try {
12807            if (intent.getComponent() != null) {
12808                // Broadcast is going to one specific receiver class...
12809                ActivityInfo ai = AppGlobals.getPackageManager().
12810                        getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId);
12811                if (ai != null) {
12812                    receivers = new ArrayList();
12813                    ResolveInfo ri = new ResolveInfo();
12814                    if (isSingleton(ai.processName, ai.applicationInfo)) {
12815                        ri.activityInfo = getActivityInfoForUser(ai, 0);
12816                    } else {
12817                        ri.activityInfo = getActivityInfoForUser(ai, userId);
12818                    }
12819                    receivers.add(ri);
12820                }
12821            } else {
12822                // Need to resolve the intent to interested receivers...
12823                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12824                         == 0) {
12825                    receivers =
12826                        AppGlobals.getPackageManager().queryIntentReceivers(
12827                                    intent, resolvedType, STOCK_PM_FLAGS, userId);
12828                }
12829                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false,
12830                        userId);
12831            }
12832        } catch (RemoteException ex) {
12833            // pm is in same process, this will never happen.
12834        }
12835
12836        final boolean replacePending =
12837                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12838
12839        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
12840                + " replacePending=" + replacePending);
12841
12842        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12843        if (!ordered && NR > 0) {
12844            // If we are not serializing this broadcast, then send the
12845            // registered receivers separately so they don't wait for the
12846            // components to be launched.
12847            final BroadcastQueue queue = broadcastQueueForIntent(intent);
12848            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
12849                    callerPackage, callingPid, callingUid, requiredPermission,
12850                    registeredReceivers, resultTo, resultCode, resultData, map,
12851                    ordered, sticky, false);
12852            if (DEBUG_BROADCAST) Slog.v(
12853                    TAG, "Enqueueing parallel broadcast " + r);
12854            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
12855            if (!replaced) {
12856                queue.enqueueParallelBroadcastLocked(r);
12857                queue.scheduleBroadcastsLocked();
12858            }
12859            registeredReceivers = null;
12860            NR = 0;
12861        }
12862
12863        // Merge into one list.
12864        int ir = 0;
12865        if (receivers != null) {
12866            // A special case for PACKAGE_ADDED: do not allow the package
12867            // being added to see this broadcast.  This prevents them from
12868            // using this as a back door to get run as soon as they are
12869            // installed.  Maybe in the future we want to have a special install
12870            // broadcast or such for apps, but we'd like to deliberately make
12871            // this decision.
12872            String skipPackages[] = null;
12873            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12874                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12875                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
12876                Uri data = intent.getData();
12877                if (data != null) {
12878                    String pkgName = data.getSchemeSpecificPart();
12879                    if (pkgName != null) {
12880                        skipPackages = new String[] { pkgName };
12881                    }
12882                }
12883            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
12884                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12885            }
12886            if (skipPackages != null && (skipPackages.length > 0)) {
12887                for (String skipPackage : skipPackages) {
12888                    if (skipPackage != null) {
12889                        int NT = receivers.size();
12890                        for (int it=0; it<NT; it++) {
12891                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
12892                            if (curt.activityInfo.packageName.equals(skipPackage)) {
12893                                receivers.remove(it);
12894                                it--;
12895                                NT--;
12896                            }
12897                        }
12898                    }
12899                }
12900            }
12901
12902            int NT = receivers != null ? receivers.size() : 0;
12903            int it = 0;
12904            ResolveInfo curt = null;
12905            BroadcastFilter curr = null;
12906            while (it < NT && ir < NR) {
12907                if (curt == null) {
12908                    curt = (ResolveInfo)receivers.get(it);
12909                }
12910                if (curr == null) {
12911                    curr = registeredReceivers.get(ir);
12912                }
12913                if (curr.getPriority() >= curt.priority) {
12914                    // Insert this broadcast record into the final list.
12915                    receivers.add(it, curr);
12916                    ir++;
12917                    curr = null;
12918                    it++;
12919                    NT++;
12920                } else {
12921                    // Skip to the next ResolveInfo in the final list.
12922                    it++;
12923                    curt = null;
12924                }
12925            }
12926        }
12927        while (ir < NR) {
12928            if (receivers == null) {
12929                receivers = new ArrayList();
12930            }
12931            receivers.add(registeredReceivers.get(ir));
12932            ir++;
12933        }
12934
12935        if ((receivers != null && receivers.size() > 0)
12936                || resultTo != null) {
12937            BroadcastQueue queue = broadcastQueueForIntent(intent);
12938            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
12939                    callerPackage, callingPid, callingUid, requiredPermission,
12940                    receivers, resultTo, resultCode, resultData, map, ordered,
12941                    sticky, false);
12942            if (DEBUG_BROADCAST) Slog.v(
12943                    TAG, "Enqueueing ordered broadcast " + r
12944                    + ": prev had " + queue.mOrderedBroadcasts.size());
12945            if (DEBUG_BROADCAST) {
12946                int seq = r.intent.getIntExtra("seq", -1);
12947                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
12948            }
12949            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
12950            if (!replaced) {
12951                queue.enqueueOrderedBroadcastLocked(r);
12952                queue.scheduleBroadcastsLocked();
12953            }
12954        }
12955
12956        return ActivityManager.BROADCAST_SUCCESS;
12957    }
12958
12959    final Intent verifyBroadcastLocked(Intent intent) {
12960        // Refuse possible leaked file descriptors
12961        if (intent != null && intent.hasFileDescriptors() == true) {
12962            throw new IllegalArgumentException("File descriptors passed in Intent");
12963        }
12964
12965        int flags = intent.getFlags();
12966
12967        if (!mProcessesReady) {
12968            // if the caller really truly claims to know what they're doing, go
12969            // ahead and allow the broadcast without launching any receivers
12970            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12971                intent = new Intent(intent);
12972                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12973            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12974                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12975                        + " before boot completion");
12976                throw new IllegalStateException("Cannot broadcast before boot completed");
12977            }
12978        }
12979
12980        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12981            throw new IllegalArgumentException(
12982                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12983        }
12984
12985        return intent;
12986    }
12987
12988    public final int broadcastIntent(IApplicationThread caller,
12989            Intent intent, String resolvedType, IIntentReceiver resultTo,
12990            int resultCode, String resultData, Bundle map,
12991            String requiredPermission, boolean serialized, boolean sticky, int userId) {
12992        enforceNotIsolatedCaller("broadcastIntent");
12993        synchronized(this) {
12994            intent = verifyBroadcastLocked(intent);
12995
12996            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12997            final int callingPid = Binder.getCallingPid();
12998            final int callingUid = Binder.getCallingUid();
12999            final long origId = Binder.clearCallingIdentity();
13000            int res = broadcastIntentLocked(callerApp,
13001                    callerApp != null ? callerApp.info.packageName : null,
13002                    intent, resolvedType, resultTo,
13003                    resultCode, resultData, map, requiredPermission, serialized, sticky,
13004                    callingPid, callingUid, userId);
13005            Binder.restoreCallingIdentity(origId);
13006            return res;
13007        }
13008    }
13009
13010    int broadcastIntentInPackage(String packageName, int uid,
13011            Intent intent, String resolvedType, IIntentReceiver resultTo,
13012            int resultCode, String resultData, Bundle map,
13013            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13014        synchronized(this) {
13015            intent = verifyBroadcastLocked(intent);
13016
13017            final long origId = Binder.clearCallingIdentity();
13018            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13019                    resultTo, resultCode, resultData, map, requiredPermission,
13020                    serialized, sticky, -1, uid, userId);
13021            Binder.restoreCallingIdentity(origId);
13022            return res;
13023        }
13024    }
13025
13026    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13027    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13028        // Refuse possible leaked file descriptors
13029        if (intent != null && intent.hasFileDescriptors() == true) {
13030            throw new IllegalArgumentException("File descriptors passed in Intent");
13031        }
13032
13033        synchronized(this) {
13034            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13035                    != PackageManager.PERMISSION_GRANTED) {
13036                String msg = "Permission Denial: unbroadcastIntent() from pid="
13037                        + Binder.getCallingPid()
13038                        + ", uid=" + Binder.getCallingUid()
13039                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13040                Slog.w(TAG, msg);
13041                throw new SecurityException(msg);
13042            }
13043            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13044            if (list != null) {
13045                int N = list.size();
13046                int i;
13047                for (i=0; i<N; i++) {
13048                    if (intent.filterEquals(list.get(i))) {
13049                        list.remove(i);
13050                        break;
13051                    }
13052                }
13053            }
13054        }
13055    }
13056
13057    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13058            String resultData, Bundle resultExtras, boolean resultAbort,
13059            boolean explicit) {
13060        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13061        if (r == null) {
13062            Slog.w(TAG, "finishReceiver called but not found on queue");
13063            return false;
13064        }
13065
13066        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13067                explicit);
13068    }
13069
13070    public void finishReceiver(IBinder who, int resultCode, String resultData,
13071            Bundle resultExtras, boolean resultAbort) {
13072        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13073
13074        // Refuse possible leaked file descriptors
13075        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13076            throw new IllegalArgumentException("File descriptors passed in Bundle");
13077        }
13078
13079        final long origId = Binder.clearCallingIdentity();
13080        try {
13081            boolean doNext = false;
13082            BroadcastRecord r = null;
13083
13084            synchronized(this) {
13085                r = broadcastRecordForReceiverLocked(who);
13086                if (r != null) {
13087                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13088                        resultData, resultExtras, resultAbort, true);
13089                }
13090            }
13091
13092            if (doNext) {
13093                r.queue.processNextBroadcast(false);
13094            }
13095            trimApplications();
13096        } finally {
13097            Binder.restoreCallingIdentity(origId);
13098        }
13099    }
13100
13101    // =========================================================
13102    // INSTRUMENTATION
13103    // =========================================================
13104
13105    public boolean startInstrumentation(ComponentName className,
13106            String profileFile, int flags, Bundle arguments,
13107            IInstrumentationWatcher watcher) {
13108        enforceNotIsolatedCaller("startInstrumentation");
13109        // Refuse possible leaked file descriptors
13110        if (arguments != null && arguments.hasFileDescriptors()) {
13111            throw new IllegalArgumentException("File descriptors passed in Bundle");
13112        }
13113
13114        synchronized(this) {
13115            InstrumentationInfo ii = null;
13116            ApplicationInfo ai = null;
13117            try {
13118                ii = mContext.getPackageManager().getInstrumentationInfo(
13119                    className, STOCK_PM_FLAGS);
13120                ai = mContext.getPackageManager().getApplicationInfo(
13121                        ii.targetPackage, STOCK_PM_FLAGS);
13122            } catch (PackageManager.NameNotFoundException e) {
13123            }
13124            if (ii == null) {
13125                reportStartInstrumentationFailure(watcher, className,
13126                        "Unable to find instrumentation info for: " + className);
13127                return false;
13128            }
13129            if (ai == null) {
13130                reportStartInstrumentationFailure(watcher, className,
13131                        "Unable to find instrumentation target package: " + ii.targetPackage);
13132                return false;
13133            }
13134
13135            int match = mContext.getPackageManager().checkSignatures(
13136                    ii.targetPackage, ii.packageName);
13137            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13138                String msg = "Permission Denial: starting instrumentation "
13139                        + className + " from pid="
13140                        + Binder.getCallingPid()
13141                        + ", uid=" + Binder.getCallingPid()
13142                        + " not allowed because package " + ii.packageName
13143                        + " does not have a signature matching the target "
13144                        + ii.targetPackage;
13145                reportStartInstrumentationFailure(watcher, className, msg);
13146                throw new SecurityException(msg);
13147            }
13148
13149            int userId = UserId.getCallingUserId();
13150            final long origId = Binder.clearCallingIdentity();
13151            // Instrumentation can kill and relaunch even persistent processes
13152            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
13153            ProcessRecord app = addAppLocked(ai, false);
13154            app.instrumentationClass = className;
13155            app.instrumentationInfo = ai;
13156            app.instrumentationProfileFile = profileFile;
13157            app.instrumentationArguments = arguments;
13158            app.instrumentationWatcher = watcher;
13159            app.instrumentationResultClass = className;
13160            Binder.restoreCallingIdentity(origId);
13161        }
13162
13163        return true;
13164    }
13165
13166    /**
13167     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13168     * error to the logs, but if somebody is watching, send the report there too.  This enables
13169     * the "am" command to report errors with more information.
13170     *
13171     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13172     * @param cn The component name of the instrumentation.
13173     * @param report The error report.
13174     */
13175    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13176            ComponentName cn, String report) {
13177        Slog.w(TAG, report);
13178        try {
13179            if (watcher != null) {
13180                Bundle results = new Bundle();
13181                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13182                results.putString("Error", report);
13183                watcher.instrumentationStatus(cn, -1, results);
13184            }
13185        } catch (RemoteException e) {
13186            Slog.w(TAG, e);
13187        }
13188    }
13189
13190    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13191        if (app.instrumentationWatcher != null) {
13192            try {
13193                // NOTE:  IInstrumentationWatcher *must* be oneway here
13194                app.instrumentationWatcher.instrumentationFinished(
13195                    app.instrumentationClass,
13196                    resultCode,
13197                    results);
13198            } catch (RemoteException e) {
13199            }
13200        }
13201        app.instrumentationWatcher = null;
13202        app.instrumentationClass = null;
13203        app.instrumentationInfo = null;
13204        app.instrumentationProfileFile = null;
13205        app.instrumentationArguments = null;
13206
13207        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
13208    }
13209
13210    public void finishInstrumentation(IApplicationThread target,
13211            int resultCode, Bundle results) {
13212        int userId = UserId.getCallingUserId();
13213        // Refuse possible leaked file descriptors
13214        if (results != null && results.hasFileDescriptors()) {
13215            throw new IllegalArgumentException("File descriptors passed in Intent");
13216        }
13217
13218        synchronized(this) {
13219            ProcessRecord app = getRecordForAppLocked(target);
13220            if (app == null) {
13221                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13222                return;
13223            }
13224            final long origId = Binder.clearCallingIdentity();
13225            finishInstrumentationLocked(app, resultCode, results);
13226            Binder.restoreCallingIdentity(origId);
13227        }
13228    }
13229
13230    // =========================================================
13231    // CONFIGURATION
13232    // =========================================================
13233
13234    public ConfigurationInfo getDeviceConfigurationInfo() {
13235        ConfigurationInfo config = new ConfigurationInfo();
13236        synchronized (this) {
13237            config.reqTouchScreen = mConfiguration.touchscreen;
13238            config.reqKeyboardType = mConfiguration.keyboard;
13239            config.reqNavigation = mConfiguration.navigation;
13240            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13241                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13242                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13243            }
13244            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13245                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13246                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13247            }
13248            config.reqGlEsVersion = GL_ES_VERSION;
13249        }
13250        return config;
13251    }
13252
13253    public Configuration getConfiguration() {
13254        Configuration ci;
13255        synchronized(this) {
13256            ci = new Configuration(mConfiguration);
13257        }
13258        return ci;
13259    }
13260
13261    public void updatePersistentConfiguration(Configuration values) {
13262        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13263                "updateConfiguration()");
13264        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13265                "updateConfiguration()");
13266        if (values == null) {
13267            throw new NullPointerException("Configuration must not be null");
13268        }
13269
13270        synchronized(this) {
13271            final long origId = Binder.clearCallingIdentity();
13272            updateConfigurationLocked(values, null, true, false);
13273            Binder.restoreCallingIdentity(origId);
13274        }
13275    }
13276
13277    public void updateConfiguration(Configuration values) {
13278        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13279                "updateConfiguration()");
13280
13281        synchronized(this) {
13282            if (values == null && mWindowManager != null) {
13283                // sentinel: fetch the current configuration from the window manager
13284                values = mWindowManager.computeNewConfiguration();
13285            }
13286
13287            if (mWindowManager != null) {
13288                mProcessList.applyDisplaySize(mWindowManager);
13289            }
13290
13291            final long origId = Binder.clearCallingIdentity();
13292            if (values != null) {
13293                Settings.System.clearConfiguration(values);
13294            }
13295            updateConfigurationLocked(values, null, false, false);
13296            Binder.restoreCallingIdentity(origId);
13297        }
13298    }
13299
13300    /**
13301     * Do either or both things: (1) change the current configuration, and (2)
13302     * make sure the given activity is running with the (now) current
13303     * configuration.  Returns true if the activity has been left running, or
13304     * false if <var>starting</var> is being destroyed to match the new
13305     * configuration.
13306     * @param persistent TODO
13307     */
13308    boolean updateConfigurationLocked(Configuration values,
13309            ActivityRecord starting, boolean persistent, boolean initLocale) {
13310        // do nothing if we are headless
13311        if (mHeadless) return true;
13312
13313        int changes = 0;
13314
13315        boolean kept = true;
13316
13317        if (values != null) {
13318            Configuration newConfig = new Configuration(mConfiguration);
13319            changes = newConfig.updateFrom(values);
13320            if (changes != 0) {
13321                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13322                    Slog.i(TAG, "Updating configuration to: " + values);
13323                }
13324
13325                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13326
13327                if (values.locale != null && !initLocale) {
13328                    saveLocaleLocked(values.locale,
13329                                     !values.locale.equals(mConfiguration.locale),
13330                                     values.userSetLocale);
13331                }
13332
13333                mConfigurationSeq++;
13334                if (mConfigurationSeq <= 0) {
13335                    mConfigurationSeq = 1;
13336                }
13337                newConfig.seq = mConfigurationSeq;
13338                mConfiguration = newConfig;
13339                Slog.i(TAG, "Config changed: " + newConfig);
13340
13341                final Configuration configCopy = new Configuration(mConfiguration);
13342
13343                // TODO: If our config changes, should we auto dismiss any currently
13344                // showing dialogs?
13345                mShowDialogs = shouldShowDialogs(newConfig);
13346
13347                AttributeCache ac = AttributeCache.instance();
13348                if (ac != null) {
13349                    ac.updateConfiguration(configCopy);
13350                }
13351
13352                // Make sure all resources in our process are updated
13353                // right now, so that anyone who is going to retrieve
13354                // resource values after we return will be sure to get
13355                // the new ones.  This is especially important during
13356                // boot, where the first config change needs to guarantee
13357                // all resources have that config before following boot
13358                // code is executed.
13359                mSystemThread.applyConfigurationToResources(configCopy);
13360
13361                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13362                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13363                    msg.obj = new Configuration(configCopy);
13364                    mHandler.sendMessage(msg);
13365                }
13366
13367                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13368                    ProcessRecord app = mLruProcesses.get(i);
13369                    try {
13370                        if (app.thread != null) {
13371                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13372                                    + app.processName + " new config " + mConfiguration);
13373                            app.thread.scheduleConfigurationChanged(configCopy);
13374                        }
13375                    } catch (Exception e) {
13376                    }
13377                }
13378                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13379                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13380                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13381                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13382                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13383                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13384                    broadcastIntentLocked(null, null,
13385                            new Intent(Intent.ACTION_LOCALE_CHANGED),
13386                            null, null, 0, null, null,
13387                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13388                }
13389            }
13390        }
13391
13392        if (changes != 0 && starting == null) {
13393            // If the configuration changed, and the caller is not already
13394            // in the process of starting an activity, then find the top
13395            // activity to check if its configuration needs to change.
13396            starting = mMainStack.topRunningActivityLocked(null);
13397        }
13398
13399        if (starting != null) {
13400            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
13401            // And we need to make sure at this point that all other activities
13402            // are made visible with the correct configuration.
13403            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
13404        }
13405
13406        if (values != null && mWindowManager != null) {
13407            mWindowManager.setNewConfiguration(mConfiguration);
13408        }
13409
13410        return kept;
13411    }
13412
13413    /**
13414     * Decide based on the configuration whether we should shouw the ANR,
13415     * crash, etc dialogs.  The idea is that if there is no affordnace to
13416     * press the on-screen buttons, we shouldn't show the dialog.
13417     *
13418     * A thought: SystemUI might also want to get told about this, the Power
13419     * dialog / global actions also might want different behaviors.
13420     */
13421    private static final boolean shouldShowDialogs(Configuration config) {
13422        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
13423                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
13424    }
13425
13426    /**
13427     * Save the locale.  You must be inside a synchronized (this) block.
13428     */
13429    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13430        if(isDiff) {
13431            SystemProperties.set("user.language", l.getLanguage());
13432            SystemProperties.set("user.region", l.getCountry());
13433        }
13434
13435        if(isPersist) {
13436            SystemProperties.set("persist.sys.language", l.getLanguage());
13437            SystemProperties.set("persist.sys.country", l.getCountry());
13438            SystemProperties.set("persist.sys.localevar", l.getVariant());
13439        }
13440    }
13441
13442    @Override
13443    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
13444        ActivityRecord srec = ActivityRecord.forToken(token);
13445        return srec != null && srec.task.affinity != null &&
13446                srec.task.affinity.equals(destAffinity);
13447    }
13448
13449    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
13450            Intent resultData) {
13451        ComponentName dest = destIntent.getComponent();
13452
13453        synchronized (this) {
13454            ActivityRecord srec = ActivityRecord.forToken(token);
13455            if (srec == null) {
13456                return false;
13457            }
13458            ArrayList<ActivityRecord> history = srec.stack.mHistory;
13459            final int start = history.indexOf(srec);
13460            if (start < 0) {
13461                // Current activity is not in history stack; do nothing.
13462                return false;
13463            }
13464            int finishTo = start - 1;
13465            ActivityRecord parent = null;
13466            boolean foundParentInTask = false;
13467            if (dest != null) {
13468                TaskRecord tr = srec.task;
13469                for (int i = start - 1; i >= 0; i--) {
13470                    ActivityRecord r = history.get(i);
13471                    if (tr != r.task) {
13472                        // Couldn't find parent in the same task; stop at the one above this.
13473                        // (Root of current task; in-app "home" behavior)
13474                        // Always at least finish the current activity.
13475                        finishTo = Math.min(start - 1, i + 1);
13476                        parent = history.get(finishTo);
13477                        break;
13478                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
13479                            r.info.name.equals(dest.getClassName())) {
13480                        finishTo = i;
13481                        parent = r;
13482                        foundParentInTask = true;
13483                        break;
13484                    }
13485                }
13486            }
13487
13488            if (mController != null) {
13489                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
13490                if (next != null) {
13491                    // ask watcher if this is allowed
13492                    boolean resumeOK = true;
13493                    try {
13494                        resumeOK = mController.activityResuming(next.packageName);
13495                    } catch (RemoteException e) {
13496                        mController = null;
13497                    }
13498
13499                    if (!resumeOK) {
13500                        return false;
13501                    }
13502                }
13503            }
13504            final long origId = Binder.clearCallingIdentity();
13505            for (int i = start; i > finishTo; i--) {
13506                ActivityRecord r = history.get(i);
13507                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
13508                        "navigate-up");
13509                // Only return the supplied result for the first activity finished
13510                resultCode = Activity.RESULT_CANCELED;
13511                resultData = null;
13512            }
13513
13514            if (parent != null && foundParentInTask) {
13515                final int parentLaunchMode = parent.info.launchMode;
13516                final int destIntentFlags = destIntent.getFlags();
13517                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
13518                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
13519                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
13520                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
13521                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
13522                } else {
13523                    try {
13524                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
13525                                destIntent.getComponent(), 0, UserId.getCallingUserId());
13526                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
13527                                null, aInfo, parent.appToken, null,
13528                                0, -1, parent.launchedFromUid, 0, null, true, null);
13529                        foundParentInTask = res == ActivityManager.START_SUCCESS;
13530                    } catch (RemoteException e) {
13531                        foundParentInTask = false;
13532                    }
13533                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
13534                            resultData, "navigate-up");
13535                }
13536            }
13537            Binder.restoreCallingIdentity(origId);
13538            return foundParentInTask;
13539        }
13540    }
13541
13542    // =========================================================
13543    // LIFETIME MANAGEMENT
13544    // =========================================================
13545
13546    // Returns which broadcast queue the app is the current [or imminent] receiver
13547    // on, or 'null' if the app is not an active broadcast recipient.
13548    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
13549        BroadcastRecord r = app.curReceiver;
13550        if (r != null) {
13551            return r.queue;
13552        }
13553
13554        // It's not the current receiver, but it might be starting up to become one
13555        synchronized (this) {
13556            for (BroadcastQueue queue : mBroadcastQueues) {
13557                r = queue.mPendingBroadcast;
13558                if (r != null && r.curApp == app) {
13559                    // found it; report which queue it's in
13560                    return queue;
13561                }
13562            }
13563        }
13564
13565        return null;
13566    }
13567
13568    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
13569            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
13570        if (mAdjSeq == app.adjSeq) {
13571            // This adjustment has already been computed.  If we are calling
13572            // from the top, we may have already computed our adjustment with
13573            // an earlier hidden adjustment that isn't really for us... if
13574            // so, use the new hidden adjustment.
13575            if (!recursed && app.hidden) {
13576                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
13577            }
13578            return app.curRawAdj;
13579        }
13580
13581        if (app.thread == null) {
13582            app.adjSeq = mAdjSeq;
13583            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13584            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
13585        }
13586
13587        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13588        app.adjSource = null;
13589        app.adjTarget = null;
13590        app.empty = false;
13591        app.hidden = false;
13592
13593        final int activitiesSize = app.activities.size();
13594
13595        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13596            // The max adjustment doesn't allow this app to be anything
13597            // below foreground, so it is not worth doing work for it.
13598            app.adjType = "fixed";
13599            app.adjSeq = mAdjSeq;
13600            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
13601            app.foregroundActivities = false;
13602            app.keeping = true;
13603            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13604            // System process can do UI, and when they do we want to have
13605            // them trim their memory after the user leaves the UI.  To
13606            // facilitate this, here we need to determine whether or not it
13607            // is currently showing UI.
13608            app.systemNoUi = true;
13609            if (app == TOP_APP) {
13610                app.systemNoUi = false;
13611            } else if (activitiesSize > 0) {
13612                for (int j = 0; j < activitiesSize; j++) {
13613                    final ActivityRecord r = app.activities.get(j);
13614                    if (r.visible) {
13615                        app.systemNoUi = false;
13616                        break;
13617                    }
13618                }
13619            }
13620            return (app.curAdj=app.maxAdj);
13621        }
13622
13623        final boolean hadForegroundActivities = app.foregroundActivities;
13624
13625        app.foregroundActivities = false;
13626        app.keeping = false;
13627        app.systemNoUi = false;
13628
13629        // Determine the importance of the process, starting with most
13630        // important to least, and assign an appropriate OOM adjustment.
13631        int adj;
13632        int schedGroup;
13633        BroadcastQueue queue;
13634        if (app == TOP_APP) {
13635            // The last app on the list is the foreground app.
13636            adj = ProcessList.FOREGROUND_APP_ADJ;
13637            schedGroup = Process.THREAD_GROUP_DEFAULT;
13638            app.adjType = "top-activity";
13639            app.foregroundActivities = true;
13640        } else if (app.instrumentationClass != null) {
13641            // Don't want to kill running instrumentation.
13642            adj = ProcessList.FOREGROUND_APP_ADJ;
13643            schedGroup = Process.THREAD_GROUP_DEFAULT;
13644            app.adjType = "instrumentation";
13645        } else if ((queue = isReceivingBroadcast(app)) != null) {
13646            // An app that is currently receiving a broadcast also
13647            // counts as being in the foreground for OOM killer purposes.
13648            // It's placed in a sched group based on the nature of the
13649            // broadcast as reflected by which queue it's active in.
13650            adj = ProcessList.FOREGROUND_APP_ADJ;
13651            schedGroup = (queue == mFgBroadcastQueue)
13652                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
13653            app.adjType = "broadcast";
13654        } else if (app.executingServices.size() > 0) {
13655            // An app that is currently executing a service callback also
13656            // counts as being in the foreground.
13657            adj = ProcessList.FOREGROUND_APP_ADJ;
13658            schedGroup = Process.THREAD_GROUP_DEFAULT;
13659            app.adjType = "exec-service";
13660        } else if (activitiesSize > 0) {
13661            // This app is in the background with paused activities.
13662            // We inspect activities to potentially upgrade adjustment further below.
13663            adj = hiddenAdj;
13664            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13665            app.hidden = true;
13666            app.adjType = "bg-activities";
13667        } else {
13668            // A very not-needed process.  If this is lower in the lru list,
13669            // we will push it in to the empty bucket.
13670            adj = hiddenAdj;
13671            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13672            app.hidden = true;
13673            app.empty = true;
13674            app.adjType = "bg-empty";
13675        }
13676
13677        boolean hasStoppingActivities = false;
13678
13679        // Examine all activities if not already foreground.
13680        if (!app.foregroundActivities && activitiesSize > 0) {
13681            for (int j = 0; j < activitiesSize; j++) {
13682                final ActivityRecord r = app.activities.get(j);
13683                if (r.visible) {
13684                    // App has a visible activity; only upgrade adjustment.
13685                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
13686                        adj = ProcessList.VISIBLE_APP_ADJ;
13687                        app.adjType = "visible";
13688                    }
13689                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13690                    app.hidden = false;
13691                    app.foregroundActivities = true;
13692                    break;
13693                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
13694                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13695                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13696                        app.adjType = "pausing";
13697                    }
13698                    app.hidden = false;
13699                    app.foregroundActivities = true;
13700                } else if (r.state == ActivityState.STOPPING) {
13701                    // We will apply the actual adjustment later, because
13702                    // we want to allow this process to immediately go through
13703                    // any memory trimming that is in effect.
13704                    app.hidden = false;
13705                    app.foregroundActivities = true;
13706                    hasStoppingActivities = true;
13707                }
13708            }
13709        }
13710
13711        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13712            if (app.foregroundServices) {
13713                // The user is aware of this app, so make it visible.
13714                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13715                app.hidden = false;
13716                app.adjType = "foreground-service";
13717                schedGroup = Process.THREAD_GROUP_DEFAULT;
13718            } else if (app.forcingToForeground != null) {
13719                // The user is aware of this app, so make it visible.
13720                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13721                app.hidden = false;
13722                app.adjType = "force-foreground";
13723                app.adjSource = app.forcingToForeground;
13724                schedGroup = Process.THREAD_GROUP_DEFAULT;
13725            }
13726        }
13727
13728        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
13729            // We don't want to kill the current heavy-weight process.
13730            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
13731            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13732            app.hidden = false;
13733            app.adjType = "heavy";
13734        }
13735
13736        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
13737            // This process is hosting what we currently consider to be the
13738            // home app, so we don't want to let it go into the background.
13739            adj = ProcessList.HOME_APP_ADJ;
13740            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13741            app.hidden = false;
13742            app.adjType = "home";
13743        }
13744
13745        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13746                && app.activities.size() > 0) {
13747            // This was the previous process that showed UI to the user.
13748            // We want to try to keep it around more aggressively, to give
13749            // a good experience around switching between two apps.
13750            adj = ProcessList.PREVIOUS_APP_ADJ;
13751            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13752            app.hidden = false;
13753            app.adjType = "previous";
13754        }
13755
13756        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13757                + " reason=" + app.adjType);
13758
13759        // By default, we use the computed adjustment.  It may be changed if
13760        // there are applications dependent on our services or providers, but
13761        // this gives us a baseline and makes sure we don't get into an
13762        // infinite recursion.
13763        app.adjSeq = mAdjSeq;
13764        app.curRawAdj = app.nonStoppingAdj = adj;
13765
13766        if (mBackupTarget != null && app == mBackupTarget.app) {
13767            // If possible we want to avoid killing apps while they're being backed up
13768            if (adj > ProcessList.BACKUP_APP_ADJ) {
13769                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13770                adj = ProcessList.BACKUP_APP_ADJ;
13771                app.adjType = "backup";
13772                app.hidden = false;
13773            }
13774        }
13775
13776        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13777                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13778            final long now = SystemClock.uptimeMillis();
13779            // This process is more important if the top activity is
13780            // bound to the service.
13781            Iterator<ServiceRecord> jt = app.services.iterator();
13782            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13783                ServiceRecord s = jt.next();
13784                if (s.startRequested) {
13785                    if (app.hasShownUi && app != mHomeProcess) {
13786                        // If this process has shown some UI, let it immediately
13787                        // go to the LRU list because it may be pretty heavy with
13788                        // UI stuff.  We'll tag it with a label just to help
13789                        // debug and understand what is going on.
13790                        if (adj > ProcessList.SERVICE_ADJ) {
13791                            app.adjType = "started-bg-ui-services";
13792                        }
13793                    } else {
13794                        if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13795                            // This service has seen some activity within
13796                            // recent memory, so we will keep its process ahead
13797                            // of the background processes.
13798                            if (adj > ProcessList.SERVICE_ADJ) {
13799                                adj = ProcessList.SERVICE_ADJ;
13800                                app.adjType = "started-services";
13801                                app.hidden = false;
13802                            }
13803                        }
13804                        // If we have let the service slide into the background
13805                        // state, still have some text describing what it is doing
13806                        // even though the service no longer has an impact.
13807                        if (adj > ProcessList.SERVICE_ADJ) {
13808                            app.adjType = "started-bg-services";
13809                        }
13810                    }
13811                    // Don't kill this process because it is doing work; it
13812                    // has said it is doing work.
13813                    app.keeping = true;
13814                }
13815                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13816                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13817                    Iterator<ArrayList<ConnectionRecord>> kt
13818                            = s.connections.values().iterator();
13819                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13820                        ArrayList<ConnectionRecord> clist = kt.next();
13821                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
13822                            // XXX should compute this based on the max of
13823                            // all connected clients.
13824                            ConnectionRecord cr = clist.get(i);
13825                            if (cr.binding.client == app) {
13826                                // Binding to ourself is not interesting.
13827                                continue;
13828                            }
13829                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
13830                                ProcessRecord client = cr.binding.client;
13831                                int clientAdj = adj;
13832                                int myHiddenAdj = hiddenAdj;
13833                                if (myHiddenAdj > client.hiddenAdj) {
13834                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
13835                                        myHiddenAdj = client.hiddenAdj;
13836                                    } else {
13837                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
13838                                    }
13839                                }
13840                                clientAdj = computeOomAdjLocked(
13841                                    client, myHiddenAdj, TOP_APP, true, doingAll);
13842                                String adjType = null;
13843                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13844                                    // Not doing bind OOM management, so treat
13845                                    // this guy more like a started service.
13846                                    if (app.hasShownUi && app != mHomeProcess) {
13847                                        // If this process has shown some UI, let it immediately
13848                                        // go to the LRU list because it may be pretty heavy with
13849                                        // UI stuff.  We'll tag it with a label just to help
13850                                        // debug and understand what is going on.
13851                                        if (adj > clientAdj) {
13852                                            adjType = "bound-bg-ui-services";
13853                                        }
13854                                        app.hidden = false;
13855                                        clientAdj = adj;
13856                                    } else {
13857                                        if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13858                                            // This service has not seen activity within
13859                                            // recent memory, so allow it to drop to the
13860                                            // LRU list if there is no other reason to keep
13861                                            // it around.  We'll also tag it with a label just
13862                                            // to help debug and undertand what is going on.
13863                                            if (adj > clientAdj) {
13864                                                adjType = "bound-bg-services";
13865                                            }
13866                                            clientAdj = adj;
13867                                        }
13868                                    }
13869                                }
13870                                if (adj > clientAdj) {
13871                                    // If this process has recently shown UI, and
13872                                    // the process that is binding to it is less
13873                                    // important than being visible, then we don't
13874                                    // care about the binding as much as we care
13875                                    // about letting this process get into the LRU
13876                                    // list to be killed and restarted if needed for
13877                                    // memory.
13878                                    if (app.hasShownUi && app != mHomeProcess
13879                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13880                                        adjType = "bound-bg-ui-services";
13881                                    } else {
13882                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13883                                                |Context.BIND_IMPORTANT)) != 0) {
13884                                            adj = clientAdj;
13885                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13886                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13887                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13888                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13889                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
13890                                            adj = clientAdj;
13891                                        } else {
13892                                            app.pendingUiClean = true;
13893                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
13894                                                adj = ProcessList.VISIBLE_APP_ADJ;
13895                                            }
13896                                        }
13897                                        if (!client.hidden) {
13898                                            app.hidden = false;
13899                                        }
13900                                        if (client.keeping) {
13901                                            app.keeping = true;
13902                                        }
13903                                        adjType = "service";
13904                                    }
13905                                }
13906                                if (adjType != null) {
13907                                    app.adjType = adjType;
13908                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13909                                            .REASON_SERVICE_IN_USE;
13910                                    app.adjSource = cr.binding.client;
13911                                    app.adjSourceOom = clientAdj;
13912                                    app.adjTarget = s.name;
13913                                }
13914                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13915                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13916                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13917                                    }
13918                                }
13919                            }
13920                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13921                                ActivityRecord a = cr.activity;
13922                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
13923                                        (a.visible || a.state == ActivityState.RESUMED
13924                                         || a.state == ActivityState.PAUSING)) {
13925                                    adj = ProcessList.FOREGROUND_APP_ADJ;
13926                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13927                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13928                                    }
13929                                    app.hidden = false;
13930                                    app.adjType = "service";
13931                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13932                                            .REASON_SERVICE_IN_USE;
13933                                    app.adjSource = a;
13934                                    app.adjSourceOom = adj;
13935                                    app.adjTarget = s.name;
13936                                }
13937                            }
13938                        }
13939                    }
13940                }
13941            }
13942
13943            // Finally, if this process has active services running in it, we
13944            // would like to avoid killing it unless it would prevent the current
13945            // application from running.  By default we put the process in
13946            // with the rest of the background processes; as we scan through
13947            // its services we may bump it up from there.
13948            if (adj > hiddenAdj) {
13949                adj = hiddenAdj;
13950                app.hidden = false;
13951                app.adjType = "bg-services";
13952            }
13953        }
13954
13955        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13956                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13957            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13958            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13959                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13960                ContentProviderRecord cpr = jt.next();
13961                if (cpr.clients.size() != 0) {
13962                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
13963                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13964                        ProcessRecord client = kt.next();
13965                        if (client == app) {
13966                            // Being our own client is not interesting.
13967                            continue;
13968                        }
13969                        int myHiddenAdj = hiddenAdj;
13970                        if (myHiddenAdj > client.hiddenAdj) {
13971                            if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13972                                myHiddenAdj = client.hiddenAdj;
13973                            } else {
13974                                myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13975                            }
13976                        }
13977                        int clientAdj = computeOomAdjLocked(
13978                            client, myHiddenAdj, TOP_APP, true, doingAll);
13979                        if (adj > clientAdj) {
13980                            if (app.hasShownUi && app != mHomeProcess
13981                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13982                                app.adjType = "bg-ui-provider";
13983                            } else {
13984                                adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13985                                        ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13986                                app.adjType = "provider";
13987                            }
13988                            if (!client.hidden) {
13989                                app.hidden = false;
13990                            }
13991                            if (client.keeping) {
13992                                app.keeping = true;
13993                            }
13994                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13995                                    .REASON_PROVIDER_IN_USE;
13996                            app.adjSource = client;
13997                            app.adjSourceOom = clientAdj;
13998                            app.adjTarget = cpr.name;
13999                        }
14000                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14001                            schedGroup = Process.THREAD_GROUP_DEFAULT;
14002                        }
14003                    }
14004                }
14005                // If the provider has external (non-framework) process
14006                // dependencies, ensure that its adjustment is at least
14007                // FOREGROUND_APP_ADJ.
14008                if (cpr.hasExternalProcessHandles()) {
14009                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14010                        adj = ProcessList.FOREGROUND_APP_ADJ;
14011                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14012                        app.hidden = false;
14013                        app.keeping = true;
14014                        app.adjType = "provider";
14015                        app.adjTarget = cpr.name;
14016                    }
14017                }
14018            }
14019        }
14020
14021        if (adj == ProcessList.SERVICE_ADJ) {
14022            if (doingAll) {
14023                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14024                mNewNumServiceProcs++;
14025            }
14026            if (app.serviceb) {
14027                adj = ProcessList.SERVICE_B_ADJ;
14028            }
14029        } else {
14030            app.serviceb = false;
14031        }
14032
14033        app.nonStoppingAdj = adj;
14034
14035        if (hasStoppingActivities) {
14036            // Only upgrade adjustment.
14037            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14038                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14039                app.adjType = "stopping";
14040            }
14041        }
14042
14043        app.curRawAdj = adj;
14044
14045        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14046        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14047        if (adj > app.maxAdj) {
14048            adj = app.maxAdj;
14049            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14050                schedGroup = Process.THREAD_GROUP_DEFAULT;
14051            }
14052        }
14053        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14054            app.keeping = true;
14055        }
14056
14057        if (app.hasAboveClient) {
14058            // If this process has bound to any services with BIND_ABOVE_CLIENT,
14059            // then we need to drop its adjustment to be lower than the service's
14060            // in order to honor the request.  We want to drop it by one adjustment
14061            // level...  but there is special meaning applied to various levels so
14062            // we will skip some of them.
14063            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
14064                // System process will not get dropped, ever
14065            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14066                adj = ProcessList.VISIBLE_APP_ADJ;
14067            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14068                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14069            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14070                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
14071            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
14072                adj++;
14073            }
14074        }
14075
14076        app.curAdj = adj;
14077        app.curSchedGroup = schedGroup;
14078
14079        if (hadForegroundActivities != app.foregroundActivities) {
14080            mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14081                    app.foregroundActivities).sendToTarget();
14082        }
14083
14084        return app.curRawAdj;
14085    }
14086
14087    /**
14088     * Ask a given process to GC right now.
14089     */
14090    final void performAppGcLocked(ProcessRecord app) {
14091        try {
14092            app.lastRequestedGc = SystemClock.uptimeMillis();
14093            if (app.thread != null) {
14094                if (app.reportLowMemory) {
14095                    app.reportLowMemory = false;
14096                    app.thread.scheduleLowMemory();
14097                } else {
14098                    app.thread.processInBackground();
14099                }
14100            }
14101        } catch (Exception e) {
14102            // whatever.
14103        }
14104    }
14105
14106    /**
14107     * Returns true if things are idle enough to perform GCs.
14108     */
14109    private final boolean canGcNowLocked() {
14110        boolean processingBroadcasts = false;
14111        for (BroadcastQueue q : mBroadcastQueues) {
14112            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14113                processingBroadcasts = true;
14114            }
14115        }
14116        return !processingBroadcasts
14117                && (mSleeping || (mMainStack.mResumedActivity != null &&
14118                        mMainStack.mResumedActivity.idle));
14119    }
14120
14121    /**
14122     * Perform GCs on all processes that are waiting for it, but only
14123     * if things are idle.
14124     */
14125    final void performAppGcsLocked() {
14126        final int N = mProcessesToGc.size();
14127        if (N <= 0) {
14128            return;
14129        }
14130        if (canGcNowLocked()) {
14131            while (mProcessesToGc.size() > 0) {
14132                ProcessRecord proc = mProcessesToGc.remove(0);
14133                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14134                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14135                            <= SystemClock.uptimeMillis()) {
14136                        // To avoid spamming the system, we will GC processes one
14137                        // at a time, waiting a few seconds between each.
14138                        performAppGcLocked(proc);
14139                        scheduleAppGcsLocked();
14140                        return;
14141                    } else {
14142                        // It hasn't been long enough since we last GCed this
14143                        // process...  put it in the list to wait for its time.
14144                        addProcessToGcListLocked(proc);
14145                        break;
14146                    }
14147                }
14148            }
14149
14150            scheduleAppGcsLocked();
14151        }
14152    }
14153
14154    /**
14155     * If all looks good, perform GCs on all processes waiting for them.
14156     */
14157    final void performAppGcsIfAppropriateLocked() {
14158        if (canGcNowLocked()) {
14159            performAppGcsLocked();
14160            return;
14161        }
14162        // Still not idle, wait some more.
14163        scheduleAppGcsLocked();
14164    }
14165
14166    /**
14167     * Schedule the execution of all pending app GCs.
14168     */
14169    final void scheduleAppGcsLocked() {
14170        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14171
14172        if (mProcessesToGc.size() > 0) {
14173            // Schedule a GC for the time to the next process.
14174            ProcessRecord proc = mProcessesToGc.get(0);
14175            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14176
14177            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14178            long now = SystemClock.uptimeMillis();
14179            if (when < (now+GC_TIMEOUT)) {
14180                when = now + GC_TIMEOUT;
14181            }
14182            mHandler.sendMessageAtTime(msg, when);
14183        }
14184    }
14185
14186    /**
14187     * Add a process to the array of processes waiting to be GCed.  Keeps the
14188     * list in sorted order by the last GC time.  The process can't already be
14189     * on the list.
14190     */
14191    final void addProcessToGcListLocked(ProcessRecord proc) {
14192        boolean added = false;
14193        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14194            if (mProcessesToGc.get(i).lastRequestedGc <
14195                    proc.lastRequestedGc) {
14196                added = true;
14197                mProcessesToGc.add(i+1, proc);
14198                break;
14199            }
14200        }
14201        if (!added) {
14202            mProcessesToGc.add(0, proc);
14203        }
14204    }
14205
14206    /**
14207     * Set up to ask a process to GC itself.  This will either do it
14208     * immediately, or put it on the list of processes to gc the next
14209     * time things are idle.
14210     */
14211    final void scheduleAppGcLocked(ProcessRecord app) {
14212        long now = SystemClock.uptimeMillis();
14213        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
14214            return;
14215        }
14216        if (!mProcessesToGc.contains(app)) {
14217            addProcessToGcListLocked(app);
14218            scheduleAppGcsLocked();
14219        }
14220    }
14221
14222    final void checkExcessivePowerUsageLocked(boolean doKills) {
14223        updateCpuStatsNow();
14224
14225        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14226        boolean doWakeKills = doKills;
14227        boolean doCpuKills = doKills;
14228        if (mLastPowerCheckRealtime == 0) {
14229            doWakeKills = false;
14230        }
14231        if (mLastPowerCheckUptime == 0) {
14232            doCpuKills = false;
14233        }
14234        if (stats.isScreenOn()) {
14235            doWakeKills = false;
14236        }
14237        final long curRealtime = SystemClock.elapsedRealtime();
14238        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14239        final long curUptime = SystemClock.uptimeMillis();
14240        final long uptimeSince = curUptime - mLastPowerCheckUptime;
14241        mLastPowerCheckRealtime = curRealtime;
14242        mLastPowerCheckUptime = curUptime;
14243        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14244            doWakeKills = false;
14245        }
14246        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14247            doCpuKills = false;
14248        }
14249        int i = mLruProcesses.size();
14250        while (i > 0) {
14251            i--;
14252            ProcessRecord app = mLruProcesses.get(i);
14253            if (!app.keeping) {
14254                long wtime;
14255                synchronized (stats) {
14256                    wtime = stats.getProcessWakeTime(app.info.uid,
14257                            app.pid, curRealtime);
14258                }
14259                long wtimeUsed = wtime - app.lastWakeTime;
14260                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14261                if (DEBUG_POWER) {
14262                    StringBuilder sb = new StringBuilder(128);
14263                    sb.append("Wake for ");
14264                    app.toShortString(sb);
14265                    sb.append(": over ");
14266                    TimeUtils.formatDuration(realtimeSince, sb);
14267                    sb.append(" used ");
14268                    TimeUtils.formatDuration(wtimeUsed, sb);
14269                    sb.append(" (");
14270                    sb.append((wtimeUsed*100)/realtimeSince);
14271                    sb.append("%)");
14272                    Slog.i(TAG, sb.toString());
14273                    sb.setLength(0);
14274                    sb.append("CPU for ");
14275                    app.toShortString(sb);
14276                    sb.append(": over ");
14277                    TimeUtils.formatDuration(uptimeSince, sb);
14278                    sb.append(" used ");
14279                    TimeUtils.formatDuration(cputimeUsed, sb);
14280                    sb.append(" (");
14281                    sb.append((cputimeUsed*100)/uptimeSince);
14282                    sb.append("%)");
14283                    Slog.i(TAG, sb.toString());
14284                }
14285                // If a process has held a wake lock for more
14286                // than 50% of the time during this period,
14287                // that sounds bad.  Kill!
14288                if (doWakeKills && realtimeSince > 0
14289                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
14290                    synchronized (stats) {
14291                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14292                                realtimeSince, wtimeUsed);
14293                    }
14294                    Slog.w(TAG, "Excessive wake lock in " + app.processName
14295                            + " (pid " + app.pid + "): held " + wtimeUsed
14296                            + " during " + realtimeSince);
14297                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14298                            app.processName, app.setAdj, "excessive wake lock");
14299                    Process.killProcessQuiet(app.pid);
14300                } else if (doCpuKills && uptimeSince > 0
14301                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
14302                    synchronized (stats) {
14303                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14304                                uptimeSince, cputimeUsed);
14305                    }
14306                    Slog.w(TAG, "Excessive CPU in " + app.processName
14307                            + " (pid " + app.pid + "): used " + cputimeUsed
14308                            + " during " + uptimeSince);
14309                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14310                            app.processName, app.setAdj, "excessive cpu");
14311                    Process.killProcessQuiet(app.pid);
14312                } else {
14313                    app.lastWakeTime = wtime;
14314                    app.lastCpuTime = app.curCpuTime;
14315                }
14316            }
14317        }
14318    }
14319
14320    private final boolean updateOomAdjLocked(
14321            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
14322        app.hiddenAdj = hiddenAdj;
14323
14324        if (app.thread == null) {
14325            return false;
14326        }
14327
14328        final boolean wasKeeping = app.keeping;
14329
14330        boolean success = true;
14331
14332        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
14333
14334        if (app.curRawAdj != app.setRawAdj) {
14335            if (wasKeeping && !app.keeping) {
14336                // This app is no longer something we want to keep.  Note
14337                // its current wake lock time to later know to kill it if
14338                // it is not behaving well.
14339                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14340                synchronized (stats) {
14341                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14342                            app.pid, SystemClock.elapsedRealtime());
14343                }
14344                app.lastCpuTime = app.curCpuTime;
14345            }
14346
14347            app.setRawAdj = app.curRawAdj;
14348        }
14349
14350        if (app.curAdj != app.setAdj) {
14351            if (Process.setOomAdj(app.pid, app.curAdj)) {
14352                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14353                    TAG, "Set " + app.pid + " " + app.processName +
14354                    " adj " + app.curAdj + ": " + app.adjType);
14355                app.setAdj = app.curAdj;
14356            } else {
14357                success = false;
14358                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
14359            }
14360        }
14361        if (app.setSchedGroup != app.curSchedGroup) {
14362            app.setSchedGroup = app.curSchedGroup;
14363            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14364                    "Setting process group of " + app.processName
14365                    + " to " + app.curSchedGroup);
14366            if (app.waitingToKill != null &&
14367                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14368                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14369                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14370                        app.processName, app.setAdj, app.waitingToKill);
14371                Process.killProcessQuiet(app.pid);
14372                success = false;
14373            } else {
14374                if (true) {
14375                    long oldId = Binder.clearCallingIdentity();
14376                    try {
14377                        Process.setProcessGroup(app.pid, app.curSchedGroup);
14378                    } catch (Exception e) {
14379                        Slog.w(TAG, "Failed setting process group of " + app.pid
14380                                + " to " + app.curSchedGroup);
14381                        e.printStackTrace();
14382                    } finally {
14383                        Binder.restoreCallingIdentity(oldId);
14384                    }
14385                } else {
14386                    if (app.thread != null) {
14387                        try {
14388                            app.thread.setSchedulingGroup(app.curSchedGroup);
14389                        } catch (RemoteException e) {
14390                        }
14391                    }
14392                }
14393            }
14394        }
14395        return success;
14396    }
14397
14398    private final ActivityRecord resumedAppLocked() {
14399        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
14400        if (resumedActivity == null || resumedActivity.app == null) {
14401            resumedActivity = mMainStack.mPausingActivity;
14402            if (resumedActivity == null || resumedActivity.app == null) {
14403                resumedActivity = mMainStack.topRunningActivityLocked(null);
14404            }
14405        }
14406        return resumedActivity;
14407    }
14408
14409    private final boolean updateOomAdjLocked(ProcessRecord app) {
14410        final ActivityRecord TOP_ACT = resumedAppLocked();
14411        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14412        int curAdj = app.curAdj;
14413        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14414            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14415
14416        mAdjSeq++;
14417
14418        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
14419        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14420            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14421        if (nowHidden != wasHidden) {
14422            // Changed to/from hidden state, so apps after it in the LRU
14423            // list may also be changed.
14424            updateOomAdjLocked();
14425        }
14426        return success;
14427    }
14428
14429    final void updateOomAdjLocked() {
14430        final ActivityRecord TOP_ACT = resumedAppLocked();
14431        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14432
14433        if (false) {
14434            RuntimeException e = new RuntimeException();
14435            e.fillInStackTrace();
14436            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
14437        }
14438
14439        mAdjSeq++;
14440        mNewNumServiceProcs = 0;
14441
14442        // Let's determine how many processes we have running vs.
14443        // how many slots we have for background processes; we may want
14444        // to put multiple processes in a slot of there are enough of
14445        // them.
14446        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
14447        int factor = (mLruProcesses.size()-4)/numSlots;
14448        if (factor < 1) factor = 1;
14449        int step = 0;
14450        int numHidden = 0;
14451        int numTrimming = 0;
14452
14453        // First update the OOM adjustment for each of the
14454        // application processes based on their current state.
14455        int i = mLruProcesses.size();
14456        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
14457        while (i > 0) {
14458            i--;
14459            ProcessRecord app = mLruProcesses.get(i);
14460            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
14461            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14462            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
14463                && app.curAdj == curHiddenAdj) {
14464                step++;
14465                if (step >= factor) {
14466                    step = 0;
14467                    curHiddenAdj++;
14468                }
14469            }
14470            if (!app.killedBackground) {
14471                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14472                    numHidden++;
14473                    if (numHidden > mProcessLimit) {
14474                        Slog.i(TAG, "No longer want " + app.processName
14475                                + " (pid " + app.pid + "): hidden #" + numHidden);
14476                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14477                                app.processName, app.setAdj, "too many background");
14478                        app.killedBackground = true;
14479                        Process.killProcessQuiet(app.pid);
14480                    }
14481                }
14482                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14483                    // If this is an isolated process, and there are no
14484                    // services running in it, then the process is no longer
14485                    // needed.  We agressively kill these because we can by
14486                    // definition not re-use the same process again, and it is
14487                    // good to avoid having whatever code was running in them
14488                    // left sitting around after no longer needed.
14489                    Slog.i(TAG, "Isolated process " + app.processName
14490                            + " (pid " + app.pid + ") no longer needed");
14491                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14492                            app.processName, app.setAdj, "isolated not needed");
14493                    app.killedBackground = true;
14494                    Process.killProcessQuiet(app.pid);
14495                }
14496                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14497                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14498                        && !app.killedBackground) {
14499                    numTrimming++;
14500                }
14501            }
14502        }
14503
14504        mNumServiceProcs = mNewNumServiceProcs;
14505
14506        // Now determine the memory trimming level of background processes.
14507        // Unfortunately we need to start at the back of the list to do this
14508        // properly.  We only do this if the number of background apps we
14509        // are managing to keep around is less than half the maximum we desire;
14510        // if we are keeping a good number around, we'll let them use whatever
14511        // memory they want.
14512        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
14513            final int N = mLruProcesses.size();
14514            factor = numTrimming/3;
14515            int minFactor = 2;
14516            if (mHomeProcess != null) minFactor++;
14517            if (mPreviousProcess != null) minFactor++;
14518            if (factor < minFactor) factor = minFactor;
14519            step = 0;
14520            int fgTrimLevel;
14521            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
14522                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
14523            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
14524                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
14525            } else {
14526                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
14527            }
14528            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
14529            for (i=0; i<N; i++) {
14530                ProcessRecord app = mLruProcesses.get(i);
14531                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14532                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14533                        && !app.killedBackground) {
14534                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
14535                        try {
14536                            app.thread.scheduleTrimMemory(curLevel);
14537                        } catch (RemoteException e) {
14538                        }
14539                        if (false) {
14540                            // For now we won't do this; our memory trimming seems
14541                            // to be good enough at this point that destroying
14542                            // activities causes more harm than good.
14543                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14544                                    && app != mHomeProcess && app != mPreviousProcess) {
14545                                // Need to do this on its own message because the stack may not
14546                                // be in a consistent state at this point.
14547                                // For these apps we will also finish their activities
14548                                // to help them free memory.
14549                                mMainStack.scheduleDestroyActivities(app, false, "trim");
14550                            }
14551                        }
14552                    }
14553                    app.trimMemoryLevel = curLevel;
14554                    step++;
14555                    if (step >= factor) {
14556                        step = 0;
14557                        switch (curLevel) {
14558                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14559                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
14560                                break;
14561                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14562                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14563                                break;
14564                        }
14565                    }
14566                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14567                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
14568                            && app.thread != null) {
14569                        try {
14570                            app.thread.scheduleTrimMemory(
14571                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
14572                        } catch (RemoteException e) {
14573                        }
14574                    }
14575                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14576                } else {
14577                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14578                            && app.pendingUiClean) {
14579                        // If this application is now in the background and it
14580                        // had done UI, then give it the special trim level to
14581                        // have it free UI resources.
14582                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14583                        if (app.trimMemoryLevel < level && app.thread != null) {
14584                            try {
14585                                app.thread.scheduleTrimMemory(level);
14586                            } catch (RemoteException e) {
14587                            }
14588                        }
14589                        app.pendingUiClean = false;
14590                    }
14591                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
14592                        try {
14593                            app.thread.scheduleTrimMemory(fgTrimLevel);
14594                        } catch (RemoteException e) {
14595                        }
14596                    }
14597                    app.trimMemoryLevel = fgTrimLevel;
14598                }
14599            }
14600        } else {
14601            final int N = mLruProcesses.size();
14602            for (i=0; i<N; i++) {
14603                ProcessRecord app = mLruProcesses.get(i);
14604                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14605                        && app.pendingUiClean) {
14606                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14607                            && app.thread != null) {
14608                        try {
14609                            app.thread.scheduleTrimMemory(
14610                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14611                        } catch (RemoteException e) {
14612                        }
14613                    }
14614                    app.pendingUiClean = false;
14615                }
14616                app.trimMemoryLevel = 0;
14617            }
14618        }
14619
14620        if (mAlwaysFinishActivities) {
14621            // Need to do this on its own message because the stack may not
14622            // be in a consistent state at this point.
14623            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
14624        }
14625    }
14626
14627    final void trimApplications() {
14628        synchronized (this) {
14629            int i;
14630
14631            // First remove any unused application processes whose package
14632            // has been removed.
14633            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14634                final ProcessRecord app = mRemovedProcesses.get(i);
14635                if (app.activities.size() == 0
14636                        && app.curReceiver == null && app.services.size() == 0) {
14637                    Slog.i(
14638                        TAG, "Exiting empty application process "
14639                        + app.processName + " ("
14640                        + (app.thread != null ? app.thread.asBinder() : null)
14641                        + ")\n");
14642                    if (app.pid > 0 && app.pid != MY_PID) {
14643                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14644                                app.processName, app.setAdj, "empty");
14645                        Process.killProcessQuiet(app.pid);
14646                    } else {
14647                        try {
14648                            app.thread.scheduleExit();
14649                        } catch (Exception e) {
14650                            // Ignore exceptions.
14651                        }
14652                    }
14653                    cleanUpApplicationRecordLocked(app, false, true, -1);
14654                    mRemovedProcesses.remove(i);
14655
14656                    if (app.persistent) {
14657                        if (app.persistent) {
14658                            addAppLocked(app.info, false);
14659                        }
14660                    }
14661                }
14662            }
14663
14664            // Now update the oom adj for all processes.
14665            updateOomAdjLocked();
14666        }
14667    }
14668
14669    /** This method sends the specified signal to each of the persistent apps */
14670    public void signalPersistentProcesses(int sig) throws RemoteException {
14671        if (sig != Process.SIGNAL_USR1) {
14672            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14673        }
14674
14675        synchronized (this) {
14676            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14677                    != PackageManager.PERMISSION_GRANTED) {
14678                throw new SecurityException("Requires permission "
14679                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14680            }
14681
14682            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14683                ProcessRecord r = mLruProcesses.get(i);
14684                if (r.thread != null && r.persistent) {
14685                    Process.sendSignal(r.pid, sig);
14686                }
14687            }
14688        }
14689    }
14690
14691    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14692        if (proc == null || proc == mProfileProc) {
14693            proc = mProfileProc;
14694            path = mProfileFile;
14695            profileType = mProfileType;
14696            clearProfilerLocked();
14697        }
14698        if (proc == null) {
14699            return;
14700        }
14701        try {
14702            proc.thread.profilerControl(false, path, null, profileType);
14703        } catch (RemoteException e) {
14704            throw new IllegalStateException("Process disappeared");
14705        }
14706    }
14707
14708    private void clearProfilerLocked() {
14709        if (mProfileFd != null) {
14710            try {
14711                mProfileFd.close();
14712            } catch (IOException e) {
14713            }
14714        }
14715        mProfileApp = null;
14716        mProfileProc = null;
14717        mProfileFile = null;
14718        mProfileType = 0;
14719        mAutoStopProfiler = false;
14720    }
14721
14722    public boolean profileControl(String process, boolean start,
14723            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
14724
14725        try {
14726            synchronized (this) {
14727                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14728                // its own permission.
14729                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14730                        != PackageManager.PERMISSION_GRANTED) {
14731                    throw new SecurityException("Requires permission "
14732                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14733                }
14734
14735                if (start && fd == null) {
14736                    throw new IllegalArgumentException("null fd");
14737                }
14738
14739                ProcessRecord proc = null;
14740                if (process != null) {
14741                    try {
14742                        int pid = Integer.parseInt(process);
14743                        synchronized (mPidsSelfLocked) {
14744                            proc = mPidsSelfLocked.get(pid);
14745                        }
14746                    } catch (NumberFormatException e) {
14747                    }
14748
14749                    if (proc == null) {
14750                        HashMap<String, SparseArray<ProcessRecord>> all
14751                                = mProcessNames.getMap();
14752                        SparseArray<ProcessRecord> procs = all.get(process);
14753                        if (procs != null && procs.size() > 0) {
14754                            proc = procs.valueAt(0);
14755                        }
14756                    }
14757                }
14758
14759                if (start && (proc == null || proc.thread == null)) {
14760                    throw new IllegalArgumentException("Unknown process: " + process);
14761                }
14762
14763                if (start) {
14764                    stopProfilerLocked(null, null, 0);
14765                    setProfileApp(proc.info, proc.processName, path, fd, false);
14766                    mProfileProc = proc;
14767                    mProfileType = profileType;
14768                    try {
14769                        fd = fd.dup();
14770                    } catch (IOException e) {
14771                        fd = null;
14772                    }
14773                    proc.thread.profilerControl(start, path, fd, profileType);
14774                    fd = null;
14775                    mProfileFd = null;
14776                } else {
14777                    stopProfilerLocked(proc, path, profileType);
14778                    if (fd != null) {
14779                        try {
14780                            fd.close();
14781                        } catch (IOException e) {
14782                        }
14783                    }
14784                }
14785
14786                return true;
14787            }
14788        } catch (RemoteException e) {
14789            throw new IllegalStateException("Process disappeared");
14790        } finally {
14791            if (fd != null) {
14792                try {
14793                    fd.close();
14794                } catch (IOException e) {
14795                }
14796            }
14797        }
14798    }
14799
14800    public boolean dumpHeap(String process, boolean managed,
14801            String path, ParcelFileDescriptor fd) throws RemoteException {
14802
14803        try {
14804            synchronized (this) {
14805                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14806                // its own permission (same as profileControl).
14807                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14808                        != PackageManager.PERMISSION_GRANTED) {
14809                    throw new SecurityException("Requires permission "
14810                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14811                }
14812
14813                if (fd == null) {
14814                    throw new IllegalArgumentException("null fd");
14815                }
14816
14817                ProcessRecord proc = null;
14818                try {
14819                    int pid = Integer.parseInt(process);
14820                    synchronized (mPidsSelfLocked) {
14821                        proc = mPidsSelfLocked.get(pid);
14822                    }
14823                } catch (NumberFormatException e) {
14824                }
14825
14826                if (proc == null) {
14827                    HashMap<String, SparseArray<ProcessRecord>> all
14828                            = mProcessNames.getMap();
14829                    SparseArray<ProcessRecord> procs = all.get(process);
14830                    if (procs != null && procs.size() > 0) {
14831                        proc = procs.valueAt(0);
14832                    }
14833                }
14834
14835                if (proc == null || proc.thread == null) {
14836                    throw new IllegalArgumentException("Unknown process: " + process);
14837                }
14838
14839                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14840                if (!isDebuggable) {
14841                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14842                        throw new SecurityException("Process not debuggable: " + proc);
14843                    }
14844                }
14845
14846                proc.thread.dumpHeap(managed, path, fd);
14847                fd = null;
14848                return true;
14849            }
14850        } catch (RemoteException e) {
14851            throw new IllegalStateException("Process disappeared");
14852        } finally {
14853            if (fd != null) {
14854                try {
14855                    fd.close();
14856                } catch (IOException e) {
14857                }
14858            }
14859        }
14860    }
14861
14862    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14863    public void monitor() {
14864        synchronized (this) { }
14865    }
14866
14867    void onCoreSettingsChange(Bundle settings) {
14868        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14869            ProcessRecord processRecord = mLruProcesses.get(i);
14870            try {
14871                if (processRecord.thread != null) {
14872                    processRecord.thread.setCoreSettings(settings);
14873                }
14874            } catch (RemoteException re) {
14875                /* ignore */
14876            }
14877        }
14878    }
14879
14880    // Multi-user methods
14881
14882    private int mCurrentUserId;
14883    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
14884
14885    public boolean switchUser(int userId) {
14886        final int callingUid = Binder.getCallingUid();
14887        if (callingUid != 0 && callingUid != Process.myUid()) {
14888            Slog.e(TAG, "Trying to switch user from unauthorized app");
14889            return false;
14890        }
14891        if (mCurrentUserId == userId)
14892            return true;
14893
14894        synchronized (this) {
14895            // Check if user is already logged in, otherwise check if user exists first before
14896            // adding to the list of logged in users.
14897            if (mLoggedInUsers.indexOfKey(userId) < 0) {
14898                if (!userExists(userId)) {
14899                    return false;
14900                }
14901                mLoggedInUsers.append(userId, userId);
14902            }
14903
14904            mCurrentUserId = userId;
14905            boolean haveActivities = mMainStack.switchUser(userId);
14906            if (!haveActivities) {
14907                startHomeActivityLocked(userId);
14908            }
14909
14910        }
14911
14912        // Inform of user switch
14913        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
14914        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
14915        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
14916
14917        return true;
14918    }
14919
14920    @Override
14921    public UserInfo getCurrentUser() throws RemoteException {
14922        final int callingUid = Binder.getCallingUid();
14923        if (callingUid != 0 && callingUid != Process.myUid()) {
14924            Slog.e(TAG, "Trying to get user from unauthorized app");
14925            return null;
14926        }
14927        return AppGlobals.getPackageManager().getUser(mCurrentUserId);
14928    }
14929
14930    private void onUserRemoved(Intent intent) {
14931        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
14932        if (extraUserId < 1) return;
14933
14934        // Kill all the processes for the user
14935        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
14936        synchronized (this) {
14937            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
14938            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
14939                SparseArray<ProcessRecord> uids = uidMap.getValue();
14940                for (int i = 0; i < uids.size(); i++) {
14941                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
14942                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
14943                    }
14944                }
14945            }
14946
14947            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
14948                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
14949                        false, false, true, true, extraUserId);
14950            }
14951        }
14952    }
14953
14954    private boolean userExists(int userId) {
14955        try {
14956            UserInfo user = AppGlobals.getPackageManager().getUser(userId);
14957            return user != null;
14958        } catch (RemoteException re) {
14959            // Won't happen, in same process
14960        }
14961
14962        return false;
14963    }
14964
14965    private void checkValidCaller(int uid, int userId) {
14966        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14967
14968        throw new SecurityException("Caller uid=" + uid
14969                + " is not privileged to communicate with user=" + userId);
14970    }
14971
14972    private int applyUserId(int uid, int userId) {
14973        return UserId.getUid(userId, uid);
14974    }
14975
14976    private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14977        if (info == null) return null;
14978        ApplicationInfo newInfo = new ApplicationInfo(info);
14979        newInfo.uid = applyUserId(info.uid, userId);
14980        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14981                + info.packageName;
14982        return newInfo;
14983    }
14984
14985    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14986        if (aInfo == null
14987                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
14988            return aInfo;
14989        }
14990
14991        ActivityInfo info = new ActivityInfo(aInfo);
14992        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14993        return info;
14994    }
14995
14996    static class ServiceMap {
14997
14998        private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
14999                = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15000        private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15001                mServicesByIntentPerUser = new SparseArray<
15002                    HashMap<Intent.FilterComparison, ServiceRecord>>();
15003
15004        ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15005            // TODO: Deal with global services
15006            if (DEBUG_MU)
15007                Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15008            return getServices(callingUser).get(name);
15009        }
15010
15011        ServiceRecord getServiceByName(ComponentName name) {
15012            return getServiceByName(name, -1);
15013        }
15014
15015        ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15016            // TODO: Deal with global services
15017            if (DEBUG_MU)
15018                Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15019            return getServicesByIntent(callingUser).get(filter);
15020        }
15021
15022        ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15023            return getServiceByIntent(filter, -1);
15024        }
15025
15026        void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15027            // TODO: Deal with global services
15028            getServices(callingUser).put(name, value);
15029        }
15030
15031        void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15032                ServiceRecord value) {
15033            // TODO: Deal with global services
15034            getServicesByIntent(callingUser).put(filter, value);
15035        }
15036
15037        void removeServiceByName(ComponentName name, int callingUser) {
15038            // TODO: Deal with global services
15039            ServiceRecord removed = getServices(callingUser).remove(name);
15040            if (DEBUG_MU)
15041                Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15042                        + " removed=" + removed);
15043        }
15044
15045        void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15046            // TODO: Deal with global services
15047            ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15048            if (DEBUG_MU)
15049                Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15050                        + " removed=" + removed);
15051        }
15052
15053        Collection<ServiceRecord> getAllServices(int callingUser) {
15054            // TODO: Deal with global services
15055            return getServices(callingUser).values();
15056        }
15057
15058        private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15059            HashMap map = mServicesByNamePerUser.get(callingUser);
15060            if (map == null) {
15061                map = new HashMap<ComponentName, ServiceRecord>();
15062                mServicesByNamePerUser.put(callingUser, map);
15063            }
15064            return map;
15065        }
15066
15067        private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15068                int callingUser) {
15069            HashMap map = mServicesByIntentPerUser.get(callingUser);
15070            if (map == null) {
15071                map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15072                mServicesByIntentPerUser.put(callingUser, map);
15073            }
15074            return map;
15075        }
15076    }
15077}
15078