OSDN Git Service

am c660c608: Merge "add Toshiba usb driver link delete Fujitsu-Toshiba bug: 9755017...
[android-x86/frameworks-base.git] / services / java / com / android / server / am / ActivityManagerService.java
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
17 package com.android.server.am;
18
19 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21 import com.android.internal.R;
22 import com.android.internal.os.BatteryStatsImpl;
23 import com.android.internal.os.ProcessStats;
24 import com.android.server.AttributeCache;
25 import com.android.server.IntentResolver;
26 import com.android.server.ProcessMap;
27 import com.android.server.SystemServer;
28 import com.android.server.Watchdog;
29 import com.android.server.am.ActivityStack.ActivityState;
30 import com.android.server.pm.UserManagerService;
31 import com.android.server.wm.WindowManagerService;
32
33 import dalvik.system.Zygote;
34
35 import android.app.Activity;
36 import android.app.ActivityManager;
37 import android.app.ActivityManagerNative;
38 import android.app.ActivityOptions;
39 import android.app.ActivityThread;
40 import android.app.AlertDialog;
41 import android.app.AppGlobals;
42 import android.app.ApplicationErrorReport;
43 import android.app.Dialog;
44 import android.app.IActivityController;
45 import android.app.IApplicationThread;
46 import android.app.IInstrumentationWatcher;
47 import android.app.INotificationManager;
48 import android.app.IProcessObserver;
49 import android.app.IServiceConnection;
50 import android.app.IStopUserCallback;
51 import android.app.IThumbnailReceiver;
52 import android.app.IUserSwitchObserver;
53 import android.app.Instrumentation;
54 import android.app.Notification;
55 import android.app.NotificationManager;
56 import android.app.PendingIntent;
57 import android.app.backup.IBackupManager;
58 import android.content.ActivityNotFoundException;
59 import android.content.BroadcastReceiver;
60 import android.content.ClipData;
61 import android.content.ComponentCallbacks2;
62 import android.content.ComponentName;
63 import android.content.ContentProvider;
64 import android.content.ContentResolver;
65 import android.content.Context;
66 import android.content.DialogInterface;
67 import android.content.IContentProvider;
68 import android.content.IIntentReceiver;
69 import android.content.IIntentSender;
70 import android.content.Intent;
71 import android.content.IntentFilter;
72 import android.content.IntentSender;
73 import android.content.pm.ActivityInfo;
74 import android.content.pm.ApplicationInfo;
75 import android.content.pm.ConfigurationInfo;
76 import android.content.pm.IPackageDataObserver;
77 import android.content.pm.IPackageManager;
78 import android.content.pm.InstrumentationInfo;
79 import android.content.pm.PackageInfo;
80 import android.content.pm.PackageManager;
81 import android.content.pm.UserInfo;
82 import android.content.pm.PackageManager.NameNotFoundException;
83 import android.content.pm.PathPermission;
84 import android.content.pm.ProviderInfo;
85 import android.content.pm.ResolveInfo;
86 import android.content.pm.ServiceInfo;
87 import android.content.res.CompatibilityInfo;
88 import android.content.res.Configuration;
89 import android.graphics.Bitmap;
90 import android.net.Proxy;
91 import android.net.ProxyProperties;
92 import android.net.Uri;
93 import android.os.Binder;
94 import android.os.Build;
95 import android.os.Bundle;
96 import android.os.Debug;
97 import android.os.DropBoxManager;
98 import android.os.Environment;
99 import android.os.FileObserver;
100 import android.os.FileUtils;
101 import android.os.Handler;
102 import android.os.IBinder;
103 import android.os.IPermissionController;
104 import android.os.IRemoteCallback;
105 import android.os.IUserManager;
106 import android.os.Looper;
107 import android.os.Message;
108 import android.os.Parcel;
109 import android.os.ParcelFileDescriptor;
110 import android.os.Process;
111 import android.os.RemoteCallbackList;
112 import android.os.RemoteException;
113 import android.os.SELinux;
114 import android.os.ServiceManager;
115 import android.os.StrictMode;
116 import android.os.SystemClock;
117 import android.os.SystemProperties;
118 import android.os.UpdateLock;
119 import android.os.UserHandle;
120 import android.provider.Settings;
121 import android.text.format.Time;
122 import android.util.EventLog;
123 import android.util.Log;
124 import android.util.Pair;
125 import android.util.PrintWriterPrinter;
126 import android.util.Slog;
127 import android.util.SparseArray;
128 import android.util.TimeUtils;
129 import android.view.Gravity;
130 import android.view.LayoutInflater;
131 import android.view.View;
132 import android.view.WindowManager;
133 import android.view.WindowManagerPolicy;
134
135 import java.io.BufferedInputStream;
136 import java.io.BufferedOutputStream;
137 import java.io.BufferedReader;
138 import java.io.DataInputStream;
139 import java.io.DataOutputStream;
140 import java.io.File;
141 import java.io.FileDescriptor;
142 import java.io.FileInputStream;
143 import java.io.FileNotFoundException;
144 import java.io.FileOutputStream;
145 import java.io.IOException;
146 import java.io.InputStreamReader;
147 import java.io.PrintWriter;
148 import java.io.StringWriter;
149 import java.lang.ref.WeakReference;
150 import java.util.ArrayList;
151 import java.util.Arrays;
152 import java.util.Collections;
153 import java.util.Comparator;
154 import java.util.HashMap;
155 import java.util.HashSet;
156 import java.util.Iterator;
157 import java.util.List;
158 import java.util.Locale;
159 import java.util.Map;
160 import java.util.Set;
161 import java.util.concurrent.atomic.AtomicBoolean;
162 import java.util.concurrent.atomic.AtomicLong;
163
164 public final class ActivityManagerService extends ActivityManagerNative
165         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
166     private static final String USER_DATA_DIR = "/data/user/";
167     static final String TAG = "ActivityManager";
168     static final String TAG_MU = "ActivityManagerServiceMU";
169     static final boolean DEBUG = false;
170     static final boolean localLOGV = DEBUG;
171     static final boolean DEBUG_SWITCH = localLOGV || false;
172     static final boolean DEBUG_TASKS = localLOGV || false;
173     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
174     static final boolean DEBUG_PAUSE = localLOGV || false;
175     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
176     static final boolean DEBUG_TRANSITION = localLOGV || false;
177     static final boolean DEBUG_BROADCAST = localLOGV || false;
178     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
179     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
180     static final boolean DEBUG_SERVICE = localLOGV || false;
181     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
182     static final boolean DEBUG_VISBILITY = localLOGV || false;
183     static final boolean DEBUG_PROCESSES = localLOGV || false;
184     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
185     static final boolean DEBUG_CLEANUP = localLOGV || false;
186     static final boolean DEBUG_PROVIDER = localLOGV || false;
187     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
188     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
189     static final boolean DEBUG_RESULTS = localLOGV || false;
190     static final boolean DEBUG_BACKUP = localLOGV || false;
191     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
192     static final boolean DEBUG_POWER = localLOGV || false;
193     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
194     static final boolean DEBUG_MU = localLOGV || false;
195     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
196     static final boolean VALIDATE_TOKENS = false;
197     static final boolean SHOW_ACTIVITY_START_TIME = true;
198     
199     // Control over CPU and battery monitoring.
200     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
201     static final boolean MONITOR_CPU_USAGE = true;
202     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
203     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
204     static final boolean MONITOR_THREAD_CPU_USAGE = false;
205
206     // The flags that are set for all calls we make to the package manager.
207     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
208     
209     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
210
211     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
212
213     // Maximum number of recent tasks that we can remember.
214     static final int MAX_RECENT_TASKS = 20;
215     
216     // Amount of time after a call to stopAppSwitches() during which we will
217     // prevent further untrusted switches from happening.
218     static final long APP_SWITCH_DELAY_TIME = 5*1000;
219
220     // How long we wait for a launched process to attach to the activity manager
221     // before we decide it's never going to come up for real.
222     static final int PROC_START_TIMEOUT = 10*1000;
223
224     // How long we wait for a launched process to attach to the activity manager
225     // before we decide it's never going to come up for real, when the process was
226     // started with a wrapper for instrumentation (such as Valgrind) because it
227     // could take much longer than usual.
228     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
229
230     // How long to wait after going idle before forcing apps to GC.
231     static final int GC_TIMEOUT = 5*1000;
232
233     // The minimum amount of time between successive GC requests for a process.
234     static final int GC_MIN_INTERVAL = 60*1000;
235
236     // The rate at which we check for apps using excessive power -- 15 mins.
237     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
238
239     // The minimum sample duration we will allow before deciding we have
240     // enough data on wake locks to start killing things.
241     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
242
243     // The minimum sample duration we will allow before deciding we have
244     // enough data on CPU usage to start killing things.
245     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
246
247     // How long we allow a receiver to run before giving up on it.
248     static final int BROADCAST_FG_TIMEOUT = 10*1000;
249     static final int BROADCAST_BG_TIMEOUT = 60*1000;
250
251     // How long we wait until we timeout on key dispatching.
252     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
253
254     // How long we wait until we timeout on key dispatching during instrumentation.
255     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
256
257     // Amount of time we wait for observers to handle a user switch before
258     // giving up on them and unfreezing the screen.
259     static final int USER_SWITCH_TIMEOUT = 2*1000;
260
261     // Maximum number of users we allow to be running at a time.
262     static final int MAX_RUNNING_USERS = 3;
263
264     static final int MY_PID = Process.myPid();
265     
266     static final String[] EMPTY_STRING_ARRAY = new String[0];
267
268     public ActivityStack mMainStack;
269
270     private final boolean mHeadless;
271
272     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
273     // default actuion automatically.  Important for devices without direct input
274     // devices.
275     private boolean mShowDialogs = true;
276
277     /**
278      * Description of a request to start a new activity, which has been held
279      * due to app switches being disabled.
280      */
281     static class PendingActivityLaunch {
282         ActivityRecord r;
283         ActivityRecord sourceRecord;
284         int startFlags;
285     }
286     
287     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
288             = new ArrayList<PendingActivityLaunch>();
289     
290
291     BroadcastQueue mFgBroadcastQueue;
292     BroadcastQueue mBgBroadcastQueue;
293     // Convenient for easy iteration over the queues. Foreground is first
294     // so that dispatch of foreground broadcasts gets precedence.
295     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
296
297     BroadcastQueue broadcastQueueForIntent(Intent intent) {
298         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
299         if (DEBUG_BACKGROUND_BROADCAST) {
300             Slog.i(TAG, "Broadcast intent " + intent + " on "
301                     + (isFg ? "foreground" : "background")
302                     + " queue");
303         }
304         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
305     }
306
307     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
308         for (BroadcastQueue queue : mBroadcastQueues) {
309             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
310             if (r != null) {
311                 return r;
312             }
313         }
314         return null;
315     }
316
317     /**
318      * Activity we have told the window manager to have key focus.
319      */
320     ActivityRecord mFocusedActivity = null;
321     /**
322      * List of intents that were used to start the most recent tasks.
323      */
324     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
325
326     /**
327      * Process management.
328      */
329     final ProcessList mProcessList = new ProcessList();
330
331     /**
332      * All of the applications we currently have running organized by name.
333      * The keys are strings of the application package name (as
334      * returned by the package manager), and the keys are ApplicationRecord
335      * objects.
336      */
337     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
338
339     /**
340      * The currently running isolated processes.
341      */
342     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
343
344     /**
345      * Counter for assigning isolated process uids, to avoid frequently reusing the
346      * same ones.
347      */
348     int mNextIsolatedProcessUid = 0;
349
350     /**
351      * The currently running heavy-weight process, if any.
352      */
353     ProcessRecord mHeavyWeightProcess = null;
354     
355     /**
356      * The last time that various processes have crashed.
357      */
358     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
359
360     /**
361      * Set of applications that we consider to be bad, and will reject
362      * incoming broadcasts from (which the user has no control over).
363      * Processes are added to this set when they have crashed twice within
364      * a minimum amount of time; they are removed from it when they are
365      * later restarted (hopefully due to some user action).  The value is the
366      * time it was added to the list.
367      */
368     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
369
370     /**
371      * All of the processes we currently have running organized by pid.
372      * The keys are the pid running the application.
373      *
374      * <p>NOTE: This object is protected by its own lock, NOT the global
375      * activity manager lock!
376      */
377     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
378
379     /**
380      * All of the processes that have been forced to be foreground.  The key
381      * is the pid of the caller who requested it (we hold a death
382      * link on it).
383      */
384     abstract class ForegroundToken implements IBinder.DeathRecipient {
385         int pid;
386         IBinder token;
387     }
388     final SparseArray<ForegroundToken> mForegroundProcesses
389             = new SparseArray<ForegroundToken>();
390     
391     /**
392      * List of records for processes that someone had tried to start before the
393      * system was ready.  We don't start them at that point, but ensure they
394      * are started by the time booting is complete.
395      */
396     final ArrayList<ProcessRecord> mProcessesOnHold
397             = new ArrayList<ProcessRecord>();
398
399     /**
400      * List of persistent applications that are in the process
401      * of being started.
402      */
403     final ArrayList<ProcessRecord> mPersistentStartingProcesses
404             = new ArrayList<ProcessRecord>();
405
406     /**
407      * Processes that are being forcibly torn down.
408      */
409     final ArrayList<ProcessRecord> mRemovedProcesses
410             = new ArrayList<ProcessRecord>();
411
412     /**
413      * List of running applications, sorted by recent usage.
414      * The first entry in the list is the least recently used.
415      * It contains ApplicationRecord objects.  This list does NOT include
416      * any persistent application records (since we never want to exit them).
417      */
418     final ArrayList<ProcessRecord> mLruProcesses
419             = new ArrayList<ProcessRecord>();
420
421     /**
422      * List of processes that should gc as soon as things are idle.
423      */
424     final ArrayList<ProcessRecord> mProcessesToGc
425             = new ArrayList<ProcessRecord>();
426
427     /**
428      * This is the process holding what we currently consider to be
429      * the "home" activity.
430      */
431     ProcessRecord mHomeProcess;
432     
433     /**
434      * This is the process holding the activity the user last visited that
435      * is in a different process from the one they are currently in.
436      */
437     ProcessRecord mPreviousProcess;
438
439     /**
440      * The time at which the previous process was last visible.
441      */
442     long mPreviousProcessVisibleTime;
443
444     /**
445      * Which uses have been started, so are allowed to run code.
446      */
447     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
448
449     /**
450      * LRU list of history of current users.  Most recently current is at the end.
451      */
452     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
453
454     /**
455      * Constant array of the users that are currently started.
456      */
457     int[] mStartedUserArray = new int[] { 0 };
458
459     /**
460      * Registered observers of the user switching mechanics.
461      */
462     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
463             = new RemoteCallbackList<IUserSwitchObserver>();
464
465     /**
466      * Currently active user switch.
467      */
468     Object mCurUserSwitchCallback;
469
470     /**
471      * Packages that the user has asked to have run in screen size
472      * compatibility mode instead of filling the screen.
473      */
474     final CompatModePackages mCompatModePackages;
475
476     /**
477      * Set of PendingResultRecord objects that are currently active.
478      */
479     final HashSet mPendingResultRecords = new HashSet();
480
481     /**
482      * Set of IntentSenderRecord objects that are currently active.
483      */
484     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
485             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
486
487     /**
488      * Fingerprints (hashCode()) of stack traces that we've
489      * already logged DropBox entries for.  Guarded by itself.  If
490      * something (rogue user app) forces this over
491      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
492      */
493     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
494     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
495
496     /**
497      * Strict Mode background batched logging state.
498      *
499      * The string buffer is guarded by itself, and its lock is also
500      * used to determine if another batched write is already
501      * in-flight.
502      */
503     private final StringBuilder mStrictModeBuffer = new StringBuilder();
504
505     /**
506      * Keeps track of all IIntentReceivers that have been registered for
507      * broadcasts.  Hash keys are the receiver IBinder, hash value is
508      * a ReceiverList.
509      */
510     final HashMap mRegisteredReceivers = new HashMap();
511
512     /**
513      * Resolver for broadcast intents to registered receivers.
514      * Holds BroadcastFilter (subclass of IntentFilter).
515      */
516     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
517             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
518         @Override
519         protected boolean allowFilterResult(
520                 BroadcastFilter filter, List<BroadcastFilter> dest) {
521             IBinder target = filter.receiverList.receiver.asBinder();
522             for (int i=dest.size()-1; i>=0; i--) {
523                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
524                     return false;
525                 }
526             }
527             return true;
528         }
529
530         @Override
531         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
532             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
533                     || userId == filter.owningUserId) {
534                 return super.newResult(filter, match, userId);
535             }
536             return null;
537         }
538
539         @Override
540         protected BroadcastFilter[] newArray(int size) {
541             return new BroadcastFilter[size];
542         }
543
544         @Override
545         protected String packageForFilter(BroadcastFilter filter) {
546             return filter.packageName;
547         }
548     };
549
550     /**
551      * State of all active sticky broadcasts per user.  Keys are the action of the
552      * sticky Intent, values are an ArrayList of all broadcasted intents with
553      * that action (which should usually be one).  The SparseArray is keyed
554      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
555      * for stickies that are sent to all users.
556      */
557     final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
558             new SparseArray<HashMap<String, ArrayList<Intent>>>();
559
560     final ActiveServices mServices;
561
562     /**
563      * Backup/restore process management
564      */
565     String mBackupAppName = null;
566     BackupRecord mBackupTarget = null;
567
568     /**
569      * List of PendingThumbnailsRecord objects of clients who are still
570      * waiting to receive all of the thumbnails for a task.
571      */
572     final ArrayList mPendingThumbnails = new ArrayList();
573
574     /**
575      * List of HistoryRecord objects that have been finished and must
576      * still report back to a pending thumbnail receiver.
577      */
578     final ArrayList mCancelledThumbnails = new ArrayList();
579
580     final ProviderMap mProviderMap;
581
582     /**
583      * List of content providers who have clients waiting for them.  The
584      * application is currently being launched and the provider will be
585      * removed from this list once it is published.
586      */
587     final ArrayList<ContentProviderRecord> mLaunchingProviders
588             = new ArrayList<ContentProviderRecord>();
589
590     /**
591      * Global set of specific Uri permissions that have been granted.
592      */
593     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
594             = new SparseArray<HashMap<Uri, UriPermission>>();
595
596     CoreSettingsObserver mCoreSettingsObserver;
597
598     /**
599      * Thread-local storage used to carry caller permissions over through
600      * indirect content-provider access.
601      * @see #ActivityManagerService.openContentUri()
602      */
603     private class Identity {
604         public int pid;
605         public int uid;
606
607         Identity(int _pid, int _uid) {
608             pid = _pid;
609             uid = _uid;
610         }
611     }
612
613     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
614
615     /**
616      * All information we have collected about the runtime performance of
617      * any user id that can impact battery performance.
618      */
619     final BatteryStatsService mBatteryStatsService;
620     
621     /**
622      * information about component usage
623      */
624     final UsageStatsService mUsageStatsService;
625
626     /**
627      * Current configuration information.  HistoryRecord objects are given
628      * a reference to this object to indicate which configuration they are
629      * currently running in, so this object must be kept immutable.
630      */
631     Configuration mConfiguration = new Configuration();
632
633     /**
634      * Current sequencing integer of the configuration, for skipping old
635      * configurations.
636      */
637     int mConfigurationSeq = 0;
638     
639     /**
640      * Hardware-reported OpenGLES version.
641      */
642     final int GL_ES_VERSION;
643
644     /**
645      * List of initialization arguments to pass to all processes when binding applications to them.
646      * For example, references to the commonly used services.
647      */
648     HashMap<String, IBinder> mAppBindArgs;
649
650     /**
651      * Temporary to avoid allocations.  Protected by main lock.
652      */
653     final StringBuilder mStringBuilder = new StringBuilder(256);
654     
655     /**
656      * Used to control how we initialize the service.
657      */
658     boolean mStartRunning = false;
659     ComponentName mTopComponent;
660     String mTopAction;
661     String mTopData;
662     boolean mProcessesReady = false;
663     boolean mSystemReady = false;
664     boolean mBooting = false;
665     boolean mWaitingUpdate = false;
666     boolean mDidUpdate = false;
667     boolean mOnBattery = false;
668     boolean mLaunchWarningShown = false;
669
670     Context mContext;
671
672     int mFactoryTest;
673
674     boolean mCheckedForSetup;
675     
676     /**
677      * The time at which we will allow normal application switches again,
678      * after a call to {@link #stopAppSwitches()}.
679      */
680     long mAppSwitchesAllowedTime;
681
682     /**
683      * This is set to true after the first switch after mAppSwitchesAllowedTime
684      * is set; any switches after that will clear the time.
685      */
686     boolean mDidAppSwitch;
687     
688     /**
689      * Last time (in realtime) at which we checked for power usage.
690      */
691     long mLastPowerCheckRealtime;
692
693     /**
694      * Last time (in uptime) at which we checked for power usage.
695      */
696     long mLastPowerCheckUptime;
697
698     /**
699      * Set while we are wanting to sleep, to prevent any
700      * activities from being started/resumed.
701      */
702     boolean mSleeping = false;
703
704     /**
705      * State of external calls telling us if the device is asleep.
706      */
707     boolean mWentToSleep = false;
708
709     /**
710      * State of external call telling us if the lock screen is shown.
711      */
712     boolean mLockScreenShown = false;
713
714     /**
715      * Set if we are shutting down the system, similar to sleeping.
716      */
717     boolean mShuttingDown = false;
718
719     /**
720      * Task identifier that activities are currently being started
721      * in.  Incremented each time a new task is created.
722      * todo: Replace this with a TokenSpace class that generates non-repeating
723      * integers that won't wrap.
724      */
725     int mCurTask = 1;
726
727     /**
728      * Current sequence id for oom_adj computation traversal.
729      */
730     int mAdjSeq = 0;
731
732     /**
733      * Current sequence id for process LRU updating.
734      */
735     int mLruSeq = 0;
736
737     /**
738      * Keep track of the non-hidden/empty process we last found, to help
739      * determine how to distribute hidden/empty processes next time.
740      */
741     int mNumNonHiddenProcs = 0;
742
743     /**
744      * Keep track of the number of hidden procs, to balance oom adj
745      * distribution between those and empty procs.
746      */
747     int mNumHiddenProcs = 0;
748
749     /**
750      * Keep track of the number of service processes we last found, to
751      * determine on the next iteration which should be B services.
752      */
753     int mNumServiceProcs = 0;
754     int mNewNumServiceProcs = 0;
755
756     /**
757      * System monitoring: number of processes that died since the last
758      * N procs were started.
759      */
760     int[] mProcDeaths = new int[20];
761     
762     /**
763      * This is set if we had to do a delayed dexopt of an app before launching
764      * it, to increasing the ANR timeouts in that case.
765      */
766     boolean mDidDexOpt;
767     
768     String mDebugApp = null;
769     boolean mWaitForDebugger = false;
770     boolean mDebugTransient = false;
771     String mOrigDebugApp = null;
772     boolean mOrigWaitForDebugger = false;
773     boolean mAlwaysFinishActivities = false;
774     IActivityController mController = null;
775     String mProfileApp = null;
776     ProcessRecord mProfileProc = null;
777     String mProfileFile;
778     ParcelFileDescriptor mProfileFd;
779     int mProfileType = 0;
780     boolean mAutoStopProfiler = false;
781     String mOpenGlTraceApp = null;
782
783     static class ProcessChangeItem {
784         static final int CHANGE_ACTIVITIES = 1<<0;
785         static final int CHANGE_IMPORTANCE= 1<<1;
786         int changes;
787         int uid;
788         int pid;
789         int importance;
790         boolean foregroundActivities;
791     }
792
793     final RemoteCallbackList<IProcessObserver> mProcessObservers
794             = new RemoteCallbackList<IProcessObserver>();
795     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
796
797     final ArrayList<ProcessChangeItem> mPendingProcessChanges
798             = new ArrayList<ProcessChangeItem>();
799     final ArrayList<ProcessChangeItem> mAvailProcessChanges
800             = new ArrayList<ProcessChangeItem>();
801
802     /**
803      * Callback of last caller to {@link #requestPss}.
804      */
805     Runnable mRequestPssCallback;
806
807     /**
808      * Remaining processes for which we are waiting results from the last
809      * call to {@link #requestPss}.
810      */
811     final ArrayList<ProcessRecord> mRequestPssList
812             = new ArrayList<ProcessRecord>();
813     
814     /**
815      * Runtime statistics collection thread.  This object's lock is used to
816      * protect all related state.
817      */
818     final Thread mProcessStatsThread;
819     
820     /**
821      * Used to collect process stats when showing not responding dialog.
822      * Protected by mProcessStatsThread.
823      */
824     final ProcessStats mProcessStats = new ProcessStats(
825             MONITOR_THREAD_CPU_USAGE);
826     final AtomicLong mLastCpuTime = new AtomicLong(0);
827     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
828
829     long mLastWriteTime = 0;
830
831     /**
832      * Used to retain an update lock when the foreground activity is in
833      * immersive mode.
834      */
835     final UpdateLock mUpdateLock = new UpdateLock("immersive");
836
837     /**
838      * Set to true after the system has finished booting.
839      */
840     boolean mBooted = false;
841
842     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
843     int mProcessLimitOverride = -1;
844
845     WindowManagerService mWindowManager;
846
847     static ActivityManagerService mSelf;
848     static ActivityThread mSystemThread;
849
850     private int mCurrentUserId = 0;
851     private int[] mCurrentUserArray = new int[] { 0 };
852     private UserManagerService mUserManager;
853
854     private final class AppDeathRecipient implements IBinder.DeathRecipient {
855         final ProcessRecord mApp;
856         final int mPid;
857         final IApplicationThread mAppThread;
858
859         AppDeathRecipient(ProcessRecord app, int pid,
860                 IApplicationThread thread) {
861             if (localLOGV) Slog.v(
862                 TAG, "New death recipient " + this
863                 + " for thread " + thread.asBinder());
864             mApp = app;
865             mPid = pid;
866             mAppThread = thread;
867         }
868
869         public void binderDied() {
870             if (localLOGV) Slog.v(
871                 TAG, "Death received in " + this
872                 + " for thread " + mAppThread.asBinder());
873             synchronized(ActivityManagerService.this) {
874                 appDiedLocked(mApp, mPid, mAppThread);
875             }
876         }
877     }
878
879     static final int SHOW_ERROR_MSG = 1;
880     static final int SHOW_NOT_RESPONDING_MSG = 2;
881     static final int SHOW_FACTORY_ERROR_MSG = 3;
882     static final int UPDATE_CONFIGURATION_MSG = 4;
883     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
884     static final int WAIT_FOR_DEBUGGER_MSG = 6;
885     static final int SERVICE_TIMEOUT_MSG = 12;
886     static final int UPDATE_TIME_ZONE = 13;
887     static final int SHOW_UID_ERROR_MSG = 14;
888     static final int IM_FEELING_LUCKY_MSG = 15;
889     static final int PROC_START_TIMEOUT_MSG = 20;
890     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
891     static final int KILL_APPLICATION_MSG = 22;
892     static final int FINALIZE_PENDING_INTENT_MSG = 23;
893     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
894     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
895     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
896     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
897     static final int CLEAR_DNS_CACHE = 28;
898     static final int UPDATE_HTTP_PROXY = 29;
899     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
900     static final int DISPATCH_PROCESSES_CHANGED = 31;
901     static final int DISPATCH_PROCESS_DIED = 32;
902     static final int REPORT_MEM_USAGE = 33;
903     static final int REPORT_USER_SWITCH_MSG = 34;
904     static final int CONTINUE_USER_SWITCH_MSG = 35;
905     static final int USER_SWITCH_TIMEOUT_MSG = 36;
906     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
907
908     static final int FIRST_ACTIVITY_STACK_MSG = 100;
909     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
910     static final int FIRST_COMPAT_MODE_MSG = 300;
911
912     AlertDialog mUidAlert;
913     CompatModeDialog mCompatModeDialog;
914     long mLastMemUsageReportTime = 0;
915
916     final Handler mHandler = new Handler() {
917         //public Handler() {
918         //    if (localLOGV) Slog.v(TAG, "Handler started!");
919         //}
920
921         public void handleMessage(Message msg) {
922             switch (msg.what) {
923             case SHOW_ERROR_MSG: {
924                 HashMap data = (HashMap) msg.obj;
925                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
926                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
927                 synchronized (ActivityManagerService.this) {
928                     ProcessRecord proc = (ProcessRecord)data.get("app");
929                     AppErrorResult res = (AppErrorResult) data.get("result");
930                     if (proc != null && proc.crashDialog != null) {
931                         Slog.e(TAG, "App already has crash dialog: " + proc);
932                         if (res != null) {
933                             res.set(0);
934                         }
935                         return;
936                     }
937                     if (!showBackground && UserHandle.getAppId(proc.uid)
938                             >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
939                             && proc.pid != MY_PID) {
940                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
941                         if (res != null) {
942                             res.set(0);
943                         }
944                         return;
945                     }
946                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
947                         Dialog d = new AppErrorDialog(mContext,
948                                 ActivityManagerService.this, res, proc);
949                         d.show();
950                         proc.crashDialog = d;
951                     } else {
952                         // The device is asleep, so just pretend that the user
953                         // saw a crash dialog and hit "force quit".
954                         if (res != null) {
955                             res.set(0);
956                         }
957                     }
958                 }
959                 
960                 ensureBootCompleted();
961             } break;
962             case SHOW_NOT_RESPONDING_MSG: {
963                 synchronized (ActivityManagerService.this) {
964                     HashMap data = (HashMap) msg.obj;
965                     ProcessRecord proc = (ProcessRecord)data.get("app");
966                     if (proc != null && proc.anrDialog != null) {
967                         Slog.e(TAG, "App already has anr dialog: " + proc);
968                         return;
969                     }
970                     
971                     Intent intent = new Intent("android.intent.action.ANR");
972                     if (!mProcessesReady) {
973                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
974                                 | Intent.FLAG_RECEIVER_FOREGROUND);
975                     }
976                     broadcastIntentLocked(null, null, intent,
977                             null, null, 0, null, null, null,
978                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
979
980                     if (mShowDialogs) {
981                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
982                                 mContext, proc, (ActivityRecord)data.get("activity"),
983                                 msg.arg1 != 0);
984                         d.show();
985                         proc.anrDialog = d;
986                     } else {
987                         // Just kill the app if there is no dialog to be shown.
988                         killAppAtUsersRequest(proc, null);
989                     }
990                 }
991                 
992                 ensureBootCompleted();
993             } break;
994             case SHOW_STRICT_MODE_VIOLATION_MSG: {
995                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
996                 synchronized (ActivityManagerService.this) {
997                     ProcessRecord proc = (ProcessRecord) data.get("app");
998                     if (proc == null) {
999                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1000                         break;
1001                     }
1002                     if (proc.crashDialog != null) {
1003                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1004                         return;
1005                     }
1006                     AppErrorResult res = (AppErrorResult) data.get("result");
1007                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1008                         Dialog d = new StrictModeViolationDialog(mContext,
1009                                 ActivityManagerService.this, res, proc);
1010                         d.show();
1011                         proc.crashDialog = d;
1012                     } else {
1013                         // The device is asleep, so just pretend that the user
1014                         // saw a crash dialog and hit "force quit".
1015                         res.set(0);
1016                     }
1017                 }
1018                 ensureBootCompleted();
1019             } break;
1020             case SHOW_FACTORY_ERROR_MSG: {
1021                 Dialog d = new FactoryErrorDialog(
1022                     mContext, msg.getData().getCharSequence("msg"));
1023                 d.show();
1024                 ensureBootCompleted();
1025             } break;
1026             case UPDATE_CONFIGURATION_MSG: {
1027                 final ContentResolver resolver = mContext.getContentResolver();
1028                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1029             } break;
1030             case GC_BACKGROUND_PROCESSES_MSG: {
1031                 synchronized (ActivityManagerService.this) {
1032                     performAppGcsIfAppropriateLocked();
1033                 }
1034             } break;
1035             case WAIT_FOR_DEBUGGER_MSG: {
1036                 synchronized (ActivityManagerService.this) {
1037                     ProcessRecord app = (ProcessRecord)msg.obj;
1038                     if (msg.arg1 != 0) {
1039                         if (!app.waitedForDebugger) {
1040                             Dialog d = new AppWaitingForDebuggerDialog(
1041                                     ActivityManagerService.this,
1042                                     mContext, app);
1043                             app.waitDialog = d;
1044                             app.waitedForDebugger = true;
1045                             d.show();
1046                         }
1047                     } else {
1048                         if (app.waitDialog != null) {
1049                             app.waitDialog.dismiss();
1050                             app.waitDialog = null;
1051                         }
1052                     }
1053                 }
1054             } break;
1055             case SERVICE_TIMEOUT_MSG: {
1056                 if (mDidDexOpt) {
1057                     mDidDexOpt = false;
1058                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1059                     nmsg.obj = msg.obj;
1060                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1061                     return;
1062                 }
1063                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1064             } break;
1065             case UPDATE_TIME_ZONE: {
1066                 synchronized (ActivityManagerService.this) {
1067                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1068                         ProcessRecord r = mLruProcesses.get(i);
1069                         if (r.thread != null) {
1070                             try {
1071                                 r.thread.updateTimeZone();
1072                             } catch (RemoteException ex) {
1073                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1074                             }
1075                         }
1076                     }
1077                 }
1078             } break;
1079             case CLEAR_DNS_CACHE: {
1080                 synchronized (ActivityManagerService.this) {
1081                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1082                         ProcessRecord r = mLruProcesses.get(i);
1083                         if (r.thread != null) {
1084                             try {
1085                                 r.thread.clearDnsCache();
1086                             } catch (RemoteException ex) {
1087                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1088                             }
1089                         }
1090                     }
1091                 }
1092             } break;
1093             case UPDATE_HTTP_PROXY: {
1094                 ProxyProperties proxy = (ProxyProperties)msg.obj;
1095                 String host = "";
1096                 String port = "";
1097                 String exclList = "";
1098                 if (proxy != null) {
1099                     host = proxy.getHost();
1100                     port = Integer.toString(proxy.getPort());
1101                     exclList = proxy.getExclusionList();
1102                 }
1103                 synchronized (ActivityManagerService.this) {
1104                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1105                         ProcessRecord r = mLruProcesses.get(i);
1106                         if (r.thread != null) {
1107                             try {
1108                                 r.thread.setHttpProxy(host, port, exclList);
1109                             } catch (RemoteException ex) {
1110                                 Slog.w(TAG, "Failed to update http proxy for: " +
1111                                         r.info.processName);
1112                             }
1113                         }
1114                     }
1115                 }
1116             } break;
1117             case SHOW_UID_ERROR_MSG: {
1118                 String title = "System UIDs Inconsistent";
1119                 String text = "UIDs on the system are inconsistent, you need to wipe your"
1120                         + " data partition or your device will be unstable.";
1121                 Log.e(TAG, title + ": " + text);
1122                 if (mShowDialogs) {
1123                     // XXX This is a temporary dialog, no need to localize.
1124                     AlertDialog d = new BaseErrorDialog(mContext);
1125                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1126                     d.setCancelable(false);
1127                     d.setTitle(title);
1128                     d.setMessage(text);
1129                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1130                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1131                     mUidAlert = d;
1132                     d.show();
1133                 }
1134             } break;
1135             case IM_FEELING_LUCKY_MSG: {
1136                 if (mUidAlert != null) {
1137                     mUidAlert.dismiss();
1138                     mUidAlert = null;
1139                 }
1140             } break;
1141             case PROC_START_TIMEOUT_MSG: {
1142                 if (mDidDexOpt) {
1143                     mDidDexOpt = false;
1144                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1145                     nmsg.obj = msg.obj;
1146                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1147                     return;
1148                 }
1149                 ProcessRecord app = (ProcessRecord)msg.obj;
1150                 synchronized (ActivityManagerService.this) {
1151                     processStartTimedOutLocked(app);
1152                 }
1153             } break;
1154             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1155                 synchronized (ActivityManagerService.this) {
1156                     doPendingActivityLaunchesLocked(true);
1157                 }
1158             } break;
1159             case KILL_APPLICATION_MSG: {
1160                 synchronized (ActivityManagerService.this) {
1161                     int appid = msg.arg1;
1162                     boolean restart = (msg.arg2 == 1);
1163                     String pkg = (String) msg.obj;
1164                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1165                             UserHandle.USER_ALL);
1166                 }
1167             } break;
1168             case FINALIZE_PENDING_INTENT_MSG: {
1169                 ((PendingIntentRecord)msg.obj).completeFinalize();
1170             } break;
1171             case POST_HEAVY_NOTIFICATION_MSG: {
1172                 INotificationManager inm = NotificationManager.getService();
1173                 if (inm == null) {
1174                     return;
1175                 }
1176                 
1177                 ActivityRecord root = (ActivityRecord)msg.obj;
1178                 ProcessRecord process = root.app;
1179                 if (process == null) {
1180                     return;
1181                 }
1182                 
1183                 try {
1184                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1185                     String text = mContext.getString(R.string.heavy_weight_notification,
1186                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1187                     Notification notification = new Notification();
1188                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1189                     notification.when = 0;
1190                     notification.flags = Notification.FLAG_ONGOING_EVENT;
1191                     notification.tickerText = text;
1192                     notification.defaults = 0; // please be quiet
1193                     notification.sound = null;
1194                     notification.vibrate = null;
1195                     notification.setLatestEventInfo(context, text,
1196                             mContext.getText(R.string.heavy_weight_notification_detail),
1197                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1198                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
1199                                     new UserHandle(root.userId)));
1200                     
1201                     try {
1202                         int[] outId = new int[1];
1203                         inm.enqueueNotificationWithTag("android", null,
1204                                 R.string.heavy_weight_notification,
1205                                 notification, outId, root.userId);
1206                     } catch (RuntimeException e) {
1207                         Slog.w(ActivityManagerService.TAG,
1208                                 "Error showing notification for heavy-weight app", e);
1209                     } catch (RemoteException e) {
1210                     }
1211                 } catch (NameNotFoundException e) {
1212                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1213                 }
1214             } break;
1215             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1216                 INotificationManager inm = NotificationManager.getService();
1217                 if (inm == null) {
1218                     return;
1219                 }
1220                 try {
1221                     inm.cancelNotificationWithTag("android", null,
1222                             R.string.heavy_weight_notification,  msg.arg1);
1223                 } catch (RuntimeException e) {
1224                     Slog.w(ActivityManagerService.TAG,
1225                             "Error canceling notification for service", e);
1226                 } catch (RemoteException e) {
1227                 }
1228             } break;
1229             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1230                 synchronized (ActivityManagerService.this) {
1231                     checkExcessivePowerUsageLocked(true);
1232                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1233                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1234                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1235                 }
1236             } break;
1237             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1238                 synchronized (ActivityManagerService.this) {
1239                     ActivityRecord ar = (ActivityRecord)msg.obj;
1240                     if (mCompatModeDialog != null) {
1241                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1242                                 ar.info.applicationInfo.packageName)) {
1243                             return;
1244                         }
1245                         mCompatModeDialog.dismiss();
1246                         mCompatModeDialog = null;
1247                     }
1248                     if (ar != null && false) {
1249                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1250                                 ar.packageName)) {
1251                             int mode = mCompatModePackages.computeCompatModeLocked(
1252                                     ar.info.applicationInfo);
1253                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1254                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1255                                 mCompatModeDialog = new CompatModeDialog(
1256                                         ActivityManagerService.this, mContext,
1257                                         ar.info.applicationInfo);
1258                                 mCompatModeDialog.show();
1259                             }
1260                         }
1261                     }
1262                 }
1263                 break;
1264             }
1265             case DISPATCH_PROCESSES_CHANGED: {
1266                 dispatchProcessesChanged();
1267                 break;
1268             }
1269             case DISPATCH_PROCESS_DIED: {
1270                 final int pid = msg.arg1;
1271                 final int uid = msg.arg2;
1272                 dispatchProcessDied(pid, uid);
1273                 break;
1274             }
1275             case REPORT_MEM_USAGE: {
1276                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1277                 if (!isDebuggable) {
1278                     return;
1279                 }
1280                 synchronized (ActivityManagerService.this) {
1281                     long now = SystemClock.uptimeMillis();
1282                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
1283                         // Don't report more than every 5 minutes to somewhat
1284                         // avoid spamming.
1285                         return;
1286                     }
1287                     mLastMemUsageReportTime = now;
1288                 }
1289                 Thread thread = new Thread() {
1290                     @Override public void run() {
1291                         StringBuilder dropBuilder = new StringBuilder(1024);
1292                         StringBuilder logBuilder = new StringBuilder(1024);
1293                         StringWriter oomSw = new StringWriter();
1294                         PrintWriter oomPw = new PrintWriter(oomSw);
1295                         StringWriter catSw = new StringWriter();
1296                         PrintWriter catPw = new PrintWriter(catSw);
1297                         String[] emptyArgs = new String[] { };
1298                         StringBuilder tag = new StringBuilder(128);
1299                         StringBuilder stack = new StringBuilder(128);
1300                         tag.append("Low on memory -- ");
1301                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1302                                 tag, stack);
1303                         dropBuilder.append(stack);
1304                         dropBuilder.append('\n');
1305                         dropBuilder.append('\n');
1306                         String oomString = oomSw.toString();
1307                         dropBuilder.append(oomString);
1308                         dropBuilder.append('\n');
1309                         logBuilder.append(oomString);
1310                         try {
1311                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1312                                     "procrank", });
1313                             final InputStreamReader converter = new InputStreamReader(
1314                                     proc.getInputStream());
1315                             BufferedReader in = new BufferedReader(converter);
1316                             String line;
1317                             while (true) {
1318                                 line = in.readLine();
1319                                 if (line == null) {
1320                                     break;
1321                                 }
1322                                 if (line.length() > 0) {
1323                                     logBuilder.append(line);
1324                                     logBuilder.append('\n');
1325                                 }
1326                                 dropBuilder.append(line);
1327                                 dropBuilder.append('\n');
1328                             }
1329                             converter.close();
1330                         } catch (IOException e) {
1331                         }
1332                         synchronized (ActivityManagerService.this) {
1333                             catPw.println();
1334                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1335                             catPw.println();
1336                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1337                                     false, false, null);
1338                             catPw.println();
1339                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1340                         }
1341                         dropBuilder.append(catSw.toString());
1342                         addErrorToDropBox("lowmem", null, "system_server", null,
1343                                 null, tag.toString(), dropBuilder.toString(), null, null);
1344                         Slog.i(TAG, logBuilder.toString());
1345                         synchronized (ActivityManagerService.this) {
1346                             long now = SystemClock.uptimeMillis();
1347                             if (mLastMemUsageReportTime < now) {
1348                                 mLastMemUsageReportTime = now;
1349                             }
1350                         }
1351                     }
1352                 };
1353                 thread.start();
1354                 break;
1355             }
1356             case REPORT_USER_SWITCH_MSG: {
1357                 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1358                 break;
1359             }
1360             case CONTINUE_USER_SWITCH_MSG: {
1361                 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1362                 break;
1363             }
1364             case USER_SWITCH_TIMEOUT_MSG: {
1365                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1366                 break;
1367             }
1368             case IMMERSIVE_MODE_LOCK_MSG: {
1369                 final boolean nextState = (msg.arg1 != 0);
1370                 if (mUpdateLock.isHeld() != nextState) {
1371                     if (DEBUG_IMMERSIVE) {
1372                         final ActivityRecord r = (ActivityRecord) msg.obj;
1373                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1374                     }
1375                     if (nextState) {
1376                         mUpdateLock.acquire();
1377                     } else {
1378                         mUpdateLock.release();
1379                     }
1380                 }
1381                 break;
1382             }
1383             }
1384         }
1385     };
1386
1387     public static void setSystemProcess() {
1388         try {
1389             ActivityManagerService m = mSelf;
1390             
1391             ServiceManager.addService("activity", m, true);
1392             ServiceManager.addService("meminfo", new MemBinder(m));
1393             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1394             ServiceManager.addService("dbinfo", new DbBinder(m));
1395             if (MONITOR_CPU_USAGE) {
1396                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1397             }
1398             ServiceManager.addService("permission", new PermissionController(m));
1399
1400             ApplicationInfo info =
1401                 mSelf.mContext.getPackageManager().getApplicationInfo(
1402                             "android", STOCK_PM_FLAGS);
1403             mSystemThread.installSystemApplicationInfo(info);
1404        
1405             synchronized (mSelf) {
1406                 ProcessRecord app = mSelf.newProcessRecordLocked(
1407                         mSystemThread.getApplicationThread(), info,
1408                         info.processName, false);
1409                 app.persistent = true;
1410                 app.pid = MY_PID;
1411                 app.maxAdj = ProcessList.SYSTEM_ADJ;
1412                 mSelf.mProcessNames.put(app.processName, app.uid, app);
1413                 synchronized (mSelf.mPidsSelfLocked) {
1414                     mSelf.mPidsSelfLocked.put(app.pid, app);
1415                 }
1416                 mSelf.updateLruProcessLocked(app, true);
1417             }
1418         } catch (PackageManager.NameNotFoundException e) {
1419             throw new RuntimeException(
1420                     "Unable to find android system package", e);
1421         }
1422     }
1423
1424     public void setWindowManager(WindowManagerService wm) {
1425         mWindowManager = wm;
1426     }
1427
1428     public static final Context main(int factoryTest) {
1429         AThread thr = new AThread();
1430         thr.start();
1431
1432         synchronized (thr) {
1433             while (thr.mService == null) {
1434                 try {
1435                     thr.wait();
1436                 } catch (InterruptedException e) {
1437                 }
1438             }
1439         }
1440
1441         ActivityManagerService m = thr.mService;
1442         mSelf = m;
1443         ActivityThread at = ActivityThread.systemMain();
1444         mSystemThread = at;
1445         Context context = at.getSystemContext();
1446         context.setTheme(android.R.style.Theme_Holo);
1447         m.mContext = context;
1448         m.mFactoryTest = factoryTest;
1449         m.mMainStack = new ActivityStack(m, context, true);
1450         
1451         m.mBatteryStatsService.publish(context);
1452         m.mUsageStatsService.publish(context);
1453         
1454         synchronized (thr) {
1455             thr.mReady = true;
1456             thr.notifyAll();
1457         }
1458
1459         m.startRunning(null, null, null, null);
1460         
1461         return context;
1462     }
1463
1464     public static ActivityManagerService self() {
1465         return mSelf;
1466     }
1467     
1468     static class AThread extends Thread {
1469         ActivityManagerService mService;
1470         boolean mReady = false;
1471
1472         public AThread() {
1473             super("ActivityManager");
1474         }
1475
1476         public void run() {
1477             Looper.prepare();
1478
1479             android.os.Process.setThreadPriority(
1480                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
1481             android.os.Process.setCanSelfBackground(false);
1482
1483             ActivityManagerService m = new ActivityManagerService();
1484
1485             synchronized (this) {
1486                 mService = m;
1487                 notifyAll();
1488             }
1489
1490             synchronized (this) {
1491                 while (!mReady) {
1492                     try {
1493                         wait();
1494                     } catch (InterruptedException e) {
1495                     }
1496                 }
1497             }
1498
1499             // For debug builds, log event loop stalls to dropbox for analysis.
1500             if (StrictMode.conditionallyEnableDebugLogging()) {
1501                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1502             }
1503
1504             Looper.loop();
1505         }
1506     }
1507
1508     static class MemBinder extends Binder {
1509         ActivityManagerService mActivityManagerService;
1510         MemBinder(ActivityManagerService activityManagerService) {
1511             mActivityManagerService = activityManagerService;
1512         }
1513
1514         @Override
1515         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1516             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1517                     != PackageManager.PERMISSION_GRANTED) {
1518                 pw.println("Permission Denial: can't dump meminfo from from pid="
1519                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1520                         + " without permission " + android.Manifest.permission.DUMP);
1521                 return;
1522             }
1523
1524             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1525                     false, null, null, null);
1526         }
1527     }
1528
1529     static class GraphicsBinder extends Binder {
1530         ActivityManagerService mActivityManagerService;
1531         GraphicsBinder(ActivityManagerService activityManagerService) {
1532             mActivityManagerService = activityManagerService;
1533         }
1534
1535         @Override
1536         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1537             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1538                     != PackageManager.PERMISSION_GRANTED) {
1539                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1540                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1541                         + " without permission " + android.Manifest.permission.DUMP);
1542                 return;
1543             }
1544
1545             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1546         }
1547     }
1548
1549     static class DbBinder extends Binder {
1550         ActivityManagerService mActivityManagerService;
1551         DbBinder(ActivityManagerService activityManagerService) {
1552             mActivityManagerService = activityManagerService;
1553         }
1554
1555         @Override
1556         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1557             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1558                     != PackageManager.PERMISSION_GRANTED) {
1559                 pw.println("Permission Denial: can't dump dbinfo from from pid="
1560                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1561                         + " without permission " + android.Manifest.permission.DUMP);
1562                 return;
1563             }
1564
1565             mActivityManagerService.dumpDbInfo(fd, pw, args);
1566         }
1567     }
1568
1569     static class CpuBinder extends Binder {
1570         ActivityManagerService mActivityManagerService;
1571         CpuBinder(ActivityManagerService activityManagerService) {
1572             mActivityManagerService = activityManagerService;
1573         }
1574
1575         @Override
1576         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1577             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1578                     != PackageManager.PERMISSION_GRANTED) {
1579                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1580                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1581                         + " without permission " + android.Manifest.permission.DUMP);
1582                 return;
1583             }
1584
1585             synchronized (mActivityManagerService.mProcessStatsThread) {
1586                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1587                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1588                         SystemClock.uptimeMillis()));
1589             }
1590         }
1591     }
1592
1593     private ActivityManagerService() {
1594         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1595         
1596         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1597         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1598         mBroadcastQueues[0] = mFgBroadcastQueue;
1599         mBroadcastQueues[1] = mBgBroadcastQueue;
1600
1601         mServices = new ActiveServices(this);
1602         mProviderMap = new ProviderMap(this);
1603
1604         File dataDir = Environment.getDataDirectory();
1605         File systemDir = new File(dataDir, "system");
1606         systemDir.mkdirs();
1607         mBatteryStatsService = new BatteryStatsService(new File(
1608                 systemDir, "batterystats.bin").toString());
1609         mBatteryStatsService.getActiveStatistics().readLocked();
1610         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1611         mOnBattery = DEBUG_POWER ? true
1612                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1613         mBatteryStatsService.getActiveStatistics().setCallback(this);
1614         
1615         mUsageStatsService = new UsageStatsService(new File(
1616                 systemDir, "usagestats").toString());
1617         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1618
1619         // User 0 is the first and only user that runs at boot.
1620         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1621         mUserLru.add(Integer.valueOf(0));
1622         updateStartedUserArrayLocked();
1623
1624         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1625             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1626
1627         mConfiguration.setToDefaults();
1628         mConfiguration.setLocale(Locale.getDefault());
1629
1630         mConfigurationSeq = mConfiguration.seq = 1;
1631         mProcessStats.init();
1632         
1633         mCompatModePackages = new CompatModePackages(this, systemDir);
1634
1635         // Add ourself to the Watchdog monitors.
1636         Watchdog.getInstance().addMonitor(this);
1637
1638         mProcessStatsThread = new Thread("ProcessStats") {
1639             public void run() {
1640                 while (true) {
1641                     try {
1642                         try {
1643                             synchronized(this) {
1644                                 final long now = SystemClock.uptimeMillis();
1645                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1646                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1647                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1648                                 //        + ", write delay=" + nextWriteDelay);
1649                                 if (nextWriteDelay < nextCpuDelay) {
1650                                     nextCpuDelay = nextWriteDelay;
1651                                 }
1652                                 if (nextCpuDelay > 0) {
1653                                     mProcessStatsMutexFree.set(true);
1654                                     this.wait(nextCpuDelay);
1655                                 }
1656                             }
1657                         } catch (InterruptedException e) {
1658                         }
1659                         updateCpuStatsNow();
1660                     } catch (Exception e) {
1661                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
1662                     }
1663                 }
1664             }
1665         };
1666         mProcessStatsThread.start();
1667     }
1668
1669     @Override
1670     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1671             throws RemoteException {
1672         if (code == SYSPROPS_TRANSACTION) {
1673             // We need to tell all apps about the system property change.
1674             ArrayList<IBinder> procs = new ArrayList<IBinder>();
1675             synchronized(this) {
1676                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1677                     final int NA = apps.size();
1678                     for (int ia=0; ia<NA; ia++) {
1679                         ProcessRecord app = apps.valueAt(ia);
1680                         if (app.thread != null) {
1681                             procs.add(app.thread.asBinder());
1682                         }
1683                     }
1684                 }
1685             }
1686
1687             int N = procs.size();
1688             for (int i=0; i<N; i++) {
1689                 Parcel data2 = Parcel.obtain();
1690                 try {
1691                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1692                 } catch (RemoteException e) {
1693                 }
1694                 data2.recycle();
1695             }
1696         }
1697         try {
1698             return super.onTransact(code, data, reply, flags);
1699         } catch (RuntimeException e) {
1700             // The activity manager only throws security exceptions, so let's
1701             // log all others.
1702             if (!(e instanceof SecurityException)) {
1703                 Slog.e(TAG, "Activity Manager Crash", e);
1704             }
1705             throw e;
1706         }
1707     }
1708
1709     void updateCpuStats() {
1710         final long now = SystemClock.uptimeMillis();
1711         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1712             return;
1713         }
1714         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1715             synchronized (mProcessStatsThread) {
1716                 mProcessStatsThread.notify();
1717             }
1718         }
1719     }
1720
1721     void updateCpuStatsNow() {
1722         synchronized (mProcessStatsThread) {
1723             mProcessStatsMutexFree.set(false);
1724             final long now = SystemClock.uptimeMillis();
1725             boolean haveNewCpuStats = false;
1726
1727             if (MONITOR_CPU_USAGE &&
1728                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1729                 mLastCpuTime.set(now);
1730                 haveNewCpuStats = true;
1731                 mProcessStats.update();
1732                 //Slog.i(TAG, mProcessStats.printCurrentState());
1733                 //Slog.i(TAG, "Total CPU usage: "
1734                 //        + mProcessStats.getTotalCpuPercent() + "%");
1735
1736                 // Slog the cpu usage if the property is set.
1737                 if ("true".equals(SystemProperties.get("events.cpu"))) {
1738                     int user = mProcessStats.getLastUserTime();
1739                     int system = mProcessStats.getLastSystemTime();
1740                     int iowait = mProcessStats.getLastIoWaitTime();
1741                     int irq = mProcessStats.getLastIrqTime();
1742                     int softIrq = mProcessStats.getLastSoftIrqTime();
1743                     int idle = mProcessStats.getLastIdleTime();
1744
1745                     int total = user + system + iowait + irq + softIrq + idle;
1746                     if (total == 0) total = 1;
1747
1748                     EventLog.writeEvent(EventLogTags.CPU,
1749                             ((user+system+iowait+irq+softIrq) * 100) / total,
1750                             (user * 100) / total,
1751                             (system * 100) / total,
1752                             (iowait * 100) / total,
1753                             (irq * 100) / total,
1754                             (softIrq * 100) / total);
1755                 }
1756             }
1757             
1758             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1759             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1760             synchronized(bstats) {
1761                 synchronized(mPidsSelfLocked) {
1762                     if (haveNewCpuStats) {
1763                         if (mOnBattery) {
1764                             int perc = bstats.startAddingCpuLocked();
1765                             int totalUTime = 0;
1766                             int totalSTime = 0;
1767                             final int N = mProcessStats.countStats();
1768                             for (int i=0; i<N; i++) {
1769                                 ProcessStats.Stats st = mProcessStats.getStats(i);
1770                                 if (!st.working) {
1771                                     continue;
1772                                 }
1773                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1774                                 int otherUTime = (st.rel_utime*perc)/100;
1775                                 int otherSTime = (st.rel_stime*perc)/100;
1776                                 totalUTime += otherUTime;
1777                                 totalSTime += otherSTime;
1778                                 if (pr != null) {
1779                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1780                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1781                                             st.rel_stime-otherSTime);
1782                                     ps.addSpeedStepTimes(cpuSpeedTimes);
1783                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1784                                 } else {
1785                                     BatteryStatsImpl.Uid.Proc ps =
1786                                             bstats.getProcessStatsLocked(st.name, st.pid);
1787                                     if (ps != null) {
1788                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1789                                                 st.rel_stime-otherSTime);
1790                                         ps.addSpeedStepTimes(cpuSpeedTimes);
1791                                     }
1792                                 }
1793                             }
1794                             bstats.finishAddingCpuLocked(perc, totalUTime,
1795                                     totalSTime, cpuSpeedTimes);
1796                         }
1797                     }
1798                 }
1799
1800                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1801                     mLastWriteTime = now;
1802                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1803                 }
1804             }
1805         }
1806     }
1807     
1808     @Override
1809     public void batteryNeedsCpuUpdate() {
1810         updateCpuStatsNow();
1811     }
1812
1813     @Override
1814     public void batteryPowerChanged(boolean onBattery) {
1815         // When plugging in, update the CPU stats first before changing
1816         // the plug state.
1817         updateCpuStatsNow();
1818         synchronized (this) {
1819             synchronized(mPidsSelfLocked) {
1820                 mOnBattery = DEBUG_POWER ? true : onBattery;
1821             }
1822         }
1823     }
1824
1825     /**
1826      * Initialize the application bind args. These are passed to each
1827      * process when the bindApplication() IPC is sent to the process. They're
1828      * lazily setup to make sure the services are running when they're asked for.
1829      */
1830     private HashMap<String, IBinder> getCommonServicesLocked() {
1831         if (mAppBindArgs == null) {
1832             mAppBindArgs = new HashMap<String, IBinder>();
1833
1834             // Setup the application init args
1835             mAppBindArgs.put("package", ServiceManager.getService("package"));
1836             mAppBindArgs.put("window", ServiceManager.getService("window"));
1837             mAppBindArgs.put(Context.ALARM_SERVICE,
1838                     ServiceManager.getService(Context.ALARM_SERVICE));
1839         }
1840         return mAppBindArgs;
1841     }
1842
1843     final void setFocusedActivityLocked(ActivityRecord r) {
1844         if (mFocusedActivity != r) {
1845             mFocusedActivity = r;
1846             if (r != null) {
1847                 mWindowManager.setFocusedApp(r.appToken, true);
1848             }
1849             applyUpdateLockStateLocked(r);
1850         }
1851     }
1852
1853     final void applyUpdateLockStateLocked(ActivityRecord r) {
1854         // Modifications to the UpdateLock state are done on our handler, outside
1855         // the activity manager's locks.  The new state is determined based on the
1856         // state *now* of the relevant activity record.  The object is passed to
1857         // the handler solely for logging detail, not to be consulted/modified.
1858         final boolean nextState = r != null && r.immersive;
1859         mHandler.sendMessage(
1860                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
1861     }
1862
1863     private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1864         // put it on the LRU to keep track of when it should be exited.
1865         int lrui = mLruProcesses.indexOf(app);
1866         if (lrui >= 0) mLruProcesses.remove(lrui);
1867         
1868         int i = mLruProcesses.size()-1;
1869         int skipTop = 0;
1870         
1871         app.lruSeq = mLruSeq;
1872         
1873         // compute the new weight for this process.
1874         app.lastActivityTime = SystemClock.uptimeMillis();
1875         if (app.activities.size() > 0) {
1876             // If this process has activities, we more strongly want to keep
1877             // it around.
1878             app.lruWeight = app.lastActivityTime;
1879         } else if (app.pubProviders.size() > 0) {
1880             // If this process contains content providers, we want to keep
1881             // it a little more strongly.
1882             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1883             // Also don't let it kick out the first few "real" hidden processes.
1884             skipTop = ProcessList.MIN_HIDDEN_APPS;
1885         } else {
1886             // If this process doesn't have activities, we less strongly
1887             // want to keep it around, and generally want to avoid getting
1888             // in front of any very recently used activities.
1889             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1890             // Also don't let it kick out the first few "real" hidden processes.
1891             skipTop = ProcessList.MIN_HIDDEN_APPS;
1892         }
1893
1894         while (i >= 0) {
1895             ProcessRecord p = mLruProcesses.get(i);
1896             // If this app shouldn't be in front of the first N background
1897             // apps, then skip over that many that are currently hidden.
1898             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1899                 skipTop--;
1900             }
1901             if (p.lruWeight <= app.lruWeight || i < bestPos) {
1902                 mLruProcesses.add(i+1, app);
1903                 break;
1904             }
1905             i--;
1906         }
1907         if (i < 0) {
1908             mLruProcesses.add(0, app);
1909         }
1910         
1911         // If the app is currently using a content provider or service,
1912         // bump those processes as well.
1913         if (app.connections.size() > 0) {
1914             for (ConnectionRecord cr : app.connections) {
1915                 if (cr.binding != null && cr.binding.service != null
1916                         && cr.binding.service.app != null
1917                         && cr.binding.service.app.lruSeq != mLruSeq) {
1918                     updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1919                 }
1920             }
1921         }
1922         for (int j=app.conProviders.size()-1; j>=0; j--) {
1923             ContentProviderRecord cpr = app.conProviders.get(j).provider;
1924             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1925                 updateLruProcessInternalLocked(cpr.proc, i+1);
1926             }
1927         }
1928     }
1929
1930     final void updateLruProcessLocked(ProcessRecord app,
1931             boolean oomAdj) {
1932         mLruSeq++;
1933         updateLruProcessInternalLocked(app, 0);
1934
1935         //Slog.i(TAG, "Putting proc to front: " + app.processName);
1936         if (oomAdj) {
1937             updateOomAdjLocked();
1938         }
1939     }
1940
1941     final ProcessRecord getProcessRecordLocked(
1942             String processName, int uid) {
1943         if (uid == Process.SYSTEM_UID) {
1944             // The system gets to run in any process.  If there are multiple
1945             // processes with the same uid, just pick the first (this
1946             // should never happen).
1947             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1948                     processName);
1949             if (procs == null) return null;
1950             final int N = procs.size();
1951             for (int i = 0; i < N; i++) {
1952                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1953             }
1954         }
1955         ProcessRecord proc = mProcessNames.get(processName, uid);
1956         return proc;
1957     }
1958
1959     void ensurePackageDexOpt(String packageName) {
1960         IPackageManager pm = AppGlobals.getPackageManager();
1961         try {
1962             if (pm.performDexOpt(packageName)) {
1963                 mDidDexOpt = true;
1964             }
1965         } catch (RemoteException e) {
1966         }
1967     }
1968     
1969     boolean isNextTransitionForward() {
1970         int transit = mWindowManager.getPendingAppTransition();
1971         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1972                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1973                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1974     }
1975     
1976     final ProcessRecord startProcessLocked(String processName,
1977             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1978             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1979             boolean isolated) {
1980         ProcessRecord app;
1981         if (!isolated) {
1982             app = getProcessRecordLocked(processName, info.uid);
1983         } else {
1984             // If this is an isolated process, it can't re-use an existing process.
1985             app = null;
1986         }
1987         // We don't have to do anything more if:
1988         // (1) There is an existing application record; and
1989         // (2) The caller doesn't think it is dead, OR there is no thread
1990         //     object attached to it so we know it couldn't have crashed; and
1991         // (3) There is a pid assigned to it, so it is either starting or
1992         //     already running.
1993         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1994                 + " app=" + app + " knownToBeDead=" + knownToBeDead
1995                 + " thread=" + (app != null ? app.thread : null)
1996                 + " pid=" + (app != null ? app.pid : -1));
1997         if (app != null && app.pid > 0) {
1998             if (!knownToBeDead || app.thread == null) {
1999                 // We already have the app running, or are waiting for it to
2000                 // come up (we have a pid but not yet its thread), so keep it.
2001                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2002                 // If this is a new package in the process, add the package to the list
2003                 app.addPackage(info.packageName);
2004                 return app;
2005             } else {
2006                 // An application record is attached to a previous process,
2007                 // clean it up now.
2008                 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2009                 handleAppDiedLocked(app, true, true);
2010             }
2011         }
2012
2013         String hostingNameStr = hostingName != null
2014                 ? hostingName.flattenToShortString() : null;
2015
2016         if (!isolated) {
2017             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2018                 // If we are in the background, then check to see if this process
2019                 // is bad.  If so, we will just silently fail.
2020                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2021                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2022                             + "/" + info.processName);
2023                     return null;
2024                 }
2025             } else {
2026                 // When the user is explicitly starting a process, then clear its
2027                 // crash count so that we won't make it bad until they see at
2028                 // least one crash dialog again, and make the process good again
2029                 // if it had been bad.
2030                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2031                         + "/" + info.processName);
2032                 mProcessCrashTimes.remove(info.processName, info.uid);
2033                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2034                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2035                             UserHandle.getUserId(info.uid), info.uid,
2036                             info.processName);
2037                     mBadProcesses.remove(info.processName, info.uid);
2038                     if (app != null) {
2039                         app.bad = false;
2040                     }
2041                 }
2042             }
2043         }
2044
2045         if (app == null) {
2046             app = newProcessRecordLocked(null, info, processName, isolated);
2047             if (app == null) {
2048                 Slog.w(TAG, "Failed making new process record for "
2049                         + processName + "/" + info.uid + " isolated=" + isolated);
2050                 return null;
2051             }
2052             mProcessNames.put(processName, app.uid, app);
2053             if (isolated) {
2054                 mIsolatedProcesses.put(app.uid, app);
2055             }
2056         } else {
2057             // If this is a new package in the process, add the package to the list
2058             app.addPackage(info.packageName);
2059         }
2060
2061         // If the system is not ready yet, then hold off on starting this
2062         // process until it is.
2063         if (!mProcessesReady
2064                 && !isAllowedWhileBooting(info)
2065                 && !allowWhileBooting) {
2066             if (!mProcessesOnHold.contains(app)) {
2067                 mProcessesOnHold.add(app);
2068             }
2069             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2070             return app;
2071         }
2072
2073         startProcessLocked(app, hostingType, hostingNameStr);
2074         return (app.pid != 0) ? app : null;
2075     }
2076
2077     boolean isAllowedWhileBooting(ApplicationInfo ai) {
2078         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2079     }
2080     
2081     private final void startProcessLocked(ProcessRecord app,
2082             String hostingType, String hostingNameStr) {
2083         if (app.pid > 0 && app.pid != MY_PID) {
2084             synchronized (mPidsSelfLocked) {
2085                 mPidsSelfLocked.remove(app.pid);
2086                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2087             }
2088             app.setPid(0);
2089         }
2090
2091         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2092                 "startProcessLocked removing on hold: " + app);
2093         mProcessesOnHold.remove(app);
2094
2095         updateCpuStats();
2096         
2097         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2098         mProcDeaths[0] = 0;
2099         
2100         try {
2101             int uid = app.uid;
2102
2103             int[] gids = null;
2104             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2105             if (!app.isolated) {
2106                 int[] permGids = null;
2107                 try {
2108                     final PackageManager pm = mContext.getPackageManager();
2109                     permGids = pm.getPackageGids(app.info.packageName);
2110
2111                     if (Environment.isExternalStorageEmulated()) {
2112                         if (pm.checkPermission(
2113                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2114                                 app.info.packageName) == PERMISSION_GRANTED) {
2115                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2116                         } else {
2117                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2118                         }
2119                     }
2120                 } catch (PackageManager.NameNotFoundException e) {
2121                     Slog.w(TAG, "Unable to retrieve gids", e);
2122                 }
2123
2124                 /*
2125                  * Add shared application GID so applications can share some
2126                  * resources like shared libraries
2127                  */
2128                 if (permGids == null) {
2129                     gids = new int[1];
2130                 } else {
2131                     gids = new int[permGids.length + 1];
2132                     System.arraycopy(permGids, 0, gids, 1, permGids.length);
2133                 }
2134                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2135             }
2136             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2137                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2138                         && mTopComponent != null
2139                         && app.processName.equals(mTopComponent.getPackageName())) {
2140                     uid = 0;
2141                 }
2142                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2143                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2144                     uid = 0;
2145                 }
2146             }
2147             int debugFlags = 0;
2148             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2149                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2150                 // Also turn on CheckJNI for debuggable apps. It's quite
2151                 // awkward to turn on otherwise.
2152                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2153             }
2154             // Run the app in safe mode if its manifest requests so or the
2155             // system is booted in safe mode.
2156             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2157                 Zygote.systemInSafeMode == true) {
2158                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2159             }
2160             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2161                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2162             }
2163             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2164                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2165             }
2166             if ("1".equals(SystemProperties.get("debug.assert"))) {
2167                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2168             }
2169
2170             // Start the process.  It will either succeed and return a result containing
2171             // the PID of the new process, or else throw a RuntimeException.
2172             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2173                     app.processName, uid, uid, gids, debugFlags, mountExternal,
2174                     app.info.targetSdkVersion, null, null);
2175
2176             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2177             synchronized (bs) {
2178                 if (bs.isOnBattery()) {
2179                     app.batteryStats.incStartsLocked();
2180                 }
2181             }
2182             
2183             EventLog.writeEvent(EventLogTags.AM_PROC_START,
2184                     UserHandle.getUserId(uid), startResult.pid, uid,
2185                     app.processName, hostingType,
2186                     hostingNameStr != null ? hostingNameStr : "");
2187             
2188             if (app.persistent) {
2189                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2190             }
2191             
2192             StringBuilder buf = mStringBuilder;
2193             buf.setLength(0);
2194             buf.append("Start proc ");
2195             buf.append(app.processName);
2196             buf.append(" for ");
2197             buf.append(hostingType);
2198             if (hostingNameStr != null) {
2199                 buf.append(" ");
2200                 buf.append(hostingNameStr);
2201             }
2202             buf.append(": pid=");
2203             buf.append(startResult.pid);
2204             buf.append(" uid=");
2205             buf.append(uid);
2206             buf.append(" gids={");
2207             if (gids != null) {
2208                 for (int gi=0; gi<gids.length; gi++) {
2209                     if (gi != 0) buf.append(", ");
2210                     buf.append(gids[gi]);
2211
2212                 }
2213             }
2214             buf.append("}");
2215             Slog.i(TAG, buf.toString());
2216             app.setPid(startResult.pid);
2217             app.usingWrapper = startResult.usingWrapper;
2218             app.removed = false;
2219             synchronized (mPidsSelfLocked) {
2220                 this.mPidsSelfLocked.put(startResult.pid, app);
2221                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2222                 msg.obj = app;
2223                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2224                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2225             }
2226         } catch (RuntimeException e) {
2227             // XXX do better error recovery.
2228             app.setPid(0);
2229             Slog.e(TAG, "Failure starting process " + app.processName, e);
2230         }
2231     }
2232
2233     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2234         if (resumed) {
2235             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2236         } else {
2237             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2238         }
2239     }
2240
2241     boolean startHomeActivityLocked(int userId) {
2242         if (mHeadless) {
2243             // Added because none of the other calls to ensureBootCompleted seem to fire
2244             // when running headless.
2245             ensureBootCompleted();
2246             return false;
2247         }
2248
2249         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2250                 && mTopAction == null) {
2251             // We are running in factory test mode, but unable to find
2252             // the factory test app, so just sit around displaying the
2253             // error message and don't try to start anything.
2254             return false;
2255         }
2256         Intent intent = new Intent(
2257             mTopAction,
2258             mTopData != null ? Uri.parse(mTopData) : null);
2259         intent.setComponent(mTopComponent);
2260         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2261             intent.addCategory(Intent.CATEGORY_HOME);
2262         }
2263         ActivityInfo aInfo =
2264             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2265         if (aInfo != null) {
2266             intent.setComponent(new ComponentName(
2267                     aInfo.applicationInfo.packageName, aInfo.name));
2268             // Don't do this if the home app is currently being
2269             // instrumented.
2270             aInfo = new ActivityInfo(aInfo);
2271             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2272             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2273                     aInfo.applicationInfo.uid);
2274             if (app == null || app.instrumentationClass == null) {
2275                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2276                 mMainStack.startActivityLocked(null, intent, null, aInfo,
2277                         null, null, 0, 0, 0, 0, null, false, null);
2278             }
2279         }
2280
2281         return true;
2282     }
2283
2284     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2285         ActivityInfo ai = null;
2286         ComponentName comp = intent.getComponent();
2287         try {
2288             if (comp != null) {
2289                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2290             } else {
2291                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2292                         intent,
2293                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2294                             flags, userId);
2295     
2296                 if (info != null) {
2297                     ai = info.activityInfo;
2298                 }
2299             }
2300         } catch (RemoteException e) {
2301             // ignore
2302         }
2303
2304         return ai;
2305     }
2306
2307     /**
2308      * Starts the "new version setup screen" if appropriate.
2309      */
2310     void startSetupActivityLocked() {
2311         // Only do this once per boot.
2312         if (mCheckedForSetup) {
2313             return;
2314         }
2315         
2316         // We will show this screen if the current one is a different
2317         // version than the last one shown, and we are not running in
2318         // low-level factory test mode.
2319         final ContentResolver resolver = mContext.getContentResolver();
2320         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2321                 Settings.Global.getInt(resolver,
2322                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2323             mCheckedForSetup = true;
2324             
2325             // See if we should be showing the platform update setup UI.
2326             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2327             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2328                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2329             
2330             // We don't allow third party apps to replace this.
2331             ResolveInfo ri = null;
2332             for (int i=0; ris != null && i<ris.size(); i++) {
2333                 if ((ris.get(i).activityInfo.applicationInfo.flags
2334                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
2335                     ri = ris.get(i);
2336                     break;
2337                 }
2338             }
2339             
2340             if (ri != null) {
2341                 String vers = ri.activityInfo.metaData != null
2342                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2343                         : null;
2344                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2345                     vers = ri.activityInfo.applicationInfo.metaData.getString(
2346                             Intent.METADATA_SETUP_VERSION);
2347                 }
2348                 String lastVers = Settings.Secure.getString(
2349                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
2350                 if (vers != null && !vers.equals(lastVers)) {
2351                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2352                     intent.setComponent(new ComponentName(
2353                             ri.activityInfo.packageName, ri.activityInfo.name));
2354                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2355                             null, null, 0, 0, 0, 0, null, false, null);
2356                 }
2357             }
2358         }
2359     }
2360     
2361     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2362         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2363     }
2364
2365     void enforceNotIsolatedCaller(String caller) {
2366         if (UserHandle.isIsolated(Binder.getCallingUid())) {
2367             throw new SecurityException("Isolated process not allowed to call " + caller);
2368         }
2369     }
2370
2371     public int getFrontActivityScreenCompatMode() {
2372         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2373         synchronized (this) {
2374             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2375         }
2376     }
2377
2378     public void setFrontActivityScreenCompatMode(int mode) {
2379         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2380                 "setFrontActivityScreenCompatMode");
2381         synchronized (this) {
2382             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2383         }
2384     }
2385
2386     public int getPackageScreenCompatMode(String packageName) {
2387         enforceNotIsolatedCaller("getPackageScreenCompatMode");
2388         synchronized (this) {
2389             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2390         }
2391     }
2392
2393     public void setPackageScreenCompatMode(String packageName, int mode) {
2394         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2395                 "setPackageScreenCompatMode");
2396         synchronized (this) {
2397             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2398         }
2399     }
2400
2401     public boolean getPackageAskScreenCompat(String packageName) {
2402         enforceNotIsolatedCaller("getPackageAskScreenCompat");
2403         synchronized (this) {
2404             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2405         }
2406     }
2407
2408     public void setPackageAskScreenCompat(String packageName, boolean ask) {
2409         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2410                 "setPackageAskScreenCompat");
2411         synchronized (this) {
2412             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2413         }
2414     }
2415
2416     void reportResumedActivityLocked(ActivityRecord r) {
2417         //Slog.i(TAG, "**** REPORT RESUME: " + r);
2418         updateUsageStats(r, true);
2419     }
2420
2421     private void dispatchProcessesChanged() {
2422         int N;
2423         synchronized (this) {
2424             N = mPendingProcessChanges.size();
2425             if (mActiveProcessChanges.length < N) {
2426                 mActiveProcessChanges = new ProcessChangeItem[N];
2427             }
2428             mPendingProcessChanges.toArray(mActiveProcessChanges);
2429             mAvailProcessChanges.addAll(mPendingProcessChanges);
2430             mPendingProcessChanges.clear();
2431             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2432         }
2433         int i = mProcessObservers.beginBroadcast();
2434         while (i > 0) {
2435             i--;
2436             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2437             if (observer != null) {
2438                 try {
2439                     for (int j=0; j<N; j++) {
2440                         ProcessChangeItem item = mActiveProcessChanges[j];
2441                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2442                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2443                                     + item.pid + " uid=" + item.uid + ": "
2444                                     + item.foregroundActivities);
2445                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
2446                                     item.foregroundActivities);
2447                         }
2448                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2449                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2450                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
2451                             observer.onImportanceChanged(item.pid, item.uid,
2452                                     item.importance);
2453                         }
2454                     }
2455                 } catch (RemoteException e) {
2456                 }
2457             }
2458         }
2459         mProcessObservers.finishBroadcast();
2460     }
2461
2462     private void dispatchProcessDied(int pid, int uid) {
2463         int i = mProcessObservers.beginBroadcast();
2464         while (i > 0) {
2465             i--;
2466             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2467             if (observer != null) {
2468                 try {
2469                     observer.onProcessDied(pid, uid);
2470                 } catch (RemoteException e) {
2471                 }
2472             }
2473         }
2474         mProcessObservers.finishBroadcast();
2475     }
2476
2477     final void doPendingActivityLaunchesLocked(boolean doResume) {
2478         final int N = mPendingActivityLaunches.size();
2479         if (N <= 0) {
2480             return;
2481         }
2482         for (int i=0; i<N; i++) {
2483             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2484             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2485                     pal.startFlags, doResume && i == (N-1), null);
2486         }
2487         mPendingActivityLaunches.clear();
2488     }
2489
2490     public final int startActivity(IApplicationThread caller,
2491             Intent intent, String resolvedType, IBinder resultTo,
2492             String resultWho, int requestCode, int startFlags,
2493             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2494         return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2495                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2496     }
2497
2498     public final int startActivityAsUser(IApplicationThread caller,
2499             Intent intent, String resolvedType, IBinder resultTo,
2500             String resultWho, int requestCode, int startFlags,
2501             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2502         enforceNotIsolatedCaller("startActivity");
2503         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2504                 false, true, "startActivity", null);
2505         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2506                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2507                 null, null, options, userId);
2508     }
2509
2510     public final WaitResult startActivityAndWait(IApplicationThread caller,
2511             Intent intent, String resolvedType, IBinder resultTo,
2512             String resultWho, int requestCode, int startFlags, String profileFile,
2513             ParcelFileDescriptor profileFd, Bundle options, int userId) {
2514         enforceNotIsolatedCaller("startActivityAndWait");
2515         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2516                 false, true, "startActivityAndWait", null);
2517         WaitResult res = new WaitResult();
2518         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2519                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2520                 res, null, options, UserHandle.getCallingUserId());
2521         return res;
2522     }
2523
2524     public final int startActivityWithConfig(IApplicationThread caller,
2525             Intent intent, String resolvedType, IBinder resultTo,
2526             String resultWho, int requestCode, int startFlags, Configuration config,
2527             Bundle options, int userId) {
2528         enforceNotIsolatedCaller("startActivityWithConfig");
2529         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2530                 false, true, "startActivityWithConfig", null);
2531         int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2532                 resultTo, resultWho, requestCode, startFlags,
2533                 null, null, null, config, options, userId);
2534         return ret;
2535     }
2536
2537     public int startActivityIntentSender(IApplicationThread caller,
2538             IntentSender intent, Intent fillInIntent, String resolvedType,
2539             IBinder resultTo, String resultWho, int requestCode,
2540             int flagsMask, int flagsValues, Bundle options) {
2541         enforceNotIsolatedCaller("startActivityIntentSender");
2542         // Refuse possible leaked file descriptors
2543         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2544             throw new IllegalArgumentException("File descriptors passed in Intent");
2545         }
2546         
2547         IIntentSender sender = intent.getTarget();
2548         if (!(sender instanceof PendingIntentRecord)) {
2549             throw new IllegalArgumentException("Bad PendingIntent object");
2550         }
2551         
2552         PendingIntentRecord pir = (PendingIntentRecord)sender;
2553         
2554         synchronized (this) {
2555             // If this is coming from the currently resumed activity, it is
2556             // effectively saying that app switches are allowed at this point.
2557             if (mMainStack.mResumedActivity != null
2558                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2559                             Binder.getCallingUid()) {
2560                 mAppSwitchesAllowedTime = 0;
2561             }
2562         }
2563         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2564                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2565         return ret;
2566     }
2567     
2568     public boolean startNextMatchingActivity(IBinder callingActivity,
2569             Intent intent, Bundle options) {
2570         // Refuse possible leaked file descriptors
2571         if (intent != null && intent.hasFileDescriptors() == true) {
2572             throw new IllegalArgumentException("File descriptors passed in Intent");
2573         }
2574
2575         synchronized (this) {
2576             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2577             if (r == null) {
2578                 ActivityOptions.abort(options);
2579                 return false;
2580             }
2581             if (r.app == null || r.app.thread == null) {
2582                 // The caller is not running...  d'oh!
2583                 ActivityOptions.abort(options);
2584                 return false;
2585             }
2586             intent = new Intent(intent);
2587             // The caller is not allowed to change the data.
2588             intent.setDataAndType(r.intent.getData(), r.intent.getType());
2589             // And we are resetting to find the next component...
2590             intent.setComponent(null);
2591
2592             ActivityInfo aInfo = null;
2593             try {
2594                 List<ResolveInfo> resolves =
2595                     AppGlobals.getPackageManager().queryIntentActivities(
2596                             intent, r.resolvedType,
2597                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2598                             UserHandle.getCallingUserId());
2599
2600                 // Look for the original activity in the list...
2601                 final int N = resolves != null ? resolves.size() : 0;
2602                 for (int i=0; i<N; i++) {
2603                     ResolveInfo rInfo = resolves.get(i);
2604                     if (rInfo.activityInfo.packageName.equals(r.packageName)
2605                             && rInfo.activityInfo.name.equals(r.info.name)) {
2606                         // We found the current one...  the next matching is
2607                         // after it.
2608                         i++;
2609                         if (i<N) {
2610                             aInfo = resolves.get(i).activityInfo;
2611                         }
2612                         break;
2613                     }
2614                 }
2615             } catch (RemoteException e) {
2616             }
2617
2618             if (aInfo == null) {
2619                 // Nobody who is next!
2620                 ActivityOptions.abort(options);
2621                 return false;
2622             }
2623
2624             intent.setComponent(new ComponentName(
2625                     aInfo.applicationInfo.packageName, aInfo.name));
2626             intent.setFlags(intent.getFlags()&~(
2627                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2628                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
2629                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2630                     Intent.FLAG_ACTIVITY_NEW_TASK));
2631
2632             // Okay now we need to start the new activity, replacing the
2633             // currently running activity.  This is a little tricky because
2634             // we want to start the new one as if the current one is finished,
2635             // but not finish the current one first so that there is no flicker.
2636             // And thus...
2637             final boolean wasFinishing = r.finishing;
2638             r.finishing = true;
2639
2640             // Propagate reply information over to the new activity.
2641             final ActivityRecord resultTo = r.resultTo;
2642             final String resultWho = r.resultWho;
2643             final int requestCode = r.requestCode;
2644             r.resultTo = null;
2645             if (resultTo != null) {
2646                 resultTo.removeResultsLocked(r, resultWho, requestCode);
2647             }
2648
2649             final long origId = Binder.clearCallingIdentity();
2650             int res = mMainStack.startActivityLocked(r.app.thread, intent,
2651                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2652                     resultWho, requestCode, -1, r.launchedFromUid, 0,
2653                     options, false, null);
2654             Binder.restoreCallingIdentity(origId);
2655
2656             r.finishing = wasFinishing;
2657             if (res != ActivityManager.START_SUCCESS) {
2658                 return false;
2659             }
2660             return true;
2661         }
2662     }
2663
2664     final int startActivityInPackage(int uid,
2665             Intent intent, String resolvedType, IBinder resultTo,
2666             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2667
2668         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2669                 false, true, "startActivityInPackage", null);
2670
2671         int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2672                 resultTo, resultWho, requestCode, startFlags,
2673                 null, null, null, null, options, userId);
2674         return ret;
2675     }
2676
2677     public final int startActivities(IApplicationThread caller,
2678             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2679             int userId) {
2680         enforceNotIsolatedCaller("startActivities");
2681         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2682                 false, true, "startActivity", null);
2683         int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2684                 options, userId);
2685         return ret;
2686     }
2687
2688     final int startActivitiesInPackage(int uid,
2689             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2690             Bundle options, int userId) {
2691
2692         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2693                 false, true, "startActivityInPackage", null);
2694         int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2695                 options, userId);
2696         return ret;
2697     }
2698
2699     final void addRecentTaskLocked(TaskRecord task) {
2700         int N = mRecentTasks.size();
2701         // Quick case: check if the top-most recent task is the same.
2702         if (N > 0 && mRecentTasks.get(0) == task) {
2703             return;
2704         }
2705         // Remove any existing entries that are the same kind of task.
2706         for (int i=0; i<N; i++) {
2707             TaskRecord tr = mRecentTasks.get(i);
2708             if (task.userId == tr.userId
2709                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
2710                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2711                 mRecentTasks.remove(i);
2712                 i--;
2713                 N--;
2714                 if (task.intent == null) {
2715                     // If the new recent task we are adding is not fully
2716                     // specified, then replace it with the existing recent task.
2717                     task = tr;
2718                 }
2719             }
2720         }
2721         if (N >= MAX_RECENT_TASKS) {
2722             mRecentTasks.remove(N-1);
2723         }
2724         mRecentTasks.add(0, task);
2725     }
2726
2727     public void setRequestedOrientation(IBinder token,
2728             int requestedOrientation) {
2729         synchronized (this) {
2730             ActivityRecord r = mMainStack.isInStackLocked(token);
2731             if (r == null) {
2732                 return;
2733             }
2734             final long origId = Binder.clearCallingIdentity();
2735             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2736             Configuration config = mWindowManager.updateOrientationFromAppTokens(
2737                     mConfiguration,
2738                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2739             if (config != null) {
2740                 r.frozenBeforeDestroy = true;
2741                 if (!updateConfigurationLocked(config, r, false, false)) {
2742                     mMainStack.resumeTopActivityLocked(null);
2743                 }
2744             }
2745             Binder.restoreCallingIdentity(origId);
2746         }
2747     }
2748
2749     public int getRequestedOrientation(IBinder token) {
2750         synchronized (this) {
2751             ActivityRecord r = mMainStack.isInStackLocked(token);
2752             if (r == null) {
2753                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2754             }
2755             return mWindowManager.getAppOrientation(r.appToken);
2756         }
2757     }
2758
2759     /**
2760      * This is the internal entry point for handling Activity.finish().
2761      * 
2762      * @param token The Binder token referencing the Activity we want to finish.
2763      * @param resultCode Result code, if any, from this Activity.
2764      * @param resultData Result data (Intent), if any, from this Activity.
2765      * 
2766      * @return Returns true if the activity successfully finished, or false if it is still running.
2767      */
2768     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2769         // Refuse possible leaked file descriptors
2770         if (resultData != null && resultData.hasFileDescriptors() == true) {
2771             throw new IllegalArgumentException("File descriptors passed in Intent");
2772         }
2773
2774         synchronized(this) {
2775             if (mController != null) {
2776                 // Find the first activity that is not finishing.
2777                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2778                 if (next != null) {
2779                     // ask watcher if this is allowed
2780                     boolean resumeOK = true;
2781                     try {
2782                         resumeOK = mController.activityResuming(next.packageName);
2783                     } catch (RemoteException e) {
2784                         mController = null;
2785                     }
2786     
2787                     if (!resumeOK) {
2788                         return false;
2789                     }
2790                 }
2791             }
2792             final long origId = Binder.clearCallingIdentity();
2793             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2794                     resultData, "app-request", true);
2795             Binder.restoreCallingIdentity(origId);
2796             return res;
2797         }
2798     }
2799
2800     public final void finishHeavyWeightApp() {
2801         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2802                 != PackageManager.PERMISSION_GRANTED) {
2803             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2804                     + Binder.getCallingPid()
2805                     + ", uid=" + Binder.getCallingUid()
2806                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2807             Slog.w(TAG, msg);
2808             throw new SecurityException(msg);
2809         }
2810         
2811         synchronized(this) {
2812             if (mHeavyWeightProcess == null) {
2813                 return;
2814             }
2815             
2816             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2817                     mHeavyWeightProcess.activities);
2818             for (int i=0; i<activities.size(); i++) {
2819                 ActivityRecord r = activities.get(i);
2820                 if (!r.finishing) {
2821                     int index = mMainStack.indexOfTokenLocked(r.appToken);
2822                     if (index >= 0) {
2823                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2824                                 null, "finish-heavy", true);
2825                     }
2826                 }
2827             }
2828             
2829             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2830                     mHeavyWeightProcess.userId, 0));
2831             mHeavyWeightProcess = null;
2832         }
2833     }
2834     
2835     public void crashApplication(int uid, int initialPid, String packageName,
2836             String message) {
2837         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2838                 != PackageManager.PERMISSION_GRANTED) {
2839             String msg = "Permission Denial: crashApplication() from pid="
2840                     + Binder.getCallingPid()
2841                     + ", uid=" + Binder.getCallingUid()
2842                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2843             Slog.w(TAG, msg);
2844             throw new SecurityException(msg);
2845         }
2846         
2847         synchronized(this) {
2848             ProcessRecord proc = null;
2849             
2850             // Figure out which process to kill.  We don't trust that initialPid
2851             // still has any relation to current pids, so must scan through the
2852             // list.
2853             synchronized (mPidsSelfLocked) {
2854                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2855                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
2856                     if (p.uid != uid) {
2857                         continue;
2858                     }
2859                     if (p.pid == initialPid) {
2860                         proc = p;
2861                         break;
2862                     }
2863                     for (String str : p.pkgList) {
2864                         if (str.equals(packageName)) {
2865                             proc = p;
2866                         }
2867                     }
2868                 }
2869             }
2870             
2871             if (proc == null) {
2872                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2873                         + " initialPid=" + initialPid
2874                         + " packageName=" + packageName);
2875                 return;
2876             }
2877             
2878             if (proc.thread != null) {
2879                 if (proc.pid == Process.myPid()) {
2880                     Log.w(TAG, "crashApplication: trying to crash self!");
2881                     return;
2882                 }
2883                 long ident = Binder.clearCallingIdentity();
2884                 try {
2885                     proc.thread.scheduleCrash(message);
2886                 } catch (RemoteException e) {
2887                 }
2888                 Binder.restoreCallingIdentity(ident);
2889             }
2890         }
2891     }
2892     
2893     public final void finishSubActivity(IBinder token, String resultWho,
2894             int requestCode) {
2895         synchronized(this) {
2896             final long origId = Binder.clearCallingIdentity();
2897             mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2898             Binder.restoreCallingIdentity(origId);
2899         }
2900     }
2901
2902     public boolean finishActivityAffinity(IBinder token) {
2903         synchronized(this) {
2904             final long origId = Binder.clearCallingIdentity();
2905             boolean res = mMainStack.finishActivityAffinityLocked(token);
2906             Binder.restoreCallingIdentity(origId);
2907             return res;
2908         }
2909     }
2910
2911     public boolean willActivityBeVisible(IBinder token) {
2912         synchronized(this) {
2913             int i;
2914             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2915                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2916                 if (r.appToken == token) {
2917                     return true;
2918                 }
2919                 if (r.fullscreen && !r.finishing) {
2920                     return false;
2921                 }
2922             }
2923             return true;
2924         }
2925     }
2926     
2927     public void overridePendingTransition(IBinder token, String packageName,
2928             int enterAnim, int exitAnim) {
2929         synchronized(this) {
2930             ActivityRecord self = mMainStack.isInStackLocked(token);
2931             if (self == null) {
2932                 return;
2933             }
2934
2935             final long origId = Binder.clearCallingIdentity();
2936             
2937             if (self.state == ActivityState.RESUMED
2938                     || self.state == ActivityState.PAUSING) {
2939                 mWindowManager.overridePendingAppTransition(packageName,
2940                         enterAnim, exitAnim, null);
2941             }
2942             
2943             Binder.restoreCallingIdentity(origId);
2944         }
2945     }
2946     
2947     /**
2948      * Main function for removing an existing process from the activity manager
2949      * as a result of that process going away.  Clears out all connections
2950      * to the process.
2951      */
2952     private final void handleAppDiedLocked(ProcessRecord app,
2953             boolean restarting, boolean allowRestart) {
2954         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2955         if (!restarting) {
2956             mLruProcesses.remove(app);
2957         }
2958
2959         if (mProfileProc == app) {
2960             clearProfilerLocked();
2961         }
2962
2963         // Just in case...
2964         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2965             if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2966                     "App died while pausing: " + mMainStack.mPausingActivity);
2967             mMainStack.mPausingActivity = null;
2968         }
2969         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2970             mMainStack.mLastPausedActivity = null;
2971         }
2972
2973         // Remove this application's activities from active lists.
2974         boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
2975
2976         app.activities.clear();
2977         
2978         if (app.instrumentationClass != null) {
2979             Slog.w(TAG, "Crash of app " + app.processName
2980                   + " running instrumentation " + app.instrumentationClass);
2981             Bundle info = new Bundle();
2982             info.putString("shortMsg", "Process crashed.");
2983             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2984         }
2985
2986         if (!restarting) {
2987             if (!mMainStack.resumeTopActivityLocked(null)) {
2988                 // If there was nothing to resume, and we are not already
2989                 // restarting this process, but there is a visible activity that
2990                 // is hosted by the process...  then make sure all visible
2991                 // activities are running, taking care of restarting this
2992                 // process.
2993                 if (hasVisibleActivities) {
2994                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
2995                 }
2996             }
2997         }
2998     }
2999
3000     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3001         IBinder threadBinder = thread.asBinder();
3002         // Find the application record.
3003         for (int i=mLruProcesses.size()-1; i>=0; i--) {
3004             ProcessRecord rec = mLruProcesses.get(i);
3005             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3006                 return i;
3007             }
3008         }
3009         return -1;
3010     }
3011
3012     final ProcessRecord getRecordForAppLocked(
3013             IApplicationThread thread) {
3014         if (thread == null) {
3015             return null;
3016         }
3017
3018         int appIndex = getLRURecordIndexForAppLocked(thread);
3019         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3020     }
3021
3022     final void appDiedLocked(ProcessRecord app, int pid,
3023             IApplicationThread thread) {
3024
3025         mProcDeaths[0]++;
3026         
3027         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3028         synchronized (stats) {
3029             stats.noteProcessDiedLocked(app.info.uid, pid);
3030         }
3031
3032         // Clean up already done if the process has been re-started.
3033         if (app.pid == pid && app.thread != null &&
3034                 app.thread.asBinder() == thread.asBinder()) {
3035             if (!app.killedBackground) {
3036                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3037                         + ") has died.");
3038             }
3039             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3040             if (DEBUG_CLEANUP) Slog.v(
3041                 TAG, "Dying app: " + app + ", pid: " + pid
3042                 + ", thread: " + thread.asBinder());
3043             boolean doLowMem = app.instrumentationClass == null;
3044             handleAppDiedLocked(app, false, true);
3045
3046             if (doLowMem) {
3047                 // If there are no longer any background processes running,
3048                 // and the app that died was not running instrumentation,
3049                 // then tell everyone we are now low on memory.
3050                 boolean haveBg = false;
3051                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3052                     ProcessRecord rec = mLruProcesses.get(i);
3053                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3054                         haveBg = true;
3055                         break;
3056                     }
3057                 }
3058                 
3059                 if (!haveBg) {
3060                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3061                     long now = SystemClock.uptimeMillis();
3062                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
3063                         ProcessRecord rec = mLruProcesses.get(i);
3064                         if (rec != app && rec.thread != null &&
3065                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3066                             // The low memory report is overriding any current
3067                             // state for a GC request.  Make sure to do
3068                             // heavy/important/visible/foreground processes first.
3069                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3070                                 rec.lastRequestedGc = 0;
3071                             } else {
3072                                 rec.lastRequestedGc = rec.lastLowMemory;
3073                             }
3074                             rec.reportLowMemory = true;
3075                             rec.lastLowMemory = now;
3076                             mProcessesToGc.remove(rec);
3077                             addProcessToGcListLocked(rec);
3078                         }
3079                     }
3080                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3081                     scheduleAppGcsLocked();
3082                 }
3083             }
3084         } else if (app.pid != pid) {
3085             // A new process has already been started.
3086             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3087                     + ") has died and restarted (pid " + app.pid + ").");
3088             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3089         } else if (DEBUG_PROCESSES) {
3090             Slog.d(TAG, "Received spurious death notification for thread "
3091                     + thread.asBinder());
3092         }
3093     }
3094
3095     /**
3096      * If a stack trace dump file is configured, dump process stack traces.
3097      * @param clearTraces causes the dump file to be erased prior to the new
3098      *    traces being written, if true; when false, the new traces will be
3099      *    appended to any existing file content.
3100      * @param firstPids of dalvik VM processes to dump stack traces for first
3101      * @param lastPids of dalvik VM processes to dump stack traces for last
3102      * @param nativeProcs optional list of native process names to dump stack crawls
3103      * @return file containing stack traces, or null if no dump file is configured
3104      */
3105     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3106             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3107         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3108         if (tracesPath == null || tracesPath.length() == 0) {
3109             return null;
3110         }
3111
3112         File tracesFile = new File(tracesPath);
3113         try {
3114             File tracesDir = tracesFile.getParentFile();
3115             if (!tracesDir.exists()) {
3116                 tracesFile.mkdirs();
3117                 if (!SELinux.restorecon(tracesDir)) {
3118                     return null;
3119                 }
3120             }
3121             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3122
3123             if (clearTraces && tracesFile.exists()) tracesFile.delete();
3124             tracesFile.createNewFile();
3125             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3126         } catch (IOException e) {
3127             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3128             return null;
3129         }
3130
3131         dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3132         return tracesFile;
3133     }
3134
3135     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3136             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3137         // Use a FileObserver to detect when traces finish writing.
3138         // The order of traces is considered important to maintain for legibility.
3139         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3140             public synchronized void onEvent(int event, String path) { notify(); }
3141         };
3142
3143         try {
3144             observer.startWatching();
3145
3146             // First collect all of the stacks of the most important pids.
3147             if (firstPids != null) {
3148                 try {
3149                     int num = firstPids.size();
3150                     for (int i = 0; i < num; i++) {
3151                         synchronized (observer) {
3152                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3153                             observer.wait(200);  // Wait for write-close, give up after 200msec
3154                         }
3155                     }
3156                 } catch (InterruptedException e) {
3157                     Log.wtf(TAG, e);
3158                 }
3159             }
3160
3161             // Next measure CPU usage.
3162             if (processStats != null) {
3163                 processStats.init();
3164                 System.gc();
3165                 processStats.update();
3166                 try {
3167                     synchronized (processStats) {
3168                         processStats.wait(500); // measure over 1/2 second.
3169                     }
3170                 } catch (InterruptedException e) {
3171                 }
3172                 processStats.update();
3173
3174                 // We'll take the stack crawls of just the top apps using CPU.
3175                 final int N = processStats.countWorkingStats();
3176                 int numProcs = 0;
3177                 for (int i=0; i<N && numProcs<5; i++) {
3178                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
3179                     if (lastPids.indexOfKey(stats.pid) >= 0) {
3180                         numProcs++;
3181                         try {
3182                             synchronized (observer) {
3183                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3184                                 observer.wait(200);  // Wait for write-close, give up after 200msec
3185                             }
3186                         } catch (InterruptedException e) {
3187                             Log.wtf(TAG, e);
3188                         }
3189
3190                     }
3191                 }
3192             }
3193
3194         } finally {
3195             observer.stopWatching();
3196         }
3197
3198         if (nativeProcs != null) {
3199             int[] pids = Process.getPidsForCommands(nativeProcs);
3200             if (pids != null) {
3201                 for (int pid : pids) {
3202                     Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3203                 }
3204             }
3205         }
3206     }
3207
3208     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3209         if (true || IS_USER_BUILD) {
3210             return;
3211         }
3212         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3213         if (tracesPath == null || tracesPath.length() == 0) {
3214             return;
3215         }
3216
3217         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3218         StrictMode.allowThreadDiskWrites();
3219         try {
3220             final File tracesFile = new File(tracesPath);
3221             final File tracesDir = tracesFile.getParentFile();
3222             final File tracesTmp = new File(tracesDir, "__tmp__");
3223             try {
3224                 if (!tracesDir.exists()) {
3225                     tracesFile.mkdirs();
3226                     if (!SELinux.restorecon(tracesDir.getPath())) {
3227                         return;
3228                     }
3229                 }
3230                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3231
3232                 if (tracesFile.exists()) {
3233                     tracesTmp.delete();
3234                     tracesFile.renameTo(tracesTmp);
3235                 }
3236                 StringBuilder sb = new StringBuilder();
3237                 Time tobj = new Time();
3238                 tobj.set(System.currentTimeMillis());
3239                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3240                 sb.append(": ");
3241                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3242                 sb.append(" since ");
3243                 sb.append(msg);
3244                 FileOutputStream fos = new FileOutputStream(tracesFile);
3245                 fos.write(sb.toString().getBytes());
3246                 if (app == null) {
3247                     fos.write("\n*** No application process!".getBytes());
3248                 }
3249                 fos.close();
3250                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3251             } catch (IOException e) {
3252                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3253                 return;
3254             }
3255
3256             if (app != null) {
3257                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3258                 firstPids.add(app.pid);
3259                 dumpStackTraces(tracesPath, firstPids, null, null, null);
3260             }
3261
3262             File lastTracesFile = null;
3263             File curTracesFile = null;
3264             for (int i=9; i>=0; i--) {
3265                 String name = String.format("slow%02d.txt", i);
3266                 curTracesFile = new File(tracesDir, name);
3267                 if (curTracesFile.exists()) {
3268                     if (lastTracesFile != null) {
3269                         curTracesFile.renameTo(lastTracesFile);
3270                     } else {
3271                         curTracesFile.delete();
3272                     }
3273                 }
3274                 lastTracesFile = curTracesFile;
3275             }
3276             tracesFile.renameTo(curTracesFile);
3277             if (tracesTmp.exists()) {
3278                 tracesTmp.renameTo(tracesFile);
3279             }
3280         } finally {
3281             StrictMode.setThreadPolicy(oldPolicy);
3282         }
3283     }
3284
3285     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3286             ActivityRecord parent, boolean aboveSystem, final String annotation) {
3287         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3288         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3289
3290         if (mController != null) {
3291             try {
3292                 // 0 == continue, -1 = kill process immediately
3293                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3294                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3295             } catch (RemoteException e) {
3296                 mController = null;
3297             }
3298         }
3299
3300         long anrTime = SystemClock.uptimeMillis();
3301         if (MONITOR_CPU_USAGE) {
3302             updateCpuStatsNow();
3303         }
3304         
3305         synchronized (this) {
3306             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3307             if (mShuttingDown) {
3308                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3309                 return;
3310             } else if (app.notResponding) {
3311                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3312                 return;
3313             } else if (app.crashing) {
3314                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3315                 return;
3316             }
3317             
3318             // In case we come through here for the same app before completing
3319             // this one, mark as anring now so we will bail out.
3320             app.notResponding = true;
3321
3322             // Log the ANR to the event log.
3323             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3324                     app.processName, app.info.flags, annotation);
3325
3326             // Dump thread traces as quickly as we can, starting with "interesting" processes.
3327             firstPids.add(app.pid);
3328     
3329             int parentPid = app.pid;
3330             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3331             if (parentPid != app.pid) firstPids.add(parentPid);
3332     
3333             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3334
3335             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3336                 ProcessRecord r = mLruProcesses.get(i);
3337                 if (r != null && r.thread != null) {
3338                     int pid = r.pid;
3339                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3340                         if (r.persistent) {
3341                             firstPids.add(pid);
3342                         } else {
3343                             lastPids.put(pid, Boolean.TRUE);
3344                         }
3345                     }
3346                 }
3347             }
3348         }
3349
3350         // Log the ANR to the main log.
3351         StringBuilder info = new StringBuilder();
3352         info.setLength(0);
3353         info.append("ANR in ").append(app.processName);
3354         if (activity != null && activity.shortComponentName != null) {
3355             info.append(" (").append(activity.shortComponentName).append(")");
3356         }
3357         info.append("\n");
3358         if (annotation != null) {
3359             info.append("Reason: ").append(annotation).append("\n");
3360         }
3361         if (parent != null && parent != activity) {
3362             info.append("Parent: ").append(parent.shortComponentName).append("\n");
3363         }
3364
3365         final ProcessStats processStats = new ProcessStats(true);
3366
3367         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3368
3369         String cpuInfo = null;
3370         if (MONITOR_CPU_USAGE) {
3371             updateCpuStatsNow();
3372             synchronized (mProcessStatsThread) {
3373                 cpuInfo = mProcessStats.printCurrentState(anrTime);
3374             }
3375             info.append(processStats.printCurrentLoad());
3376             info.append(cpuInfo);
3377         }
3378
3379         info.append(processStats.printCurrentState(anrTime));
3380
3381         Slog.e(TAG, info.toString());
3382         if (tracesFile == null) {
3383             // There is no trace file, so dump (only) the alleged culprit's threads to the log
3384             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3385         }
3386
3387         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3388                 cpuInfo, tracesFile, null);
3389
3390         if (mController != null) {
3391             try {
3392                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3393                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3394                 if (res != 0) {
3395                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3396                     return;
3397                 }
3398             } catch (RemoteException e) {
3399                 mController = null;
3400             }
3401         }
3402
3403         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3404         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3405                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3406         
3407         synchronized (this) {
3408             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3409                 Slog.w(TAG, "Killing " + app + ": background ANR");
3410                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3411                         app.processName, app.setAdj, "background ANR");
3412                 Process.killProcessQuiet(app.pid);
3413                 return;
3414             }
3415     
3416             // Set the app's notResponding state, and look up the errorReportReceiver
3417             makeAppNotRespondingLocked(app,
3418                     activity != null ? activity.shortComponentName : null,
3419                     annotation != null ? "ANR " + annotation : "ANR",
3420                     info.toString());
3421     
3422             // Bring up the infamous App Not Responding dialog
3423             Message msg = Message.obtain();
3424             HashMap map = new HashMap();
3425             msg.what = SHOW_NOT_RESPONDING_MSG;
3426             msg.obj = map;
3427             msg.arg1 = aboveSystem ? 1 : 0;
3428             map.put("app", app);
3429             if (activity != null) {
3430                 map.put("activity", activity);
3431             }
3432     
3433             mHandler.sendMessage(msg);
3434         }
3435     }
3436
3437     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3438         if (!mLaunchWarningShown) {
3439             mLaunchWarningShown = true;
3440             mHandler.post(new Runnable() {
3441                 @Override
3442                 public void run() {
3443                     synchronized (ActivityManagerService.this) {
3444                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3445                         d.show();
3446                         mHandler.postDelayed(new Runnable() {
3447                             @Override
3448                             public void run() {
3449                                 synchronized (ActivityManagerService.this) {
3450                                     d.dismiss();
3451                                     mLaunchWarningShown = false;
3452                                 }
3453                             }
3454                         }, 4000);
3455                     }
3456                 }
3457             });
3458         }
3459     }
3460     
3461     public boolean clearApplicationUserData(final String packageName,
3462             final IPackageDataObserver observer, int userId) {
3463         enforceNotIsolatedCaller("clearApplicationUserData");
3464         int uid = Binder.getCallingUid();
3465         int pid = Binder.getCallingPid();
3466         userId = handleIncomingUser(pid, uid,
3467                 userId, false, true, "clearApplicationUserData", null);
3468         long callingId = Binder.clearCallingIdentity();
3469         try {
3470             IPackageManager pm = AppGlobals.getPackageManager();
3471             int pkgUid = -1;
3472             synchronized(this) {
3473                 try {
3474                     pkgUid = pm.getPackageUid(packageName, userId);
3475                 } catch (RemoteException e) {
3476                 }
3477                 if (pkgUid == -1) {
3478                     Slog.w(TAG, "Invalid packageName:" + packageName);
3479                     return false;
3480                 }
3481                 if (uid == pkgUid || checkComponentPermission(
3482                         android.Manifest.permission.CLEAR_APP_USER_DATA,
3483                         pid, uid, -1, true)
3484                         == PackageManager.PERMISSION_GRANTED) {
3485                     forceStopPackageLocked(packageName, pkgUid);
3486                 } else {
3487                     throw new SecurityException(pid+" does not have permission:"+
3488                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3489                                     "for process:"+packageName);
3490                 }
3491             }
3492             
3493             try {
3494                 //clear application user data
3495                 pm.clearApplicationUserData(packageName, observer, userId);
3496                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3497                         Uri.fromParts("package", packageName, null));
3498                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
3499                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3500                         null, null, 0, null, null, null, false, false, userId);
3501             } catch (RemoteException e) {
3502             }
3503         } finally {
3504             Binder.restoreCallingIdentity(callingId);
3505         }
3506         return true;
3507     }
3508
3509     public void killBackgroundProcesses(final String packageName, int userId) {
3510         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3511                 != PackageManager.PERMISSION_GRANTED &&
3512                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3513                         != PackageManager.PERMISSION_GRANTED) {
3514             String msg = "Permission Denial: killBackgroundProcesses() from pid="
3515                     + Binder.getCallingPid()
3516                     + ", uid=" + Binder.getCallingUid()
3517                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3518             Slog.w(TAG, msg);
3519             throw new SecurityException(msg);
3520         }
3521
3522         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3523                 userId, true, true, "killBackgroundProcesses", null);
3524         long callingId = Binder.clearCallingIdentity();
3525         try {
3526             IPackageManager pm = AppGlobals.getPackageManager();
3527             synchronized(this) {
3528                 int appId = -1;
3529                 try {
3530                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3531                 } catch (RemoteException e) {
3532                 }
3533                 if (appId == -1) {
3534                     Slog.w(TAG, "Invalid packageName: " + packageName);
3535                     return;
3536                 }
3537                 killPackageProcessesLocked(packageName, appId, userId,
3538                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3539             }
3540         } finally {
3541             Binder.restoreCallingIdentity(callingId);
3542         }
3543     }
3544
3545     public void killAllBackgroundProcesses() {
3546         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3547                 != PackageManager.PERMISSION_GRANTED) {
3548             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3549                     + Binder.getCallingPid()
3550                     + ", uid=" + Binder.getCallingUid()
3551                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3552             Slog.w(TAG, msg);
3553             throw new SecurityException(msg);
3554         }
3555         
3556         long callingId = Binder.clearCallingIdentity();
3557         try {
3558             synchronized(this) {
3559                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3560                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3561                     final int NA = apps.size();
3562                     for (int ia=0; ia<NA; ia++) {
3563                         ProcessRecord app = apps.valueAt(ia);
3564                         if (app.persistent) {
3565                             // we don't kill persistent processes
3566                             continue;
3567                         }
3568                         if (app.removed) {
3569                             procs.add(app);
3570                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3571                             app.removed = true;
3572                             procs.add(app);
3573                         }
3574                     }
3575                 }
3576                 
3577                 int N = procs.size();
3578                 for (int i=0; i<N; i++) {
3579                     removeProcessLocked(procs.get(i), false, true, "kill all background");
3580                 }
3581             }
3582         } finally {
3583             Binder.restoreCallingIdentity(callingId);
3584         }
3585     }
3586
3587     public void forceStopPackage(final String packageName, int userId) {
3588         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3589                 != PackageManager.PERMISSION_GRANTED) {
3590             String msg = "Permission Denial: forceStopPackage() from pid="
3591                     + Binder.getCallingPid()
3592                     + ", uid=" + Binder.getCallingUid()
3593                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3594             Slog.w(TAG, msg);
3595             throw new SecurityException(msg);
3596         }
3597         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3598                 userId, true, true, "forceStopPackage", null);
3599         long callingId = Binder.clearCallingIdentity();
3600         try {
3601             IPackageManager pm = AppGlobals.getPackageManager();
3602             synchronized(this) {
3603                 int[] users = userId == UserHandle.USER_ALL
3604                         ? getUsersLocked() : new int[] { userId };
3605                 for (int user : users) {
3606                     int pkgUid = -1;
3607                     try {
3608                         pkgUid = pm.getPackageUid(packageName, user);
3609                     } catch (RemoteException e) {
3610                     }
3611                     if (pkgUid == -1) {
3612                         Slog.w(TAG, "Invalid packageName: " + packageName);
3613                         continue;
3614                     }
3615                     try {
3616                         pm.setPackageStoppedState(packageName, true, user);
3617                     } catch (RemoteException e) {
3618                     } catch (IllegalArgumentException e) {
3619                         Slog.w(TAG, "Failed trying to unstop package "
3620                                 + packageName + ": " + e);
3621                     }
3622                     if (isUserRunningLocked(user, false)) {
3623                         forceStopPackageLocked(packageName, pkgUid);
3624                     }
3625                 }
3626             }
3627         } finally {
3628             Binder.restoreCallingIdentity(callingId);
3629         }
3630     }
3631
3632     /*
3633      * The pkg name and app id have to be specified.
3634      */
3635     public void killApplicationWithAppId(String pkg, int appid) {
3636         if (pkg == null) {
3637             return;
3638         }
3639         // Make sure the uid is valid.
3640         if (appid < 0) {
3641             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3642             return;
3643         }
3644         int callerUid = Binder.getCallingUid();
3645         // Only the system server can kill an application
3646         if (callerUid == Process.SYSTEM_UID) {
3647             // Post an aysnc message to kill the application
3648             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3649             msg.arg1 = appid;
3650             msg.arg2 = 0;
3651             msg.obj = pkg;
3652             mHandler.sendMessage(msg);
3653         } else {
3654             throw new SecurityException(callerUid + " cannot kill pkg: " +
3655                     pkg);
3656         }
3657     }
3658
3659     public void closeSystemDialogs(String reason) {
3660         enforceNotIsolatedCaller("closeSystemDialogs");
3661
3662         final int pid = Binder.getCallingPid();
3663         final int uid = Binder.getCallingUid();
3664         final long origId = Binder.clearCallingIdentity();
3665         try {
3666             synchronized (this) {
3667                 // Only allow this from foreground processes, so that background
3668                 // applications can't abuse it to prevent system UI from being shown.
3669                 if (uid >= Process.FIRST_APPLICATION_UID) {
3670                     ProcessRecord proc;
3671                     synchronized (mPidsSelfLocked) {
3672                         proc = mPidsSelfLocked.get(pid);
3673                     }
3674                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3675                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3676                                 + " from background process " + proc);
3677                         return;
3678                     }
3679                 }
3680                 closeSystemDialogsLocked(reason);
3681             }
3682         } finally {
3683             Binder.restoreCallingIdentity(origId);
3684         }
3685     }
3686
3687     void closeSystemDialogsLocked(String reason) {
3688         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3689         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3690                 | Intent.FLAG_RECEIVER_FOREGROUND);
3691         if (reason != null) {
3692             intent.putExtra("reason", reason);
3693         }
3694         mWindowManager.closeSystemDialogs(reason);
3695
3696         for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3697             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3698             if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3699                 r.stack.finishActivityLocked(r, i,
3700                         Activity.RESULT_CANCELED, null, "close-sys", true);
3701             }
3702         }
3703
3704         broadcastIntentLocked(null, null, intent, null,
3705                 null, 0, null, null, null, false, false, -1,
3706                 Process.SYSTEM_UID, UserHandle.USER_ALL);
3707     }
3708
3709     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3710             throws RemoteException {
3711         enforceNotIsolatedCaller("getProcessMemoryInfo");
3712         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3713         for (int i=pids.length-1; i>=0; i--) {
3714             infos[i] = new Debug.MemoryInfo();
3715             Debug.getMemoryInfo(pids[i], infos[i]);
3716         }
3717         return infos;
3718     }
3719
3720     public long[] getProcessPss(int[] pids) throws RemoteException {
3721         enforceNotIsolatedCaller("getProcessPss");
3722         long[] pss = new long[pids.length];
3723         for (int i=pids.length-1; i>=0; i--) {
3724             pss[i] = Debug.getPss(pids[i]);
3725         }
3726         return pss;
3727     }
3728
3729     public void killApplicationProcess(String processName, int uid) {
3730         if (processName == null) {
3731             return;
3732         }
3733
3734         int callerUid = Binder.getCallingUid();
3735         // Only the system server can kill an application
3736         if (callerUid == Process.SYSTEM_UID) {
3737             synchronized (this) {
3738                 ProcessRecord app = getProcessRecordLocked(processName, uid);
3739                 if (app != null && app.thread != null) {
3740                     try {
3741                         app.thread.scheduleSuicide();
3742                     } catch (RemoteException e) {
3743                         // If the other end already died, then our work here is done.
3744                     }
3745                 } else {
3746                     Slog.w(TAG, "Process/uid not found attempting kill of "
3747                             + processName + " / " + uid);
3748                 }
3749             }
3750         } else {
3751             throw new SecurityException(callerUid + " cannot kill app process: " +
3752                     processName);
3753         }
3754     }
3755
3756     private void forceStopPackageLocked(final String packageName, int uid) {
3757         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3758                 false, true, false, UserHandle.getUserId(uid));
3759         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3760                 Uri.fromParts("package", packageName, null));
3761         if (!mProcessesReady) {
3762             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3763                     | Intent.FLAG_RECEIVER_FOREGROUND);
3764         }
3765         intent.putExtra(Intent.EXTRA_UID, uid);
3766         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3767         broadcastIntentLocked(null, null, intent,
3768                 null, null, 0, null, null, null,
3769                 false, false,
3770                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3771     }
3772
3773     private void forceStopUserLocked(int userId) {
3774         forceStopPackageLocked(null, -1, false, false, true, false, userId);
3775         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3776         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3777                 | Intent.FLAG_RECEIVER_FOREGROUND);
3778         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3779         broadcastIntentLocked(null, null, intent,
3780                 null, null, 0, null, null, null,
3781                 false, false,
3782                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3783     }
3784
3785     private final boolean killPackageProcessesLocked(String packageName, int appId,
3786             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3787             boolean doit, boolean evenPersistent, String reason) {
3788         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3789
3790         // Remove all processes this package may have touched: all with the
3791         // same UID (except for the system or root user), and all whose name
3792         // matches the package name.
3793         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3794         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3795             final int NA = apps.size();
3796             for (int ia=0; ia<NA; ia++) {
3797                 ProcessRecord app = apps.valueAt(ia);
3798                 if (app.persistent && !evenPersistent) {
3799                     // we don't kill persistent processes
3800                     continue;
3801                 }
3802                 if (app.removed) {
3803                     if (doit) {
3804                         procs.add(app);
3805                     }
3806                     continue;
3807                 }
3808
3809                 // Skip process if it doesn't meet our oom adj requirement.
3810                 if (app.setAdj < minOomAdj) {
3811                     continue;
3812                 }
3813
3814                 // If no package is specified, we call all processes under the
3815                 // give user id.
3816                 if (packageName == null) {
3817                     if (app.userId != userId) {
3818                         continue;
3819                     }
3820                 // Package has been specified, we want to hit all processes
3821                 // that match it.  We need to qualify this by the processes
3822                 // that are running under the specified app and user ID.
3823                 } else {
3824                     if (UserHandle.getAppId(app.uid) != appId) {
3825                         continue;
3826                     }
3827                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
3828                         continue;
3829                     }
3830                     if (!app.pkgList.contains(packageName)) {
3831                         continue;
3832                     }
3833                 }
3834
3835                 // Process has passed all conditions, kill it!
3836                 if (!doit) {
3837                     return true;
3838                 }
3839                 app.removed = true;
3840                 procs.add(app);
3841             }
3842         }
3843         
3844         int N = procs.size();
3845         for (int i=0; i<N; i++) {
3846             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3847         }
3848         return N > 0;
3849     }
3850
3851     private final boolean forceStopPackageLocked(String name, int appId,
3852             boolean callerWillRestart, boolean purgeCache, boolean doit,
3853             boolean evenPersistent, int userId) {
3854         int i;
3855         int N;
3856
3857         if (userId == UserHandle.USER_ALL && name == null) {
3858             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3859         }
3860
3861         if (appId < 0 && name != null) {
3862             try {
3863                 appId = UserHandle.getAppId(
3864                         AppGlobals.getPackageManager().getPackageUid(name, 0));
3865             } catch (RemoteException e) {
3866             }
3867         }
3868
3869         if (doit) {
3870             if (name != null) {
3871                 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3872                         + " user=" + userId);
3873             } else {
3874                 Slog.i(TAG, "Force stopping user " + userId);
3875             }
3876
3877             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3878             while (badApps.hasNext()) {
3879                 SparseArray<Long> ba = badApps.next();
3880                 for (i=ba.size()-1; i>=0; i--) {
3881                     boolean remove = false;
3882                     final int entUid = ba.keyAt(i);
3883                     if (name != null) {
3884                         if (userId == UserHandle.USER_ALL) {
3885                             if (UserHandle.getAppId(entUid) == appId) {
3886                                 remove = true;
3887                             }
3888                         } else {
3889                             if (entUid == UserHandle.getUid(userId, appId)) {
3890                                 remove = true;
3891                             }
3892                         }
3893                     } else if (UserHandle.getUserId(entUid) == userId) {
3894                         remove = true;
3895                     }
3896                     if (remove) {
3897                         ba.removeAt(i);
3898                     }
3899                 }
3900                 if (ba.size() == 0) {
3901                     badApps.remove();
3902                 }
3903             }
3904         }
3905
3906         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3907                 -100, callerWillRestart, true, doit, evenPersistent,
3908                 name == null ? ("force stop user " + userId) : ("force stop " + name));
3909         
3910         TaskRecord lastTask = null;
3911         for (i=0; i<mMainStack.mHistory.size(); i++) {
3912             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3913             final boolean samePackage = r.packageName.equals(name)
3914                     || (name == null && r.userId == userId);
3915             if ((userId == UserHandle.USER_ALL || r.userId == userId)
3916                     && (samePackage || r.task == lastTask)
3917                     && (r.app == null || evenPersistent || !r.app.persistent)) {
3918                 if (!doit) {
3919                     if (r.finishing) {
3920                         // If this activity is just finishing, then it is not
3921                         // interesting as far as something to stop.
3922                         continue;
3923                     }
3924                     return true;
3925                 }
3926                 didSomething = true;
3927                 Slog.i(TAG, "  Force finishing activity " + r);
3928                 if (samePackage) {
3929                     if (r.app != null) {
3930                         r.app.removed = true;
3931                     }
3932                     r.app = null;
3933                 }
3934                 lastTask = r.task;
3935                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3936                         null, "force-stop", true)) {
3937                     i--;
3938                 }
3939             }
3940         }
3941
3942         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3943             if (!doit) {
3944                 return true;
3945             }
3946             didSomething = true;
3947         }
3948
3949         if (name == null) {
3950             // Remove all sticky broadcasts from this user.
3951             mStickyBroadcasts.remove(userId);
3952         }
3953
3954         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3955         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3956                 userId, providers)) {
3957             if (!doit) {
3958                 return true;
3959             }
3960             didSomething = true;
3961         }
3962         N = providers.size();
3963         for (i=0; i<N; i++) {
3964             removeDyingProviderLocked(null, providers.get(i), true);
3965         }
3966
3967         if (name == null) {
3968             // Remove pending intents.  For now we only do this when force
3969             // stopping users, because we have some problems when doing this
3970             // for packages -- app widgets are not currently cleaned up for
3971             // such packages, so they can be left with bad pending intents.
3972             if (mIntentSenderRecords.size() > 0) {
3973                 Iterator<WeakReference<PendingIntentRecord>> it
3974                         = mIntentSenderRecords.values().iterator();
3975                 while (it.hasNext()) {
3976                     WeakReference<PendingIntentRecord> wpir = it.next();
3977                     if (wpir == null) {
3978                         it.remove();
3979                         continue;
3980                     }
3981                     PendingIntentRecord pir = wpir.get();
3982                     if (pir == null) {
3983                         it.remove();
3984                         continue;
3985                     }
3986                     if (name == null) {
3987                         // Stopping user, remove all objects for the user.
3988                         if (pir.key.userId != userId) {
3989                             // Not the same user, skip it.
3990                             continue;
3991                         }
3992                     } else {
3993                         if (UserHandle.getAppId(pir.uid) != appId) {
3994                             // Different app id, skip it.
3995                             continue;
3996                         }
3997                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3998                             // Different user, skip it.
3999                             continue;
4000                         }
4001                         if (!pir.key.packageName.equals(name)) {
4002                             // Different package, skip it.
4003                             continue;
4004                         }
4005                     }
4006                     if (!doit) {
4007                         return true;
4008                     }
4009                     didSomething = true;
4010                     it.remove();
4011                     pir.canceled = true;
4012                     if (pir.key.activity != null) {
4013                         pir.key.activity.pendingResults.remove(pir.ref);
4014                     }
4015                 }
4016             }
4017         }
4018
4019         if (doit) {
4020             if (purgeCache && name != null) {
4021                 AttributeCache ac = AttributeCache.instance();
4022                 if (ac != null) {
4023                     ac.removePackage(name);
4024                 }
4025             }
4026             if (mBooted) {
4027                 mMainStack.resumeTopActivityLocked(null);
4028                 mMainStack.scheduleIdleLocked();
4029             }
4030         }
4031         
4032         return didSomething;
4033     }
4034
4035     private final boolean removeProcessLocked(ProcessRecord app,
4036             boolean callerWillRestart, boolean allowRestart, String reason) {
4037         final String name = app.processName;
4038         final int uid = app.uid;
4039         if (DEBUG_PROCESSES) Slog.d(
4040             TAG, "Force removing proc " + app.toShortString() + " (" + name
4041             + "/" + uid + ")");
4042
4043         mProcessNames.remove(name, uid);
4044         mIsolatedProcesses.remove(app.uid);
4045         if (mHeavyWeightProcess == app) {
4046             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4047                     mHeavyWeightProcess.userId, 0));
4048             mHeavyWeightProcess = null;
4049         }
4050         boolean needRestart = false;
4051         if (app.pid > 0 && app.pid != MY_PID) {
4052             int pid = app.pid;
4053             synchronized (mPidsSelfLocked) {
4054                 mPidsSelfLocked.remove(pid);
4055                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4056             }
4057             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4058             handleAppDiedLocked(app, true, allowRestart);
4059             mLruProcesses.remove(app);
4060             Process.killProcessQuiet(pid);
4061             
4062             if (app.persistent && !app.isolated) {
4063                 if (!callerWillRestart) {
4064                     addAppLocked(app.info, false);
4065                 } else {
4066                     needRestart = true;
4067                 }
4068             }
4069         } else {
4070             mRemovedProcesses.add(app);
4071         }
4072         
4073         return needRestart;
4074     }
4075
4076     private final void processStartTimedOutLocked(ProcessRecord app) {
4077         final int pid = app.pid;
4078         boolean gone = false;
4079         synchronized (mPidsSelfLocked) {
4080             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4081             if (knownApp != null && knownApp.thread == null) {
4082                 mPidsSelfLocked.remove(pid);
4083                 gone = true;
4084             }        
4085         }
4086         
4087         if (gone) {
4088             Slog.w(TAG, "Process " + app + " failed to attach");
4089             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4090                     pid, app.uid, app.processName);
4091             mProcessNames.remove(app.processName, app.uid);
4092             mIsolatedProcesses.remove(app.uid);
4093             if (mHeavyWeightProcess == app) {
4094                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4095                         mHeavyWeightProcess.userId, 0));
4096                 mHeavyWeightProcess = null;
4097             }
4098             // Take care of any launching providers waiting for this process.
4099             checkAppInLaunchingProvidersLocked(app, true);
4100             // Take care of any services that are waiting for the process.
4101             mServices.processStartTimedOutLocked(app);
4102             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4103                     app.processName, app.setAdj, "start timeout");
4104             Process.killProcessQuiet(pid);
4105             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4106                 Slog.w(TAG, "Unattached app died before backup, skipping");
4107                 try {
4108                     IBackupManager bm = IBackupManager.Stub.asInterface(
4109                             ServiceManager.getService(Context.BACKUP_SERVICE));
4110                     bm.agentDisconnected(app.info.packageName);
4111                 } catch (RemoteException e) {
4112                     // Can't happen; the backup manager is local
4113                 }
4114             }
4115             if (isPendingBroadcastProcessLocked(pid)) {
4116                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4117                 skipPendingBroadcastLocked(pid);
4118             }
4119         } else {
4120             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4121         }
4122     }
4123
4124     private final boolean attachApplicationLocked(IApplicationThread thread,
4125             int pid) {
4126
4127         // Find the application record that is being attached...  either via
4128         // the pid if we are running in multiple processes, or just pull the
4129         // next app record if we are emulating process with anonymous threads.
4130         ProcessRecord app;
4131         if (pid != MY_PID && pid >= 0) {
4132             synchronized (mPidsSelfLocked) {
4133                 app = mPidsSelfLocked.get(pid);
4134             }
4135         } else {
4136             app = null;
4137         }
4138
4139         if (app == null) {
4140             Slog.w(TAG, "No pending application record for pid " + pid
4141                     + " (IApplicationThread " + thread + "); dropping process");
4142             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4143             if (pid > 0 && pid != MY_PID) {
4144                 Process.killProcessQuiet(pid);
4145             } else {
4146                 try {
4147                     thread.scheduleExit();
4148                 } catch (Exception e) {
4149                     // Ignore exceptions.
4150                 }
4151             }
4152             return false;
4153         }
4154
4155         // If this application record is still attached to a previous
4156         // process, clean it up now.
4157         if (app.thread != null) {
4158             handleAppDiedLocked(app, true, true);
4159         }
4160
4161         // Tell the process all about itself.
4162
4163         if (localLOGV) Slog.v(
4164                 TAG, "Binding process pid " + pid + " to record " + app);
4165
4166         String processName = app.processName;
4167         try {
4168             AppDeathRecipient adr = new AppDeathRecipient(
4169                     app, pid, thread);
4170             thread.asBinder().linkToDeath(adr, 0);
4171             app.deathRecipient = adr;
4172         } catch (RemoteException e) {
4173             app.resetPackageList();
4174             startProcessLocked(app, "link fail", processName);
4175             return false;
4176         }
4177
4178         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4179         
4180         app.thread = thread;
4181         app.curAdj = app.setAdj = -100;
4182         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4183         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4184         app.forcingToForeground = null;
4185         app.foregroundServices = false;
4186         app.hasShownUi = false;
4187         app.debugging = false;
4188
4189         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4190
4191         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4192         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4193
4194         if (!normalMode) {
4195             Slog.i(TAG, "Launching preboot mode app: " + app);
4196         }
4197         
4198         if (localLOGV) Slog.v(
4199             TAG, "New app record " + app
4200             + " thread=" + thread.asBinder() + " pid=" + pid);
4201         try {
4202             int testMode = IApplicationThread.DEBUG_OFF;
4203             if (mDebugApp != null && mDebugApp.equals(processName)) {
4204                 testMode = mWaitForDebugger
4205                     ? IApplicationThread.DEBUG_WAIT
4206                     : IApplicationThread.DEBUG_ON;
4207                 app.debugging = true;
4208                 if (mDebugTransient) {
4209                     mDebugApp = mOrigDebugApp;
4210                     mWaitForDebugger = mOrigWaitForDebugger;
4211                 }
4212             }
4213             String profileFile = app.instrumentationProfileFile;
4214             ParcelFileDescriptor profileFd = null;
4215             boolean profileAutoStop = false;
4216             if (mProfileApp != null && mProfileApp.equals(processName)) {
4217                 mProfileProc = app;
4218                 profileFile = mProfileFile;
4219                 profileFd = mProfileFd;
4220                 profileAutoStop = mAutoStopProfiler;
4221             }
4222             boolean enableOpenGlTrace = false;
4223             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4224                 enableOpenGlTrace = true;
4225                 mOpenGlTraceApp = null;
4226             }
4227
4228             // If the app is being launched for restore or full backup, set it up specially
4229             boolean isRestrictedBackupMode = false;
4230             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4231                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4232                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4233                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4234             }
4235             
4236             ensurePackageDexOpt(app.instrumentationInfo != null
4237                     ? app.instrumentationInfo.packageName
4238                     : app.info.packageName);
4239             if (app.instrumentationClass != null) {
4240                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4241             }
4242             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4243                     + processName + " with config " + mConfiguration);
4244             ApplicationInfo appInfo = app.instrumentationInfo != null
4245                     ? app.instrumentationInfo : app.info;
4246             app.compat = compatibilityInfoForPackageLocked(appInfo);
4247             if (profileFd != null) {
4248                 profileFd = profileFd.dup();
4249             }
4250             thread.bindApplication(processName, appInfo, providers,
4251                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4252                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
4253                     enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4254                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4255                     mCoreSettingsObserver.getCoreSettingsLocked());
4256             updateLruProcessLocked(app, false);
4257             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4258         } catch (Exception e) {
4259             // todo: Yikes!  What should we do?  For now we will try to
4260             // start another process, but that could easily get us in
4261             // an infinite loop of restarting processes...
4262             Slog.w(TAG, "Exception thrown during bind!", e);
4263
4264             app.resetPackageList();
4265             app.unlinkDeathRecipient();
4266             startProcessLocked(app, "bind fail", processName);
4267             return false;
4268         }
4269
4270         // Remove this record from the list of starting applications.
4271         mPersistentStartingProcesses.remove(app);
4272         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4273                 "Attach application locked removing on hold: " + app);
4274         mProcessesOnHold.remove(app);
4275
4276         boolean badApp = false;
4277         boolean didSomething = false;
4278
4279         // See if the top visible activity is waiting to run in this process...
4280         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4281         if (hr != null && normalMode) {
4282             if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4283                     && processName.equals(hr.processName)) {
4284                 try {
4285                     if (mHeadless) {
4286                         Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4287                     } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4288                         didSomething = true;
4289                     }
4290                 } catch (Exception e) {
4291                     Slog.w(TAG, "Exception in new application when starting activity "
4292                           + hr.intent.getComponent().flattenToShortString(), e);
4293                     badApp = true;
4294                 }
4295             } else {
4296                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4297             }
4298         }
4299
4300         // Find any services that should be running in this process...
4301         if (!badApp) {
4302             try {
4303                 didSomething |= mServices.attachApplicationLocked(app, processName);
4304             } catch (Exception e) {
4305                 badApp = true;
4306             }
4307         }
4308
4309         // Check if a next-broadcast receiver is in this process...
4310         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4311             try {
4312                 didSomething = sendPendingBroadcastsLocked(app);
4313             } catch (Exception e) {
4314                 // If the app died trying to launch the receiver we declare it 'bad'
4315                 badApp = true;
4316             }
4317         }
4318
4319         // Check whether the next backup agent is in this process...
4320         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4321             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4322             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4323             try {
4324                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4325                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4326                         mBackupTarget.backupMode);
4327             } catch (Exception e) {
4328                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
4329                 e.printStackTrace();
4330             }
4331         }
4332
4333         if (badApp) {
4334             // todo: Also need to kill application to deal with all
4335             // kinds of exceptions.
4336             handleAppDiedLocked(app, false, true);
4337             return false;
4338         }
4339
4340         if (!didSomething) {
4341             updateOomAdjLocked();
4342         }
4343
4344         return true;
4345     }
4346
4347     public final void attachApplication(IApplicationThread thread) {
4348         synchronized (this) {
4349             int callingPid = Binder.getCallingPid();
4350             final long origId = Binder.clearCallingIdentity();
4351             attachApplicationLocked(thread, callingPid);
4352             Binder.restoreCallingIdentity(origId);
4353         }
4354     }
4355
4356     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4357         final long origId = Binder.clearCallingIdentity();
4358         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4359         if (stopProfiling) {
4360             synchronized (this) {
4361                 if (mProfileProc == r.app) {
4362                     if (mProfileFd != null) {
4363                         try {
4364                             mProfileFd.close();
4365                         } catch (IOException e) {
4366                         }
4367                         clearProfilerLocked();
4368                     }
4369                 }
4370             }
4371         }
4372         Binder.restoreCallingIdentity(origId);
4373     }
4374
4375     void enableScreenAfterBoot() {
4376         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4377                 SystemClock.uptimeMillis());
4378         mWindowManager.enableScreenAfterBoot();
4379
4380         synchronized (this) {
4381             updateEventDispatchingLocked();
4382         }
4383     }
4384
4385     public void showBootMessage(final CharSequence msg, final boolean always) {
4386         enforceNotIsolatedCaller("showBootMessage");
4387         mWindowManager.showBootMessage(msg, always);
4388     }
4389
4390     public void dismissKeyguardOnNextActivity() {
4391         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4392         final long token = Binder.clearCallingIdentity();
4393         try {
4394             synchronized (this) {
4395                 if (mLockScreenShown) {
4396                     mLockScreenShown = false;
4397                     comeOutOfSleepIfNeededLocked();
4398                 }
4399                 mMainStack.dismissKeyguardOnNextActivityLocked();
4400             }
4401         } finally {
4402             Binder.restoreCallingIdentity(token);
4403         }
4404     }
4405
4406     final void finishBooting() {
4407         IntentFilter pkgFilter = new IntentFilter();
4408         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4409         pkgFilter.addDataScheme("package");
4410         mContext.registerReceiver(new BroadcastReceiver() {
4411             @Override
4412             public void onReceive(Context context, Intent intent) {
4413                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4414                 if (pkgs != null) {
4415                     for (String pkg : pkgs) {
4416                         synchronized (ActivityManagerService.this) {
4417                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4418                                 setResultCode(Activity.RESULT_OK);
4419                                 return;
4420                             }
4421                         }
4422                     }
4423                 }
4424             }
4425         }, pkgFilter);
4426
4427         synchronized (this) {
4428             // Ensure that any processes we had put on hold are now started
4429             // up.
4430             final int NP = mProcessesOnHold.size();
4431             if (NP > 0) {
4432                 ArrayList<ProcessRecord> procs =
4433                     new ArrayList<ProcessRecord>(mProcessesOnHold);
4434                 for (int ip=0; ip<NP; ip++) {
4435                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4436                             + procs.get(ip));
4437                     startProcessLocked(procs.get(ip), "on-hold", null);
4438                 }
4439             }
4440             
4441             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4442                 // Start looking for apps that are abusing wake locks.
4443                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4444                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4445                 // Tell anyone interested that we are done booting!
4446                 SystemProperties.set("sys.boot_completed", "1");
4447                 SystemProperties.set("dev.bootcomplete", "1");
4448                 for (int i=0; i<mStartedUsers.size(); i++) {
4449                     UserStartedState uss = mStartedUsers.valueAt(i);
4450                     if (uss.mState == UserStartedState.STATE_BOOTING) {
4451                         uss.mState = UserStartedState.STATE_RUNNING;
4452                         final int userId = mStartedUsers.keyAt(i);
4453                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4454                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4455                         broadcastIntentLocked(null, null, intent,
4456                                 null, null, 0, null, null,
4457                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4458                                 false, false, MY_PID, Process.SYSTEM_UID, userId);
4459                     }
4460                 }
4461             }
4462         }
4463     }
4464     
4465     final void ensureBootCompleted() {
4466         boolean booting;
4467         boolean enableScreen;
4468         synchronized (this) {
4469             booting = mBooting;
4470             mBooting = false;
4471             enableScreen = !mBooted;
4472             mBooted = true;
4473         }
4474         
4475         if (booting) {
4476             finishBooting();
4477         }
4478
4479         if (enableScreen) {
4480             enableScreenAfterBoot();
4481         }
4482     }
4483
4484     public final void activityResumed(IBinder token) {
4485         final long origId = Binder.clearCallingIdentity();
4486         mMainStack.activityResumed(token);
4487         Binder.restoreCallingIdentity(origId);
4488     }
4489
4490     public final void activityPaused(IBinder token) {
4491         final long origId = Binder.clearCallingIdentity();
4492         mMainStack.activityPaused(token, false);
4493         Binder.restoreCallingIdentity(origId);
4494     }
4495
4496     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4497             CharSequence description) {
4498         if (localLOGV) Slog.v(
4499             TAG, "Activity stopped: token=" + token);
4500
4501         // Refuse possible leaked file descriptors
4502         if (icicle != null && icicle.hasFileDescriptors()) {
4503             throw new IllegalArgumentException("File descriptors passed in Bundle");
4504         }
4505
4506         ActivityRecord r = null;
4507
4508         final long origId = Binder.clearCallingIdentity();
4509
4510         synchronized (this) {
4511             r = mMainStack.isInStackLocked(token);
4512             if (r != null) {
4513                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4514             }
4515         }
4516
4517         if (r != null) {
4518             sendPendingThumbnail(r, null, null, null, false);
4519         }
4520
4521         trimApplications();
4522
4523         Binder.restoreCallingIdentity(origId);
4524     }
4525
4526     public final void activityDestroyed(IBinder token) {
4527         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4528         mMainStack.activityDestroyed(token);
4529     }
4530     
4531     public String getCallingPackage(IBinder token) {
4532         synchronized (this) {
4533             ActivityRecord r = getCallingRecordLocked(token);
4534             return r != null && r.app != null ? r.info.packageName : null;
4535         }
4536     }
4537
4538     public ComponentName getCallingActivity(IBinder token) {
4539         synchronized (this) {
4540             ActivityRecord r = getCallingRecordLocked(token);
4541             return r != null ? r.intent.getComponent() : null;
4542         }
4543     }
4544
4545     private ActivityRecord getCallingRecordLocked(IBinder token) {
4546         ActivityRecord r = mMainStack.isInStackLocked(token);
4547         if (r == null) {
4548             return null;
4549         }
4550         return r.resultTo;
4551     }
4552
4553     public ComponentName getActivityClassForToken(IBinder token) {
4554         synchronized(this) {
4555             ActivityRecord r = mMainStack.isInStackLocked(token);
4556             if (r == null) {
4557                 return null;
4558             }
4559             return r.intent.getComponent();
4560         }
4561     }
4562
4563     public String getPackageForToken(IBinder token) {
4564         synchronized(this) {
4565             ActivityRecord r = mMainStack.isInStackLocked(token);
4566             if (r == null) {
4567                 return null;
4568             }
4569             return r.packageName;
4570         }
4571     }
4572
4573     public IIntentSender getIntentSender(int type,
4574             String packageName, IBinder token, String resultWho,
4575             int requestCode, Intent[] intents, String[] resolvedTypes,
4576             int flags, Bundle options, int userId) {
4577         enforceNotIsolatedCaller("getIntentSender");
4578         // Refuse possible leaked file descriptors
4579         if (intents != null) {
4580             if (intents.length < 1) {
4581                 throw new IllegalArgumentException("Intents array length must be >= 1");
4582             }
4583             for (int i=0; i<intents.length; i++) {
4584                 Intent intent = intents[i];
4585                 if (intent != null) {
4586                     if (intent.hasFileDescriptors()) {
4587                         throw new IllegalArgumentException("File descriptors passed in Intent");
4588                     }
4589                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4590                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4591                         throw new IllegalArgumentException(
4592                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4593                     }
4594                     intents[i] = new Intent(intent);
4595                 }
4596             }
4597             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4598                 throw new IllegalArgumentException(
4599                         "Intent array length does not match resolvedTypes length");
4600             }
4601         }
4602         if (options != null) {
4603             if (options.hasFileDescriptors()) {
4604                 throw new IllegalArgumentException("File descriptors passed in options");
4605             }
4606         }
4607         
4608         synchronized(this) {
4609             int callingUid = Binder.getCallingUid();
4610             int origUserId = userId;
4611             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4612                     type == ActivityManager.INTENT_SENDER_BROADCAST, false,
4613                     "getIntentSender", null);
4614             if (origUserId == UserHandle.USER_CURRENT) {
4615                 // We don't want to evaluate this until the pending intent is
4616                 // actually executed.  However, we do want to always do the
4617                 // security checking for it above.
4618                 userId = UserHandle.USER_CURRENT;
4619             }
4620             try {
4621                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4622                     int uid = AppGlobals.getPackageManager()
4623                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4624                     if (!UserHandle.isSameApp(callingUid, uid)) {
4625                         String msg = "Permission Denial: getIntentSender() from pid="
4626                             + Binder.getCallingPid()
4627                             + ", uid=" + Binder.getCallingUid()
4628                             + ", (need uid=" + uid + ")"
4629                             + " is not allowed to send as package " + packageName;
4630                         Slog.w(TAG, msg);
4631                         throw new SecurityException(msg);
4632                     }
4633                 }
4634
4635                 return getIntentSenderLocked(type, packageName, callingUid, userId,
4636                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4637                 
4638             } catch (RemoteException e) {
4639                 throw new SecurityException(e);
4640             }
4641         }
4642     }
4643     
4644     IIntentSender getIntentSenderLocked(int type, String packageName,
4645             int callingUid, int userId, IBinder token, String resultWho,
4646             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4647             Bundle options) {
4648         if (DEBUG_MU)
4649             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4650         ActivityRecord activity = null;
4651         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4652             activity = mMainStack.isInStackLocked(token);
4653             if (activity == null) {
4654                 return null;
4655             }
4656             if (activity.finishing) {
4657                 return null;
4658             }
4659         }
4660
4661         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4662         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4663         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4664         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4665                 |PendingIntent.FLAG_UPDATE_CURRENT);
4666
4667         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4668                 type, packageName, activity, resultWho,
4669                 requestCode, intents, resolvedTypes, flags, options, userId);
4670         WeakReference<PendingIntentRecord> ref;
4671         ref = mIntentSenderRecords.get(key);
4672         PendingIntentRecord rec = ref != null ? ref.get() : null;
4673         if (rec != null) {
4674             if (!cancelCurrent) {
4675                 if (updateCurrent) {
4676                     if (rec.key.requestIntent != null) {
4677                         rec.key.requestIntent.replaceExtras(intents != null ?
4678                                 intents[intents.length - 1] : null);
4679                     }
4680                     if (intents != null) {
4681                         intents[intents.length-1] = rec.key.requestIntent;
4682                         rec.key.allIntents = intents;
4683                         rec.key.allResolvedTypes = resolvedTypes;
4684                     } else {
4685                         rec.key.allIntents = null;
4686                         rec.key.allResolvedTypes = null;
4687                     }
4688                 }
4689                 return rec;
4690             }
4691             rec.canceled = true;
4692             mIntentSenderRecords.remove(key);
4693         }
4694         if (noCreate) {
4695             return rec;
4696         }
4697         rec = new PendingIntentRecord(this, key, callingUid);
4698         mIntentSenderRecords.put(key, rec.ref);
4699         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4700             if (activity.pendingResults == null) {
4701                 activity.pendingResults
4702                         = new HashSet<WeakReference<PendingIntentRecord>>();
4703             }
4704             activity.pendingResults.add(rec.ref);
4705         }
4706         return rec;
4707     }
4708
4709     public void cancelIntentSender(IIntentSender sender) {
4710         if (!(sender instanceof PendingIntentRecord)) {
4711             return;
4712         }
4713         synchronized(this) {
4714             PendingIntentRecord rec = (PendingIntentRecord)sender;
4715             try {
4716                 int uid = AppGlobals.getPackageManager()
4717                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4718                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4719                     String msg = "Permission Denial: cancelIntentSender() from pid="
4720                         + Binder.getCallingPid()
4721                         + ", uid=" + Binder.getCallingUid()
4722                         + " is not allowed to cancel packges "
4723                         + rec.key.packageName;
4724                     Slog.w(TAG, msg);
4725                     throw new SecurityException(msg);
4726                 }
4727             } catch (RemoteException e) {
4728                 throw new SecurityException(e);
4729             }
4730             cancelIntentSenderLocked(rec, true);
4731         }
4732     }
4733
4734     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4735         rec.canceled = true;
4736         mIntentSenderRecords.remove(rec.key);
4737         if (cleanActivity && rec.key.activity != null) {
4738             rec.key.activity.pendingResults.remove(rec.ref);
4739         }
4740     }
4741
4742     public String getPackageForIntentSender(IIntentSender pendingResult) {
4743         if (!(pendingResult instanceof PendingIntentRecord)) {
4744             return null;
4745         }
4746         try {
4747             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4748             return res.key.packageName;
4749         } catch (ClassCastException e) {
4750         }
4751         return null;
4752     }
4753
4754     public int getUidForIntentSender(IIntentSender sender) {
4755         if (sender instanceof PendingIntentRecord) {
4756             try {
4757                 PendingIntentRecord res = (PendingIntentRecord)sender;
4758                 return res.uid;
4759             } catch (ClassCastException e) {
4760             }
4761         }
4762         return -1;
4763     }
4764
4765     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4766         if (!(pendingResult instanceof PendingIntentRecord)) {
4767             return false;
4768         }
4769         try {
4770             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4771             if (res.key.allIntents == null) {
4772                 return false;
4773             }
4774             for (int i=0; i<res.key.allIntents.length; i++) {
4775                 Intent intent = res.key.allIntents[i];
4776                 if (intent.getPackage() != null && intent.getComponent() != null) {
4777                     return false;
4778                 }
4779             }
4780             return true;
4781         } catch (ClassCastException e) {
4782         }
4783         return false;
4784     }
4785
4786     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4787         if (!(pendingResult instanceof PendingIntentRecord)) {
4788             return false;
4789         }
4790         try {
4791             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4792             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4793                 return true;
4794             }
4795             return false;
4796         } catch (ClassCastException e) {
4797         }
4798         return false;
4799     }
4800
4801     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
4802         if (!(pendingResult instanceof PendingIntentRecord)) {
4803             return null;
4804         }
4805         try {
4806             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4807             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
4808         } catch (ClassCastException e) {
4809         }
4810         return null;
4811     }
4812
4813     public void setProcessLimit(int max) {
4814         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4815                 "setProcessLimit()");
4816         synchronized (this) {
4817             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4818             mProcessLimitOverride = max;
4819         }
4820         trimApplications();
4821     }
4822
4823     public int getProcessLimit() {
4824         synchronized (this) {
4825             return mProcessLimitOverride;
4826         }
4827     }
4828
4829     void foregroundTokenDied(ForegroundToken token) {
4830         synchronized (ActivityManagerService.this) {
4831             synchronized (mPidsSelfLocked) {
4832                 ForegroundToken cur
4833                     = mForegroundProcesses.get(token.pid);
4834                 if (cur != token) {
4835                     return;
4836                 }
4837                 mForegroundProcesses.remove(token.pid);
4838                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4839                 if (pr == null) {
4840                     return;
4841                 }
4842                 pr.forcingToForeground = null;
4843                 pr.foregroundServices = false;
4844             }
4845             updateOomAdjLocked();
4846         }
4847     }
4848     
4849     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4850         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4851                 "setProcessForeground()");
4852         synchronized(this) {
4853             boolean changed = false;
4854             
4855             synchronized (mPidsSelfLocked) {
4856                 ProcessRecord pr = mPidsSelfLocked.get(pid);
4857                 if (pr == null && isForeground) {
4858                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4859                     return;
4860                 }
4861                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4862                 if (oldToken != null) {
4863                     oldToken.token.unlinkToDeath(oldToken, 0);
4864                     mForegroundProcesses.remove(pid);
4865                     if (pr != null) {
4866                         pr.forcingToForeground = null;
4867                     }
4868                     changed = true;
4869                 }
4870                 if (isForeground && token != null) {
4871                     ForegroundToken newToken = new ForegroundToken() {
4872                         public void binderDied() {
4873                             foregroundTokenDied(this);
4874                         }
4875                     };
4876                     newToken.pid = pid;
4877                     newToken.token = token;
4878                     try {
4879                         token.linkToDeath(newToken, 0);
4880                         mForegroundProcesses.put(pid, newToken);
4881                         pr.forcingToForeground = token;
4882                         changed = true;
4883                     } catch (RemoteException e) {
4884                         // If the process died while doing this, we will later
4885                         // do the cleanup with the process death link.
4886                     }
4887                 }
4888             }
4889             
4890             if (changed) {
4891                 updateOomAdjLocked();
4892             }
4893         }
4894     }
4895     
4896     // =========================================================
4897     // PERMISSIONS
4898     // =========================================================
4899
4900     static class PermissionController extends IPermissionController.Stub {
4901         ActivityManagerService mActivityManagerService;
4902         PermissionController(ActivityManagerService activityManagerService) {
4903             mActivityManagerService = activityManagerService;
4904         }
4905
4906         public boolean checkPermission(String permission, int pid, int uid) {
4907             return mActivityManagerService.checkPermission(permission, pid,
4908                     uid) == PackageManager.PERMISSION_GRANTED;
4909         }
4910     }
4911
4912     /**
4913      * This can be called with or without the global lock held.
4914      */
4915     int checkComponentPermission(String permission, int pid, int uid,
4916             int owningUid, boolean exported) {
4917         // We might be performing an operation on behalf of an indirect binder
4918         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4919         // client identity accordingly before proceeding.
4920         Identity tlsIdentity = sCallerIdentity.get();
4921         if (tlsIdentity != null) {
4922             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4923                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4924             uid = tlsIdentity.uid;
4925             pid = tlsIdentity.pid;
4926         }
4927
4928         if (pid == MY_PID) {
4929             return PackageManager.PERMISSION_GRANTED;
4930         }
4931
4932         return ActivityManager.checkComponentPermission(permission, uid,
4933                 owningUid, exported);
4934     }
4935
4936     /**
4937      * As the only public entry point for permissions checking, this method
4938      * can enforce the semantic that requesting a check on a null global
4939      * permission is automatically denied.  (Internally a null permission
4940      * string is used when calling {@link #checkComponentPermission} in cases
4941      * when only uid-based security is needed.)
4942      * 
4943      * This can be called with or without the global lock held.
4944      */
4945     public int checkPermission(String permission, int pid, int uid) {
4946         if (permission == null) {
4947             return PackageManager.PERMISSION_DENIED;
4948         }
4949         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4950     }
4951
4952     /**
4953      * Binder IPC calls go through the public entry point.
4954      * This can be called with or without the global lock held.
4955      */
4956     int checkCallingPermission(String permission) {
4957         return checkPermission(permission,
4958                 Binder.getCallingPid(),
4959                 UserHandle.getAppId(Binder.getCallingUid()));
4960     }
4961
4962     /**
4963      * This can be called with or without the global lock held.
4964      */
4965     void enforceCallingPermission(String permission, String func) {
4966         if (checkCallingPermission(permission)
4967                 == PackageManager.PERMISSION_GRANTED) {
4968             return;
4969         }
4970
4971         String msg = "Permission Denial: " + func + " from pid="
4972                 + Binder.getCallingPid()
4973                 + ", uid=" + Binder.getCallingUid()
4974                 + " requires " + permission;
4975         Slog.w(TAG, msg);
4976         throw new SecurityException(msg);
4977     }
4978
4979     /**
4980      * Determine if UID is holding permissions required to access {@link Uri} in
4981      * the given {@link ProviderInfo}. Final permission checking is always done
4982      * in {@link ContentProvider}.
4983      */
4984     private final boolean checkHoldingPermissionsLocked(
4985             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4986         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4987                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4988
4989         if (pi.applicationInfo.uid == uid) {
4990             return true;
4991         } else if (!pi.exported) {
4992             return false;
4993         }
4994
4995         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4996         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4997         try {
4998             // check if target holds top-level <provider> permissions
4999             if (!readMet && pi.readPermission != null
5000                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5001                 readMet = true;
5002             }
5003             if (!writeMet && pi.writePermission != null
5004                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5005                 writeMet = true;
5006             }
5007
5008             // track if unprotected read/write is allowed; any denied
5009             // <path-permission> below removes this ability
5010             boolean allowDefaultRead = pi.readPermission == null;
5011             boolean allowDefaultWrite = pi.writePermission == null;
5012
5013             // check if target holds any <path-permission> that match uri
5014             final PathPermission[] pps = pi.pathPermissions;
5015             if (pps != null) {
5016                 final String path = uri.getPath();
5017                 int i = pps.length;
5018                 while (i > 0 && (!readMet || !writeMet)) {
5019                     i--;
5020                     PathPermission pp = pps[i];
5021                     if (pp.match(path)) {
5022                         if (!readMet) {
5023                             final String pprperm = pp.getReadPermission();
5024                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5025                                     + pprperm + " for " + pp.getPath()
5026                                     + ": match=" + pp.match(path)
5027                                     + " check=" + pm.checkUidPermission(pprperm, uid));
5028                             if (pprperm != null) {
5029                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5030                                     readMet = true;
5031                                 } else {
5032                                     allowDefaultRead = false;
5033                                 }
5034                             }
5035                         }
5036                         if (!writeMet) {
5037                             final String ppwperm = pp.getWritePermission();
5038                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5039                                     + ppwperm + " for " + pp.getPath()
5040                                     + ": match=" + pp.match(path)
5041                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
5042                             if (ppwperm != null) {
5043                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5044                                     writeMet = true;
5045                                 } else {
5046                                     allowDefaultWrite = false;
5047                                 }
5048                             }
5049                         }
5050                     }
5051                 }
5052             }
5053
5054             // grant unprotected <provider> read/write, if not blocked by
5055             // <path-permission> above
5056             if (allowDefaultRead) readMet = true;
5057             if (allowDefaultWrite) writeMet = true;
5058
5059         } catch (RemoteException e) {
5060             return false;
5061         }
5062
5063         return readMet && writeMet;
5064     }
5065
5066     private final boolean checkUriPermissionLocked(Uri uri, int uid,
5067             int modeFlags) {
5068         // Root gets to do everything.
5069         if (uid == 0) {
5070             return true;
5071         }
5072         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5073         if (perms == null) return false;
5074         UriPermission perm = perms.get(uri);
5075         if (perm == null) return false;
5076         return (modeFlags&perm.modeFlags) == modeFlags;
5077     }
5078
5079     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5080         enforceNotIsolatedCaller("checkUriPermission");
5081
5082         // Another redirected-binder-call permissions check as in
5083         // {@link checkComponentPermission}.
5084         Identity tlsIdentity = sCallerIdentity.get();
5085         if (tlsIdentity != null) {
5086             uid = tlsIdentity.uid;
5087             pid = tlsIdentity.pid;
5088         }
5089
5090         // Our own process gets to do everything.
5091         if (pid == MY_PID) {
5092             return PackageManager.PERMISSION_GRANTED;
5093         }
5094         synchronized(this) {
5095             return checkUriPermissionLocked(uri, uid, modeFlags)
5096                     ? PackageManager.PERMISSION_GRANTED
5097                     : PackageManager.PERMISSION_DENIED;
5098         }
5099     }
5100
5101     /**
5102      * Check if the targetPkg can be granted permission to access uri by
5103      * the callingUid using the given modeFlags.  Throws a security exception
5104      * if callingUid is not allowed to do this.  Returns the uid of the target
5105      * if the URI permission grant should be performed; returns -1 if it is not
5106      * needed (for example targetPkg already has permission to access the URI).
5107      * If you already know the uid of the target, you can supply it in
5108      * lastTargetUid else set that to -1.
5109      */
5110     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5111             Uri uri, int modeFlags, int lastTargetUid) {
5112         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5113                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5114         if (modeFlags == 0) {
5115             return -1;
5116         }
5117
5118         if (targetPkg != null) {
5119             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5120                     "Checking grant " + targetPkg + " permission to " + uri);
5121         }
5122         
5123         final IPackageManager pm = AppGlobals.getPackageManager();
5124
5125         // If this is not a content: uri, we can't do anything with it.
5126         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5127             if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
5128                     "Can't grant URI permission for non-content URI: " + uri);
5129             return -1;
5130         }
5131
5132         String name = uri.getAuthority();
5133         ProviderInfo pi = null;
5134         ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5135                 UserHandle.getUserId(callingUid));
5136         if (cpr != null) {
5137             pi = cpr.info;
5138         } else {
5139             try {
5140                 pi = pm.resolveContentProvider(name,
5141                         PackageManager.GET_URI_PERMISSION_PATTERNS,
5142                         UserHandle.getUserId(callingUid));
5143             } catch (RemoteException ex) {
5144             }
5145         }
5146         if (pi == null) {
5147             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5148             return -1;
5149         }
5150
5151         int targetUid = lastTargetUid;
5152         if (targetUid < 0 && targetPkg != null) {
5153             try {
5154                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5155                 if (targetUid < 0) {
5156                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5157                             "Can't grant URI permission no uid for: " + targetPkg);
5158                     return -1;
5159                 }
5160             } catch (RemoteException ex) {
5161                 return -1;
5162             }
5163         }
5164
5165         if (targetUid >= 0) {
5166             // First...  does the target actually need this permission?
5167             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5168                 // No need to grant the target this permission.
5169                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5170                         "Target " + targetPkg + " already has full permission to " + uri);
5171                 return -1;
5172             }
5173         } else {
5174             // First...  there is no target package, so can anyone access it?
5175             boolean allowed = pi.exported;
5176             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5177                 if (pi.readPermission != null) {
5178                     allowed = false;
5179                 }
5180             }
5181             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5182                 if (pi.writePermission != null) {
5183                     allowed = false;
5184                 }
5185             }
5186             if (allowed) {
5187                 return -1;
5188             }
5189         }
5190
5191         // Second...  is the provider allowing granting of URI permissions?
5192         if (!pi.grantUriPermissions) {
5193             throw new SecurityException("Provider " + pi.packageName
5194                     + "/" + pi.name
5195                     + " does not allow granting of Uri permissions (uri "
5196                     + uri + ")");
5197         }
5198         if (pi.uriPermissionPatterns != null) {
5199             final int N = pi.uriPermissionPatterns.length;
5200             boolean allowed = false;
5201             for (int i=0; i<N; i++) {
5202                 if (pi.uriPermissionPatterns[i] != null
5203                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5204                     allowed = true;
5205                     break;
5206                 }
5207             }
5208             if (!allowed) {
5209                 throw new SecurityException("Provider " + pi.packageName
5210                         + "/" + pi.name
5211                         + " does not allow granting of permission to path of Uri "
5212                         + uri);
5213             }
5214         }
5215
5216         // Third...  does the caller itself have permission to access
5217         // this uri?
5218         if (callingUid != Process.myUid()) {
5219             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5220                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5221                     throw new SecurityException("Uid " + callingUid
5222                             + " does not have permission to uri " + uri);
5223                 }
5224             }
5225         }
5226
5227         return targetUid;
5228     }
5229
5230     public int checkGrantUriPermission(int callingUid, String targetPkg,
5231             Uri uri, int modeFlags) {
5232         enforceNotIsolatedCaller("checkGrantUriPermission");
5233         synchronized(this) {
5234             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5235         }
5236     }
5237
5238     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5239             Uri uri, int modeFlags, UriPermissionOwner owner) {
5240         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5241                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5242         if (modeFlags == 0) {
5243             return;
5244         }
5245
5246         // So here we are: the caller has the assumed permission
5247         // to the uri, and the target doesn't.  Let's now give this to
5248         // the target.
5249
5250         if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
5251                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5252         
5253         HashMap<Uri, UriPermission> targetUris
5254                 = mGrantedUriPermissions.get(targetUid);
5255         if (targetUris == null) {
5256             targetUris = new HashMap<Uri, UriPermission>();
5257             mGrantedUriPermissions.put(targetUid, targetUris);
5258         }
5259
5260         UriPermission perm = targetUris.get(uri);
5261         if (perm == null) {
5262             perm = new UriPermission(targetUid, uri);
5263             targetUris.put(uri, perm);
5264         }
5265
5266         perm.modeFlags |= modeFlags;
5267         if (owner == null) {
5268             perm.globalModeFlags |= modeFlags;
5269         } else {
5270             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5271                  perm.readOwners.add(owner);
5272                  owner.addReadPermission(perm);
5273             }
5274             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5275                  perm.writeOwners.add(owner);
5276                  owner.addWritePermission(perm);
5277             }
5278         }
5279     }
5280
5281     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5282             int modeFlags, UriPermissionOwner owner) {
5283         if (targetPkg == null) {
5284             throw new NullPointerException("targetPkg");
5285         }
5286
5287         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5288         if (targetUid < 0) {
5289             return;
5290         }
5291
5292         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5293     }
5294
5295     static class NeededUriGrants extends ArrayList<Uri> {
5296         final String targetPkg;
5297         final int targetUid;
5298         final int flags;
5299
5300         NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5301             targetPkg = _targetPkg;
5302             targetUid = _targetUid;
5303             flags = _flags;
5304         }
5305     }
5306
5307     /**
5308      * Like checkGrantUriPermissionLocked, but takes an Intent.
5309      */
5310     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5311             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5312         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5313                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5314                 + " clip=" + (intent != null ? intent.getClipData() : null)
5315                 + " from " + intent + "; flags=0x"
5316                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5317
5318         if (targetPkg == null) {
5319             throw new NullPointerException("targetPkg");
5320         }
5321
5322         if (intent == null) {
5323             return null;
5324         }
5325         Uri data = intent.getData();
5326         ClipData clip = intent.getClipData();
5327         if (data == null && clip == null) {
5328             return null;
5329         }
5330         if (data != null) {
5331             int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5332                 mode, needed != null ? needed.targetUid : -1);
5333             if (target > 0) {
5334                 if (needed == null) {
5335                     needed = new NeededUriGrants(targetPkg, target, mode);
5336                 }
5337                 needed.add(data);
5338             }
5339         }
5340         if (clip != null) {
5341             for (int i=0; i<clip.getItemCount(); i++) {
5342                 Uri uri = clip.getItemAt(i).getUri();
5343                 if (uri != null) {
5344                     int target = -1;
5345                     target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5346                             mode, needed != null ? needed.targetUid : -1);
5347                     if (target > 0) {
5348                         if (needed == null) {
5349                             needed = new NeededUriGrants(targetPkg, target, mode);
5350                         }
5351                         needed.add(uri);
5352                     }
5353                 } else {
5354                     Intent clipIntent = clip.getItemAt(i).getIntent();
5355                     if (clipIntent != null) {
5356                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5357                                 callingUid, targetPkg, clipIntent, mode, needed);
5358                         if (newNeeded != null) {
5359                             needed = newNeeded;
5360                         }
5361                     }
5362                 }
5363             }
5364         }
5365
5366         return needed;
5367     }
5368
5369     /**
5370      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5371      */
5372     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5373             UriPermissionOwner owner) {
5374         if (needed != null) {
5375             for (int i=0; i<needed.size(); i++) {
5376                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5377                         needed.get(i), needed.flags, owner);
5378             }
5379         }
5380     }
5381
5382     void grantUriPermissionFromIntentLocked(int callingUid,
5383             String targetPkg, Intent intent, UriPermissionOwner owner) {
5384         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5385                 intent, intent != null ? intent.getFlags() : 0, null);
5386         if (needed == null) {
5387             return;
5388         }
5389
5390         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5391     }
5392
5393     public void grantUriPermission(IApplicationThread caller, String targetPkg,
5394             Uri uri, int modeFlags) {
5395         enforceNotIsolatedCaller("grantUriPermission");
5396         synchronized(this) {
5397             final ProcessRecord r = getRecordForAppLocked(caller);
5398             if (r == null) {
5399                 throw new SecurityException("Unable to find app for caller "
5400                         + caller
5401                         + " when granting permission to uri " + uri);
5402             }
5403             if (targetPkg == null) {
5404                 throw new IllegalArgumentException("null target");
5405             }
5406             if (uri == null) {
5407                 throw new IllegalArgumentException("null uri");
5408             }
5409
5410             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5411                     null);
5412         }
5413     }
5414
5415     void removeUriPermissionIfNeededLocked(UriPermission perm) {
5416         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5417                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5418             HashMap<Uri, UriPermission> perms
5419                     = mGrantedUriPermissions.get(perm.uid);
5420             if (perms != null) {
5421                 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
5422                         "Removing " + perm.uid + " permission to " + perm.uri);
5423                 perms.remove(perm.uri);
5424                 if (perms.size() == 0) {
5425                     mGrantedUriPermissions.remove(perm.uid);
5426                 }
5427             }
5428         }
5429     }
5430
5431     private void revokeUriPermissionLocked(int callingUid, Uri uri,
5432             int modeFlags) {
5433         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5434                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5435         if (modeFlags == 0) {
5436             return;
5437         }
5438
5439         if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
5440                 "Revoking all granted permissions to " + uri);
5441         
5442         final IPackageManager pm = AppGlobals.getPackageManager();
5443
5444         final String authority = uri.getAuthority();
5445         ProviderInfo pi = null;
5446         int userId = UserHandle.getUserId(callingUid);
5447         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5448         if (cpr != null) {
5449             pi = cpr.info;
5450         } else {
5451             try {
5452                 pi = pm.resolveContentProvider(authority,
5453                         PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5454             } catch (RemoteException ex) {
5455             }
5456         }
5457         if (pi == null) {
5458             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5459             return;
5460         }
5461
5462         // Does the caller have this permission on the URI?
5463         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5464             // Right now, if you are not the original owner of the permission,
5465             // you are not allowed to revoke it.
5466             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5467                 throw new SecurityException("Uid " + callingUid
5468                         + " does not have permission to uri " + uri);
5469             //}
5470         }
5471
5472         // Go through all of the permissions and remove any that match.
5473         final List<String> SEGMENTS = uri.getPathSegments();
5474         if (SEGMENTS != null) {
5475             final int NS = SEGMENTS.size();
5476             int N = mGrantedUriPermissions.size();
5477             for (int i=0; i<N; i++) {
5478                 HashMap<Uri, UriPermission> perms
5479                         = mGrantedUriPermissions.valueAt(i);
5480                 Iterator<UriPermission> it = perms.values().iterator();
5481             toploop:
5482                 while (it.hasNext()) {
5483                     UriPermission perm = it.next();
5484                     Uri targetUri = perm.uri;
5485                     if (!authority.equals(targetUri.getAuthority())) {
5486                         continue;
5487                     }
5488                     List<String> targetSegments = targetUri.getPathSegments();
5489                     if (targetSegments == null) {
5490                         continue;
5491                     }
5492                     if (targetSegments.size() < NS) {
5493                         continue;
5494                     }
5495                     for (int j=0; j<NS; j++) {
5496                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5497                             continue toploop;
5498                         }
5499                     }
5500                     if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
5501                             "Revoking " + perm.uid + " permission to " + perm.uri);
5502                     perm.clearModes(modeFlags);
5503                     if (perm.modeFlags == 0) {
5504                         it.remove();
5505                     }
5506                 }
5507                 if (perms.size() == 0) {
5508                     mGrantedUriPermissions.remove(
5509                             mGrantedUriPermissions.keyAt(i));
5510                     N--;
5511                     i--;
5512                 }
5513             }
5514         }
5515     }
5516
5517     public void revokeUriPermission(IApplicationThread caller, Uri uri,
5518             int modeFlags) {
5519         enforceNotIsolatedCaller("revokeUriPermission");
5520         synchronized(this) {
5521             final ProcessRecord r = getRecordForAppLocked(caller);
5522             if (r == null) {
5523                 throw new SecurityException("Unable to find app for caller "
5524                         + caller
5525                         + " when revoking permission to uri " + uri);
5526             }
5527             if (uri == null) {
5528                 Slog.w(TAG, "revokeUriPermission: null uri");
5529                 return;
5530             }
5531
5532             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5533                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5534             if (modeFlags == 0) {
5535                 return;
5536             }
5537
5538             final IPackageManager pm = AppGlobals.getPackageManager();
5539
5540             final String authority = uri.getAuthority();
5541             ProviderInfo pi = null;
5542             ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5543             if (cpr != null) {
5544                 pi = cpr.info;
5545             } else {
5546                 try {
5547                     pi = pm.resolveContentProvider(authority,
5548                             PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5549                 } catch (RemoteException ex) {
5550                 }
5551             }
5552             if (pi == null) {
5553                 Slog.w(TAG, "No content provider found for permission revoke: "
5554                         + uri.toSafeString());
5555                 return;
5556             }
5557
5558             revokeUriPermissionLocked(r.uid, uri, modeFlags);
5559         }
5560     }
5561
5562     @Override
5563     public IBinder newUriPermissionOwner(String name) {
5564         enforceNotIsolatedCaller("newUriPermissionOwner");
5565         synchronized(this) {
5566             UriPermissionOwner owner = new UriPermissionOwner(this, name);
5567             return owner.getExternalTokenLocked();
5568         }
5569     }
5570
5571     @Override
5572     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5573             Uri uri, int modeFlags) {
5574         synchronized(this) {
5575             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5576             if (owner == null) {
5577                 throw new IllegalArgumentException("Unknown owner: " + token);
5578             }
5579             if (fromUid != Binder.getCallingUid()) {
5580                 if (Binder.getCallingUid() != Process.myUid()) {
5581                     // Only system code can grant URI permissions on behalf
5582                     // of other users.
5583                     throw new SecurityException("nice try");
5584                 }
5585             }
5586             if (targetPkg == null) {
5587                 throw new IllegalArgumentException("null target");
5588             }
5589             if (uri == null) {
5590                 throw new IllegalArgumentException("null uri");
5591             }
5592
5593             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5594         }
5595     }
5596
5597     @Override
5598     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5599         synchronized(this) {
5600             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5601             if (owner == null) {
5602                 throw new IllegalArgumentException("Unknown owner: " + token);
5603             }
5604
5605             if (uri == null) {
5606                 owner.removeUriPermissionsLocked(mode);
5607             } else {
5608                 owner.removeUriPermissionLocked(uri, mode);
5609             }
5610         }
5611     }
5612
5613     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5614         synchronized (this) {
5615             ProcessRecord app =
5616                 who != null ? getRecordForAppLocked(who) : null;
5617             if (app == null) return;
5618
5619             Message msg = Message.obtain();
5620             msg.what = WAIT_FOR_DEBUGGER_MSG;
5621             msg.obj = app;
5622             msg.arg1 = waiting ? 1 : 0;
5623             mHandler.sendMessage(msg);
5624         }
5625     }
5626
5627     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5628         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5629         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5630         outInfo.availMem = Process.getFreeMemory();
5631         outInfo.totalMem = Process.getTotalMemory();
5632         outInfo.threshold = homeAppMem;
5633         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5634         outInfo.hiddenAppThreshold = hiddenAppMem;
5635         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5636                 ProcessList.SERVICE_ADJ);
5637         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5638                 ProcessList.VISIBLE_APP_ADJ);
5639         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5640                 ProcessList.FOREGROUND_APP_ADJ);
5641     }
5642     
5643     // =========================================================
5644     // TASK MANAGEMENT
5645     // =========================================================
5646
5647     public List getTasks(int maxNum, int flags,
5648                          IThumbnailReceiver receiver) {
5649         ArrayList list = new ArrayList();
5650
5651         PendingThumbnailsRecord pending = null;
5652         IApplicationThread topThumbnail = null;
5653         ActivityRecord topRecord = null;
5654
5655         synchronized(this) {
5656             if (localLOGV) Slog.v(
5657                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5658                 + ", receiver=" + receiver);
5659
5660             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5661                     != PackageManager.PERMISSION_GRANTED) {
5662                 if (receiver != null) {
5663                     // If the caller wants to wait for pending thumbnails,
5664                     // it ain't gonna get them.
5665                     try {
5666                         receiver.finished();
5667                     } catch (RemoteException ex) {
5668                     }
5669                 }
5670                 String msg = "Permission Denial: getTasks() from pid="
5671                         + Binder.getCallingPid()
5672                         + ", uid=" + Binder.getCallingUid()
5673                         + " requires " + android.Manifest.permission.GET_TASKS;
5674                 Slog.w(TAG, msg);
5675                 throw new SecurityException(msg);
5676             }
5677
5678             int pos = mMainStack.mHistory.size()-1;
5679             ActivityRecord next =
5680                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5681             ActivityRecord top = null;
5682             TaskRecord curTask = null;
5683             int numActivities = 0;
5684             int numRunning = 0;
5685             while (pos >= 0 && maxNum > 0) {
5686                 final ActivityRecord r = next;
5687                 pos--;
5688                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5689
5690                 // Initialize state for next task if needed.
5691                 if (top == null ||
5692                         (top.state == ActivityState.INITIALIZING
5693                             && top.task == r.task)) {
5694                     top = r;
5695                     curTask = r.task;
5696                     numActivities = numRunning = 0;
5697                 }
5698
5699                 // Add 'r' into the current task.
5700                 numActivities++;
5701                 if (r.app != null && r.app.thread != null) {
5702                     numRunning++;
5703                 }
5704
5705                 if (localLOGV) Slog.v(
5706                     TAG, r.intent.getComponent().flattenToShortString()
5707                     + ": task=" + r.task);
5708
5709                 // If the next one is a different task, generate a new
5710                 // TaskInfo entry for what we have.
5711                 if (next == null || next.task != curTask) {
5712                     ActivityManager.RunningTaskInfo ci
5713                             = new ActivityManager.RunningTaskInfo();
5714                     ci.id = curTask.taskId;
5715                     ci.baseActivity = r.intent.getComponent();
5716                     ci.topActivity = top.intent.getComponent();
5717                     if (top.thumbHolder != null) {
5718                         ci.description = top.thumbHolder.lastDescription;
5719                     }
5720                     ci.numActivities = numActivities;
5721                     ci.numRunning = numRunning;
5722                     //System.out.println(
5723                     //    "#" + maxNum + ": " + " descr=" + ci.description);
5724                     if (ci.thumbnail == null && receiver != null) {
5725                         if (localLOGV) Slog.v(
5726                             TAG, "State=" + top.state + "Idle=" + top.idle
5727                             + " app=" + top.app
5728                             + " thr=" + (top.app != null ? top.app.thread : null));
5729                         if (top.state == ActivityState.RESUMED
5730                                 || top.state == ActivityState.PAUSING) {
5731                             if (top.idle && top.app != null
5732                                 && top.app.thread != null) {
5733                                 topRecord = top;
5734                                 topThumbnail = top.app.thread;
5735                             } else {
5736                                 top.thumbnailNeeded = true;
5737                             }
5738                         }
5739                         if (pending == null) {
5740                             pending = new PendingThumbnailsRecord(receiver);
5741                         }
5742                         pending.pendingRecords.add(top);
5743                     }
5744                     list.add(ci);
5745                     maxNum--;
5746                     top = null;
5747                 }
5748             }
5749
5750             if (pending != null) {
5751                 mPendingThumbnails.add(pending);
5752             }
5753         }
5754
5755         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5756
5757         if (topThumbnail != null) {
5758             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5759             try {
5760                 topThumbnail.requestThumbnail(topRecord.appToken);
5761             } catch (Exception e) {
5762                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5763                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5764             }
5765         }
5766
5767         if (pending == null && receiver != null) {
5768             // In this case all thumbnails were available and the client
5769             // is being asked to be told when the remaining ones come in...
5770             // which is unusually, since the top-most currently running
5771             // activity should never have a canned thumbnail!  Oh well.
5772             try {
5773                 receiver.finished();
5774             } catch (RemoteException ex) {
5775             }
5776         }
5777
5778         return list;
5779     }
5780
5781     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5782             int flags, int userId) {
5783         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5784                 false, true, "getRecentTasks", null);
5785
5786         synchronized (this) {
5787             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5788                     "getRecentTasks()");
5789             final boolean detailed = checkCallingPermission(
5790                     android.Manifest.permission.GET_DETAILED_TASKS)
5791                     == PackageManager.PERMISSION_GRANTED;
5792
5793             IPackageManager pm = AppGlobals.getPackageManager();
5794
5795             final int N = mRecentTasks.size();
5796             ArrayList<ActivityManager.RecentTaskInfo> res
5797                     = new ArrayList<ActivityManager.RecentTaskInfo>(
5798                             maxNum < N ? maxNum : N);
5799             for (int i=0; i<N && maxNum > 0; i++) {
5800                 TaskRecord tr = mRecentTasks.get(i);
5801                 // Only add calling user's recent tasks
5802                 if (tr.userId != userId) continue;
5803                 // Return the entry if desired by the caller.  We always return
5804                 // the first entry, because callers always expect this to be the
5805                 // foreground app.  We may filter others if the caller has
5806                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5807                 // we should exclude the entry.
5808
5809                 if (i == 0
5810                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5811                         || (tr.intent == null)
5812                         || ((tr.intent.getFlags()
5813                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5814                     ActivityManager.RecentTaskInfo rti
5815                             = new ActivityManager.RecentTaskInfo();
5816                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5817                     rti.persistentId = tr.taskId;
5818                     rti.baseIntent = new Intent(
5819                             tr.intent != null ? tr.intent : tr.affinityIntent);
5820                     if (!detailed) {
5821                         rti.baseIntent.replaceExtras((Bundle)null);
5822                     }
5823                     rti.origActivity = tr.origActivity;
5824                     rti.description = tr.lastDescription;
5825                     
5826                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5827                         // Check whether this activity is currently available.
5828                         try {
5829                             if (rti.origActivity != null) {
5830                                 if (pm.getActivityInfo(rti.origActivity, 0, userId)
5831                                         == null) {
5832                                     continue;
5833                                 }
5834                             } else if (rti.baseIntent != null) {
5835                                 if (pm.queryIntentActivities(rti.baseIntent,
5836                                         null, 0, userId) == null) {
5837                                     continue;
5838                                 }
5839                             }
5840                         } catch (RemoteException e) {
5841                             // Will never happen.
5842                         }
5843                     }
5844                     
5845                     res.add(rti);
5846                     maxNum--;
5847                 }
5848             }
5849             return res;
5850         }
5851     }
5852
5853     private TaskRecord taskForIdLocked(int id) {
5854         final int N = mRecentTasks.size();
5855         for (int i=0; i<N; i++) {
5856             TaskRecord tr = mRecentTasks.get(i);
5857             if (tr.taskId == id) {
5858                 return tr;
5859             }
5860         }
5861         return null;
5862     }
5863
5864     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5865         synchronized (this) {
5866             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5867                     "getTaskThumbnails()");
5868             TaskRecord tr = taskForIdLocked(id);
5869             if (tr != null) {
5870                 return mMainStack.getTaskThumbnailsLocked(tr);
5871             }
5872         }
5873         return null;
5874     }
5875
5876     public Bitmap getTaskTopThumbnail(int id) {
5877         synchronized (this) {
5878             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5879                     "getTaskTopThumbnail()");
5880             TaskRecord tr = taskForIdLocked(id);
5881             if (tr != null) {
5882                 return mMainStack.getTaskTopThumbnailLocked(tr);
5883             }
5884         }
5885         return null;
5886     }
5887
5888     public boolean removeSubTask(int taskId, int subTaskIndex) {
5889         synchronized (this) {
5890             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5891                     "removeSubTask()");
5892             long ident = Binder.clearCallingIdentity();
5893             try {
5894                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5895                         true) != null;
5896             } finally {
5897                 Binder.restoreCallingIdentity(ident);
5898             }
5899         }
5900     }
5901
5902     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5903         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5904         Intent baseIntent = new Intent(
5905                 tr.intent != null ? tr.intent : tr.affinityIntent);
5906         ComponentName component = baseIntent.getComponent();
5907         if (component == null) {
5908             Slog.w(TAG, "Now component for base intent of task: " + tr);
5909             return;
5910         }
5911
5912         // Find any running services associated with this app.
5913         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5914
5915         if (killProcesses) {
5916             // Find any running processes associated with this app.
5917             final String pkg = component.getPackageName();
5918             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5919             HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5920             for (SparseArray<ProcessRecord> uids : pmap.values()) {
5921                 for (int i=0; i<uids.size(); i++) {
5922                     ProcessRecord proc = uids.valueAt(i);
5923                     if (proc.userId != tr.userId) {
5924                         continue;
5925                     }
5926                     if (!proc.pkgList.contains(pkg)) {
5927                         continue;
5928                     }
5929                     procs.add(proc);
5930                 }
5931             }
5932
5933             // Kill the running processes.
5934             for (int i=0; i<procs.size(); i++) {
5935                 ProcessRecord pr = procs.get(i);
5936                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5937                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5938                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5939                             pr.processName, pr.setAdj, "remove task");
5940                     pr.killedBackground = true;
5941                     Process.killProcessQuiet(pr.pid);
5942                 } else {
5943                     pr.waitingToKill = "remove task";
5944                 }
5945             }
5946         }
5947     }
5948
5949     public boolean removeTask(int taskId, int flags) {
5950         synchronized (this) {
5951             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5952                     "removeTask()");
5953             long ident = Binder.clearCallingIdentity();
5954             try {
5955                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5956                         false);
5957                 if (r != null) {
5958                     mRecentTasks.remove(r.task);
5959                     cleanUpRemovedTaskLocked(r.task, flags);
5960                     return true;
5961                 } else {
5962                     TaskRecord tr = null;
5963                     int i=0;
5964                     while (i < mRecentTasks.size()) {
5965                         TaskRecord t = mRecentTasks.get(i);
5966                         if (t.taskId == taskId) {
5967                             tr = t;
5968                             break;
5969                         }
5970                         i++;
5971                     }
5972                     if (tr != null) {
5973                         if (tr.numActivities <= 0) {
5974                             // Caller is just removing a recent task that is
5975                             // not actively running.  That is easy!
5976                             mRecentTasks.remove(i);
5977                             cleanUpRemovedTaskLocked(tr, flags);
5978                             return true;
5979                         } else {
5980                             Slog.w(TAG, "removeTask: task " + taskId
5981                                     + " does not have activities to remove, "
5982                                     + " but numActivities=" + tr.numActivities
5983                                     + ": " + tr);
5984                         }
5985                     }
5986                 }
5987             } finally {
5988                 Binder.restoreCallingIdentity(ident);
5989             }
5990         }
5991         return false;
5992     }
5993     
5994     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5995         int j;
5996         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 
5997         TaskRecord jt = startTask;
5998         
5999         // First look backwards
6000         for (j=startIndex-1; j>=0; j--) {
6001             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6002             if (r.task != jt) {
6003                 jt = r.task;
6004                 if (affinity.equals(jt.affinity)) {
6005                     return j;
6006                 }
6007             }
6008         }
6009         
6010         // Now look forwards
6011         final int N = mMainStack.mHistory.size();
6012         jt = startTask;
6013         for (j=startIndex+1; j<N; j++) {
6014             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6015             if (r.task != jt) {
6016                 if (affinity.equals(jt.affinity)) {
6017                     return j;
6018                 }
6019                 jt = r.task;
6020             }
6021         }
6022         
6023         // Might it be at the top?
6024         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6025             return N-1;
6026         }
6027         
6028         return -1;
6029     }
6030     
6031     /**
6032      * TODO: Add mController hook
6033      */
6034     public void moveTaskToFront(int task, int flags, Bundle options) {
6035         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6036                 "moveTaskToFront()");
6037
6038         synchronized(this) {
6039             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6040                     Binder.getCallingUid(), "Task to front")) {
6041                 ActivityOptions.abort(options);
6042                 return;
6043             }
6044             final long origId = Binder.clearCallingIdentity();
6045             try {
6046                 TaskRecord tr = taskForIdLocked(task);
6047                 if (tr != null) {
6048                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6049                         mMainStack.mUserLeaving = true;
6050                     }
6051                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6052                         // Caller wants the home activity moved with it.  To accomplish this,
6053                         // we'll just move the home task to the top first.
6054                         mMainStack.moveHomeToFrontLocked();
6055                     }
6056                     mMainStack.moveTaskToFrontLocked(tr, null, options);
6057                     return;
6058                 }
6059                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6060                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6061                     if (hr.task.taskId == task) {
6062                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6063                             mMainStack.mUserLeaving = true;
6064                         }
6065                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6066                             // Caller wants the home activity moved with it.  To accomplish this,
6067                             // we'll just move the home task to the top first.
6068                             mMainStack.moveHomeToFrontLocked();
6069                         }
6070                         mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6071                         return;
6072                     }
6073                 }
6074             } finally {
6075                 Binder.restoreCallingIdentity(origId);
6076             }
6077             ActivityOptions.abort(options);
6078         }
6079     }
6080
6081     public void moveTaskToBack(int task) {
6082         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6083                 "moveTaskToBack()");
6084
6085         synchronized(this) {
6086             if (mMainStack.mResumedActivity != null
6087                     && mMainStack.mResumedActivity.task.taskId == task) {
6088                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6089                         Binder.getCallingUid(), "Task to back")) {
6090                     return;
6091                 }
6092             }
6093             final long origId = Binder.clearCallingIdentity();
6094             mMainStack.moveTaskToBackLocked(task, null);
6095             Binder.restoreCallingIdentity(origId);
6096         }
6097     }
6098
6099     /**
6100      * Moves an activity, and all of the other activities within the same task, to the bottom
6101      * of the history stack.  The activity's order within the task is unchanged.
6102      * 
6103      * @param token A reference to the activity we wish to move
6104      * @param nonRoot If false then this only works if the activity is the root
6105      *                of a task; if true it will work for any activity in a task.
6106      * @return Returns true if the move completed, false if not.
6107      */
6108     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6109         enforceNotIsolatedCaller("moveActivityTaskToBack");
6110         synchronized(this) {
6111             final long origId = Binder.clearCallingIdentity();
6112             int taskId = getTaskForActivityLocked(token, !nonRoot);
6113             if (taskId >= 0) {
6114                 return mMainStack.moveTaskToBackLocked(taskId, null);
6115             }
6116             Binder.restoreCallingIdentity(origId);
6117         }
6118         return false;
6119     }
6120
6121     public void moveTaskBackwards(int task) {
6122         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6123                 "moveTaskBackwards()");
6124
6125         synchronized(this) {
6126             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6127                     Binder.getCallingUid(), "Task backwards")) {
6128                 return;
6129             }
6130             final long origId = Binder.clearCallingIdentity();
6131             moveTaskBackwardsLocked(task);
6132             Binder.restoreCallingIdentity(origId);
6133         }
6134     }
6135
6136     private final void moveTaskBackwardsLocked(int task) {
6137         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6138     }
6139
6140     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6141         synchronized(this) {
6142             return getTaskForActivityLocked(token, onlyRoot);
6143         }
6144     }
6145
6146     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6147         final int N = mMainStack.mHistory.size();
6148         TaskRecord lastTask = null;
6149         for (int i=0; i<N; i++) {
6150             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6151             if (r.appToken == token) {
6152                 if (!onlyRoot || lastTask != r.task) {
6153                     return r.task.taskId;
6154                 }
6155                 return -1;
6156             }
6157             lastTask = r.task;
6158         }
6159
6160         return -1;
6161     }
6162
6163     // =========================================================
6164     // THUMBNAILS
6165     // =========================================================
6166
6167     public void reportThumbnail(IBinder token,
6168             Bitmap thumbnail, CharSequence description) {
6169         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6170         final long origId = Binder.clearCallingIdentity();
6171         sendPendingThumbnail(null, token, thumbnail, description, true);
6172         Binder.restoreCallingIdentity(origId);
6173     }
6174
6175     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6176             Bitmap thumbnail, CharSequence description, boolean always) {
6177         TaskRecord task = null;
6178         ArrayList receivers = null;
6179
6180         //System.out.println("Send pending thumbnail: " + r);
6181
6182         synchronized(this) {
6183             if (r == null) {
6184                 r = mMainStack.isInStackLocked(token);
6185                 if (r == null) {
6186                     return;
6187                 }
6188             }
6189             if (thumbnail == null && r.thumbHolder != null) {
6190                 thumbnail = r.thumbHolder.lastThumbnail;
6191                 description = r.thumbHolder.lastDescription;
6192             }
6193             if (thumbnail == null && !always) {
6194                 // If there is no thumbnail, and this entry is not actually
6195                 // going away, then abort for now and pick up the next
6196                 // thumbnail we get.
6197                 return;
6198             }
6199             task = r.task;
6200
6201             int N = mPendingThumbnails.size();
6202             int i=0;
6203             while (i<N) {
6204                 PendingThumbnailsRecord pr =
6205                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6206                 //System.out.println("Looking in " + pr.pendingRecords);
6207                 if (pr.pendingRecords.remove(r)) {
6208                     if (receivers == null) {
6209                         receivers = new ArrayList();
6210                     }
6211                     receivers.add(pr);
6212                     if (pr.pendingRecords.size() == 0) {
6213                         pr.finished = true;
6214                         mPendingThumbnails.remove(i);
6215                         N--;
6216                         continue;
6217                     }
6218                 }
6219                 i++;
6220             }
6221         }
6222
6223         if (receivers != null) {
6224             final int N = receivers.size();
6225             for (int i=0; i<N; i++) {
6226                 try {
6227                     PendingThumbnailsRecord pr =
6228                         (PendingThumbnailsRecord)receivers.get(i);
6229                     pr.receiver.newThumbnail(
6230                         task != null ? task.taskId : -1, thumbnail, description);
6231                     if (pr.finished) {
6232                         pr.receiver.finished();
6233                     }
6234                 } catch (Exception e) {
6235                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6236                 }
6237             }
6238         }
6239     }
6240
6241     // =========================================================
6242     // CONTENT PROVIDERS
6243     // =========================================================
6244
6245     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6246         List<ProviderInfo> providers = null;
6247         try {
6248             providers = AppGlobals.getPackageManager().
6249                 queryContentProviders(app.processName, app.uid,
6250                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6251         } catch (RemoteException ex) {
6252         }
6253         if (DEBUG_MU)
6254             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6255         int userId = app.userId;
6256         if (providers != null) {
6257             int N = providers.size();
6258             for (int i=0; i<N; i++) {
6259                 ProviderInfo cpi =
6260                     (ProviderInfo)providers.get(i);
6261                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6262                         cpi.name, cpi.flags);
6263                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
6264                     // This is a singleton provider, but a user besides the
6265                     // default user is asking to initialize a process it runs
6266                     // in...  well, no, it doesn't actually run in this process,
6267                     // it runs in the process of the default user.  Get rid of it.
6268                     providers.remove(i);
6269                     N--;
6270                     continue;
6271                 }
6272
6273                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6274                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6275                 if (cpr == null) {
6276                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6277                     mProviderMap.putProviderByClass(comp, cpr);
6278                 }
6279                 if (DEBUG_MU)
6280                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6281                 app.pubProviders.put(cpi.name, cpr);
6282                 app.addPackage(cpi.applicationInfo.packageName);
6283                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
6284             }
6285         }
6286         return providers;
6287     }
6288
6289     /**
6290      * Check if {@link ProcessRecord} has a possible chance at accessing the
6291      * given {@link ProviderInfo}. Final permission checking is always done
6292      * in {@link ContentProvider}.
6293      */
6294     private final String checkContentProviderPermissionLocked(
6295             ProviderInfo cpi, ProcessRecord r) {
6296         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6297         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6298         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6299                 cpi.applicationInfo.uid, cpi.exported)
6300                 == PackageManager.PERMISSION_GRANTED) {
6301             return null;
6302         }
6303         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6304                 cpi.applicationInfo.uid, cpi.exported)
6305                 == PackageManager.PERMISSION_GRANTED) {
6306             return null;
6307         }
6308         
6309         PathPermission[] pps = cpi.pathPermissions;
6310         if (pps != null) {
6311             int i = pps.length;
6312             while (i > 0) {
6313                 i--;
6314                 PathPermission pp = pps[i];
6315                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6316                         cpi.applicationInfo.uid, cpi.exported)
6317                         == PackageManager.PERMISSION_GRANTED) {
6318                     return null;
6319                 }
6320                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6321                         cpi.applicationInfo.uid, cpi.exported)
6322                         == PackageManager.PERMISSION_GRANTED) {
6323                     return null;
6324                 }
6325             }
6326         }
6327         
6328         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6329         if (perms != null) {
6330             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6331                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6332                     return null;
6333                 }
6334             }
6335         }
6336
6337         String msg;
6338         if (!cpi.exported) {
6339             msg = "Permission Denial: opening provider " + cpi.name
6340                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6341                     + ", uid=" + callingUid + ") that is not exported from uid "
6342                     + cpi.applicationInfo.uid;
6343         } else {
6344             msg = "Permission Denial: opening provider " + cpi.name
6345                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6346                     + ", uid=" + callingUid + ") requires "
6347                     + cpi.readPermission + " or " + cpi.writePermission;
6348         }
6349         Slog.w(TAG, msg);
6350         return msg;
6351     }
6352
6353     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6354             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6355         if (r != null) {
6356             for (int i=0; i<r.conProviders.size(); i++) {
6357                 ContentProviderConnection conn = r.conProviders.get(i);
6358                 if (conn.provider == cpr) {
6359                     if (DEBUG_PROVIDER) Slog.v(TAG,
6360                             "Adding provider requested by "
6361                             + r.processName + " from process "
6362                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6363                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6364                     if (stable) {
6365                         conn.stableCount++;
6366                         conn.numStableIncs++;
6367                     } else {
6368                         conn.unstableCount++;
6369                         conn.numUnstableIncs++;
6370                     }
6371                     return conn;
6372                 }
6373             }
6374             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6375             if (stable) {
6376                 conn.stableCount = 1;
6377                 conn.numStableIncs = 1;
6378             } else {
6379                 conn.unstableCount = 1;
6380                 conn.numUnstableIncs = 1;
6381             }
6382             cpr.connections.add(conn);
6383             r.conProviders.add(conn);
6384             return conn;
6385         }
6386         cpr.addExternalProcessHandleLocked(externalProcessToken);
6387         return null;
6388     }
6389
6390     boolean decProviderCountLocked(ContentProviderConnection conn,
6391             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6392         if (conn != null) {
6393             cpr = conn.provider;
6394             if (DEBUG_PROVIDER) Slog.v(TAG,
6395                     "Removing provider requested by "
6396                     + conn.client.processName + " from process "
6397                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6398                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6399             if (stable) {
6400                 conn.stableCount--;
6401             } else {
6402                 conn.unstableCount--;
6403             }
6404             if (conn.stableCount == 0 && conn.unstableCount == 0) {
6405                 cpr.connections.remove(conn);
6406                 conn.client.conProviders.remove(conn);
6407                 return true;
6408             }
6409             return false;
6410         }
6411         cpr.removeExternalProcessHandleLocked(externalProcessToken);
6412         return false;
6413     }
6414
6415     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6416             String name, IBinder token, boolean stable, int userId) {
6417         ContentProviderRecord cpr;
6418         ContentProviderConnection conn = null;
6419         ProviderInfo cpi = null;
6420
6421         synchronized(this) {
6422             ProcessRecord r = null;
6423             if (caller != null) {
6424                 r = getRecordForAppLocked(caller);
6425                 if (r == null) {
6426                     throw new SecurityException(
6427                             "Unable to find app for caller " + caller
6428                           + " (pid=" + Binder.getCallingPid()
6429                           + ") when getting content provider " + name);
6430                 }
6431             }
6432
6433             // First check if this content provider has been published...
6434             cpr = mProviderMap.getProviderByName(name, userId);
6435             boolean providerRunning = cpr != null;
6436             if (providerRunning) {
6437                 cpi = cpr.info;
6438                 String msg;
6439                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6440                     throw new SecurityException(msg);
6441                 }
6442
6443                 if (r != null && cpr.canRunHere(r)) {
6444                     // This provider has been published or is in the process
6445                     // of being published...  but it is also allowed to run
6446                     // in the caller's process, so don't make a connection
6447                     // and just let the caller instantiate its own instance.
6448                     ContentProviderHolder holder = cpr.newHolder(null);
6449                     // don't give caller the provider object, it needs
6450                     // to make its own.
6451                     holder.provider = null;
6452                     return holder;
6453                 }
6454
6455                 final long origId = Binder.clearCallingIdentity();
6456
6457                 // In this case the provider instance already exists, so we can
6458                 // return it right away.
6459                 conn = incProviderCountLocked(r, cpr, token, stable);
6460                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6461                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6462                         // If this is a perceptible app accessing the provider,
6463                         // make sure to count it as being accessed and thus
6464                         // back up on the LRU list.  This is good because
6465                         // content providers are often expensive to start.
6466                         updateLruProcessLocked(cpr.proc, false);
6467                     }
6468                 }
6469
6470                 if (cpr.proc != null) {
6471                     if (false) {
6472                         if (cpr.name.flattenToShortString().equals(
6473                                 "com.android.providers.calendar/.CalendarProvider2")) {
6474                             Slog.v(TAG, "****************** KILLING "
6475                                 + cpr.name.flattenToShortString());
6476                             Process.killProcess(cpr.proc.pid);
6477                         }
6478                     }
6479                     boolean success = updateOomAdjLocked(cpr.proc);
6480                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6481                     // NOTE: there is still a race here where a signal could be
6482                     // pending on the process even though we managed to update its
6483                     // adj level.  Not sure what to do about this, but at least
6484                     // the race is now smaller.
6485                     if (!success) {
6486                         // Uh oh...  it looks like the provider's process
6487                         // has been killed on us.  We need to wait for a new
6488                         // process to be started, and make sure its death
6489                         // doesn't kill our process.
6490                         Slog.i(TAG,
6491                                 "Existing provider " + cpr.name.flattenToShortString()
6492                                 + " is crashing; detaching " + r);
6493                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6494                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6495                         if (!lastRef) {
6496                             // This wasn't the last ref our process had on
6497                             // the provider...  we have now been killed, bail.
6498                             return null;
6499                         }
6500                         providerRunning = false;
6501                         conn = null;
6502                     }
6503                 }
6504
6505                 Binder.restoreCallingIdentity(origId);
6506             }
6507
6508             boolean singleton;
6509             if (!providerRunning) {
6510                 try {
6511                     cpi = AppGlobals.getPackageManager().
6512                         resolveContentProvider(name,
6513                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6514                 } catch (RemoteException ex) {
6515                 }
6516                 if (cpi == null) {
6517                     return null;
6518                 }
6519                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6520                         cpi.name, cpi.flags); 
6521                 if (singleton) {
6522                     userId = 0;
6523                 }
6524                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6525
6526                 String msg;
6527                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6528                     throw new SecurityException(msg);
6529                 }
6530
6531                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6532                         && !cpi.processName.equals("system")) {
6533                     // If this content provider does not run in the system
6534                     // process, and the system is not yet ready to run other
6535                     // processes, then fail fast instead of hanging.
6536                     throw new IllegalArgumentException(
6537                             "Attempt to launch content provider before system ready");
6538                 }
6539
6540                 // Make sure that the user who owns this provider is started.  If not,
6541                 // we don't want to allow it to run.
6542                 if (mStartedUsers.get(userId) == null) {
6543                     Slog.w(TAG, "Unable to launch app "
6544                             + cpi.applicationInfo.packageName + "/"
6545                             + cpi.applicationInfo.uid + " for provider "
6546                             + name + ": user " + userId + " is stopped");
6547                     return null;
6548                 }
6549
6550                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6551                 cpr = mProviderMap.getProviderByClass(comp, userId);
6552                 final boolean firstClass = cpr == null;
6553                 if (firstClass) {
6554                     try {
6555                         ApplicationInfo ai =
6556                             AppGlobals.getPackageManager().
6557                                 getApplicationInfo(
6558                                         cpi.applicationInfo.packageName,
6559                                         STOCK_PM_FLAGS, userId);
6560                         if (ai == null) {
6561                             Slog.w(TAG, "No package info for content provider "
6562                                     + cpi.name);
6563                             return null;
6564                         }
6565                         ai = getAppInfoForUser(ai, userId);
6566                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6567                     } catch (RemoteException ex) {
6568                         // pm is in same process, this will never happen.
6569                     }
6570                 }
6571
6572                 if (r != null && cpr.canRunHere(r)) {
6573                     // If this is a multiprocess provider, then just return its
6574                     // info and allow the caller to instantiate it.  Only do
6575                     // this if the provider is the same user as the caller's
6576                     // process, or can run as root (so can be in any process).
6577                     return cpr.newHolder(null);
6578                 }
6579
6580                 if (DEBUG_PROVIDER) {
6581                     RuntimeException e = new RuntimeException("here");
6582                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6583                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6584                 }
6585
6586                 // This is single process, and our app is now connecting to it.
6587                 // See if we are already in the process of launching this
6588                 // provider.
6589                 final int N = mLaunchingProviders.size();
6590                 int i;
6591                 for (i=0; i<N; i++) {
6592                     if (mLaunchingProviders.get(i) == cpr) {
6593                         break;
6594                     }
6595                 }
6596
6597                 // If the provider is not already being launched, then get it
6598                 // started.
6599                 if (i >= N) {
6600                     final long origId = Binder.clearCallingIdentity();
6601
6602                     try {
6603                         // Content provider is now in use, its package can't be stopped.
6604                         try {
6605                             AppGlobals.getPackageManager().setPackageStoppedState(
6606                                     cpr.appInfo.packageName, false, userId);
6607                         } catch (RemoteException e) {
6608                         } catch (IllegalArgumentException e) {
6609                             Slog.w(TAG, "Failed trying to unstop package "
6610                                     + cpr.appInfo.packageName + ": " + e);
6611                         }
6612
6613                         ProcessRecord proc = startProcessLocked(cpi.processName,
6614                                 cpr.appInfo, false, 0, "content provider",
6615                                 new ComponentName(cpi.applicationInfo.packageName,
6616                                         cpi.name), false, false);
6617                         if (proc == null) {
6618                             Slog.w(TAG, "Unable to launch app "
6619                                     + cpi.applicationInfo.packageName + "/"
6620                                     + cpi.applicationInfo.uid + " for provider "
6621                                     + name + ": process is bad");
6622                             return null;
6623                         }
6624                         cpr.launchingApp = proc;
6625                         mLaunchingProviders.add(cpr);
6626                     } finally {
6627                         Binder.restoreCallingIdentity(origId);
6628                     }
6629                 }
6630
6631                 // Make sure the provider is published (the same provider class
6632                 // may be published under multiple names).
6633                 if (firstClass) {
6634                     mProviderMap.putProviderByClass(comp, cpr);
6635                 }
6636
6637                 mProviderMap.putProviderByName(name, cpr);
6638                 conn = incProviderCountLocked(r, cpr, token, stable);
6639                 if (conn != null) {
6640                     conn.waiting = true;
6641                 }
6642             }
6643         }
6644
6645         // Wait for the provider to be published...
6646         synchronized (cpr) {
6647             while (cpr.provider == null) {
6648                 if (cpr.launchingApp == null) {
6649                     Slog.w(TAG, "Unable to launch app "
6650                             + cpi.applicationInfo.packageName + "/"
6651                             + cpi.applicationInfo.uid + " for provider "
6652                             + name + ": launching app became null");
6653                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6654                             UserHandle.getUserId(cpi.applicationInfo.uid),
6655                             cpi.applicationInfo.packageName,
6656                             cpi.applicationInfo.uid, name);
6657                     return null;
6658                 }
6659                 try {
6660                     if (DEBUG_MU) {
6661                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6662                                 + cpr.launchingApp);
6663                     }
6664                     if (conn != null) {
6665                         conn.waiting = true;
6666                     }
6667                     cpr.wait();
6668                 } catch (InterruptedException ex) {
6669                 } finally {
6670                     if (conn != null) {
6671                         conn.waiting = false;
6672                     }
6673                 }
6674             }
6675         }
6676         return cpr != null ? cpr.newHolder(conn) : null;
6677     }
6678
6679     public final ContentProviderHolder getContentProvider(
6680             IApplicationThread caller, String name, int userId, boolean stable) {
6681         enforceNotIsolatedCaller("getContentProvider");
6682         if (caller == null) {
6683             String msg = "null IApplicationThread when getting content provider "
6684                     + name;
6685             Slog.w(TAG, msg);
6686             throw new SecurityException(msg);
6687         }
6688
6689         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6690                 false, true, "getContentProvider", null);
6691         return getContentProviderImpl(caller, name, null, stable, userId);
6692     }
6693
6694     public ContentProviderHolder getContentProviderExternal(
6695             String name, int userId, IBinder token) {
6696         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6697             "Do not have permission in call getContentProviderExternal()");
6698         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6699                 false, true, "getContentProvider", null);
6700         return getContentProviderExternalUnchecked(name, token, userId);
6701     }
6702
6703     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6704             IBinder token, int userId) {
6705         return getContentProviderImpl(null, name, token, true, userId);
6706     }
6707
6708     /**
6709      * Drop a content provider from a ProcessRecord's bookkeeping
6710      * @param cpr
6711      */
6712     public void removeContentProvider(IBinder connection, boolean stable) {
6713         enforceNotIsolatedCaller("removeContentProvider");
6714         synchronized (this) {
6715             ContentProviderConnection conn;
6716             try {
6717                 conn = (ContentProviderConnection)connection;
6718             } catch (ClassCastException e) {
6719                 String msg ="removeContentProvider: " + connection
6720                         + " not a ContentProviderConnection";
6721                 Slog.w(TAG, msg);
6722                 throw new IllegalArgumentException(msg);
6723             }
6724             if (conn == null) {
6725                 throw new NullPointerException("connection is null");
6726             }
6727             if (decProviderCountLocked(conn, null, null, stable)) {
6728                 updateOomAdjLocked();
6729             }
6730         }
6731     }
6732
6733     public void removeContentProviderExternal(String name, IBinder token) {
6734         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6735             "Do not have permission in call removeContentProviderExternal()");
6736         removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6737     }
6738
6739     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6740         synchronized (this) {
6741             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6742             if(cpr == null) {
6743                 //remove from mProvidersByClass
6744                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6745                 return;
6746             }
6747
6748             //update content provider record entry info
6749             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6750             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6751             if (localCpr.hasExternalProcessHandles()) {
6752                 if (localCpr.removeExternalProcessHandleLocked(token)) {
6753                     updateOomAdjLocked();
6754                 } else {
6755                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6756                             + " with no external reference for token: "
6757                             + token + ".");
6758                 }
6759             } else {
6760                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6761                         + " with no external references.");
6762             }
6763         }
6764     }
6765     
6766     public final void publishContentProviders(IApplicationThread caller,
6767             List<ContentProviderHolder> providers) {
6768         if (providers == null) {
6769             return;
6770         }
6771
6772         enforceNotIsolatedCaller("publishContentProviders");
6773         synchronized (this) {
6774             final ProcessRecord r = getRecordForAppLocked(caller);
6775             if (DEBUG_MU)
6776                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6777             if (r == null) {
6778                 throw new SecurityException(
6779                         "Unable to find app for caller " + caller
6780                       + " (pid=" + Binder.getCallingPid()
6781                       + ") when publishing content providers");
6782             }
6783
6784             final long origId = Binder.clearCallingIdentity();
6785
6786             final int N = providers.size();
6787             for (int i=0; i<N; i++) {
6788                 ContentProviderHolder src = providers.get(i);
6789                 if (src == null || src.info == null || src.provider == null) {
6790                     continue;
6791                 }
6792                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6793                 if (DEBUG_MU)
6794                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6795                 if (dst != null) {
6796                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6797                     mProviderMap.putProviderByClass(comp, dst);
6798                     String names[] = dst.info.authority.split(";");
6799                     for (int j = 0; j < names.length; j++) {
6800                         mProviderMap.putProviderByName(names[j], dst);
6801                     }
6802
6803                     int NL = mLaunchingProviders.size();
6804                     int j;
6805                     for (j=0; j<NL; j++) {
6806                         if (mLaunchingProviders.get(j) == dst) {
6807                             mLaunchingProviders.remove(j);
6808                             j--;
6809                             NL--;
6810                         }
6811                     }
6812                     synchronized (dst) {
6813                         dst.provider = src.provider;
6814                         dst.proc = r;
6815                         dst.notifyAll();
6816                     }
6817                     updateOomAdjLocked(r);
6818                 }
6819             }
6820
6821             Binder.restoreCallingIdentity(origId);
6822         }
6823     }
6824
6825     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6826         ContentProviderConnection conn;
6827         try {
6828             conn = (ContentProviderConnection)connection;
6829         } catch (ClassCastException e) {
6830             String msg ="refContentProvider: " + connection
6831                     + " not a ContentProviderConnection";
6832             Slog.w(TAG, msg);
6833             throw new IllegalArgumentException(msg);
6834         }
6835         if (conn == null) {
6836             throw new NullPointerException("connection is null");
6837         }
6838
6839         synchronized (this) {
6840             if (stable > 0) {
6841                 conn.numStableIncs += stable;
6842             }
6843             stable = conn.stableCount + stable;
6844             if (stable < 0) {
6845                 throw new IllegalStateException("stableCount < 0: " + stable);
6846             }
6847
6848             if (unstable > 0) {
6849                 conn.numUnstableIncs += unstable;
6850             }
6851             unstable = conn.unstableCount + unstable;
6852             if (unstable < 0) {
6853                 throw new IllegalStateException("unstableCount < 0: " + unstable);
6854             }
6855
6856             if ((stable+unstable) <= 0) {
6857                 throw new IllegalStateException("ref counts can't go to zero here: stable="
6858                         + stable + " unstable=" + unstable);
6859             }
6860             conn.stableCount = stable;
6861             conn.unstableCount = unstable;
6862             return !conn.dead;
6863         }
6864     }
6865
6866     public void unstableProviderDied(IBinder connection) {
6867         ContentProviderConnection conn;
6868         try {
6869             conn = (ContentProviderConnection)connection;
6870         } catch (ClassCastException e) {
6871             String msg ="refContentProvider: " + connection
6872                     + " not a ContentProviderConnection";
6873             Slog.w(TAG, msg);
6874             throw new IllegalArgumentException(msg);
6875         }
6876         if (conn == null) {
6877             throw new NullPointerException("connection is null");
6878         }
6879
6880         // Safely retrieve the content provider associated with the connection.
6881         IContentProvider provider;
6882         synchronized (this) {
6883             provider = conn.provider.provider;
6884         }
6885
6886         if (provider == null) {
6887             // Um, yeah, we're way ahead of you.
6888             return;
6889         }
6890
6891         // Make sure the caller is being honest with us.
6892         if (provider.asBinder().pingBinder()) {
6893             // Er, no, still looks good to us.
6894             synchronized (this) {
6895                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6896                         + " says " + conn + " died, but we don't agree");
6897                 return;
6898             }
6899         }
6900
6901         // Well look at that!  It's dead!
6902         synchronized (this) {
6903             if (conn.provider.provider != provider) {
6904                 // But something changed...  good enough.
6905                 return;
6906             }
6907
6908             ProcessRecord proc = conn.provider.proc;
6909             if (proc == null || proc.thread == null) {
6910                 // Seems like the process is already cleaned up.
6911                 return;
6912             }
6913
6914             // As far as we're concerned, this is just like receiving a
6915             // death notification...  just a bit prematurely.
6916             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6917                     + ") early provider death");
6918             final long ident = Binder.clearCallingIdentity();
6919             try {
6920                 appDiedLocked(proc, proc.pid, proc.thread);
6921             } finally {
6922                 Binder.restoreCallingIdentity(ident);
6923             }
6924         }
6925     }
6926
6927     public static final void installSystemProviders() {
6928         List<ProviderInfo> providers;
6929         synchronized (mSelf) {
6930             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6931             providers = mSelf.generateApplicationProvidersLocked(app);
6932             if (providers != null) {
6933                 for (int i=providers.size()-1; i>=0; i--) {
6934                     ProviderInfo pi = (ProviderInfo)providers.get(i);
6935                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6936                         Slog.w(TAG, "Not installing system proc provider " + pi.name
6937                                 + ": not system .apk");
6938                         providers.remove(i);
6939                     }
6940                 }
6941             }
6942         }
6943         if (providers != null) {
6944             mSystemThread.installSystemProviders(providers);
6945         }
6946
6947         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6948
6949         mSelf.mUsageStatsService.monitorPackages();
6950     }
6951
6952     /**
6953      * Allows app to retrieve the MIME type of a URI without having permission
6954      * to access its content provider.
6955      *
6956      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6957      *
6958      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6959      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6960      */
6961     public String getProviderMimeType(Uri uri, int userId) {
6962         enforceNotIsolatedCaller("getProviderMimeType");
6963         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6964                 userId, false, true, "getProviderMimeType", null);
6965         final String name = uri.getAuthority();
6966         final long ident = Binder.clearCallingIdentity();
6967         ContentProviderHolder holder = null;
6968
6969         try {
6970             holder = getContentProviderExternalUnchecked(name, null, userId);
6971             if (holder != null) {
6972                 return holder.provider.getType(uri);
6973             }
6974         } catch (RemoteException e) {
6975             Log.w(TAG, "Content provider dead retrieving " + uri, e);
6976             return null;
6977         } finally {
6978             if (holder != null) {
6979                 removeContentProviderExternalUnchecked(name, null, userId);
6980             }
6981             Binder.restoreCallingIdentity(ident);
6982         }
6983
6984         return null;
6985     }
6986
6987     // =========================================================
6988     // GLOBAL MANAGEMENT
6989     // =========================================================
6990
6991     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6992             ApplicationInfo info, String customProcess, boolean isolated) {
6993         String proc = customProcess != null ? customProcess : info.processName;
6994         BatteryStatsImpl.Uid.Proc ps = null;
6995         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6996         int uid = info.uid;
6997         if (isolated) {
6998             int userId = UserHandle.getUserId(uid);
6999             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7000             uid = 0;
7001             while (true) {
7002                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7003                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7004                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7005                 }
7006                 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
7007                 mNextIsolatedProcessUid++;
7008                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7009                     // No process for this uid, use it.
7010                     break;
7011                 }
7012                 stepsLeft--;
7013                 if (stepsLeft <= 0) {
7014                     return null;
7015                 }
7016             }
7017         }
7018         synchronized (stats) {
7019             ps = stats.getProcessStatsLocked(info.uid, proc);
7020         }
7021         return new ProcessRecord(ps, thread, info, proc, uid);
7022     }
7023
7024     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7025         ProcessRecord app;
7026         if (!isolated) {
7027             app = getProcessRecordLocked(info.processName, info.uid);
7028         } else {
7029             app = null;
7030         }
7031
7032         if (app == null) {
7033             app = newProcessRecordLocked(null, info, null, isolated);
7034             mProcessNames.put(info.processName, app.uid, app);
7035             if (isolated) {
7036                 mIsolatedProcesses.put(app.uid, app);
7037             }
7038             updateLruProcessLocked(app, true);
7039         }
7040
7041         // This package really, really can not be stopped.
7042         try {
7043             AppGlobals.getPackageManager().setPackageStoppedState(
7044                     info.packageName, false, UserHandle.getUserId(app.uid));
7045         } catch (RemoteException e) {
7046         } catch (IllegalArgumentException e) {
7047             Slog.w(TAG, "Failed trying to unstop package "
7048                     + info.packageName + ": " + e);
7049         }
7050
7051         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7052                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7053             app.persistent = true;
7054             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7055         }
7056         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7057             mPersistentStartingProcesses.add(app);
7058             startProcessLocked(app, "added application", app.processName);
7059         }
7060
7061         return app;
7062     }
7063
7064     public void unhandledBack() {
7065         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7066                 "unhandledBack()");
7067
7068         synchronized(this) {
7069             int count = mMainStack.mHistory.size();
7070             if (DEBUG_SWITCH) Slog.d(
7071                 TAG, "Performing unhandledBack(): stack size = " + count);
7072             if (count > 1) {
7073                 final long origId = Binder.clearCallingIdentity();
7074                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7075                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7076                 Binder.restoreCallingIdentity(origId);
7077             }
7078         }
7079     }
7080
7081     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7082         enforceNotIsolatedCaller("openContentUri");
7083         final int userId = UserHandle.getCallingUserId();
7084         String name = uri.getAuthority();
7085         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7086         ParcelFileDescriptor pfd = null;
7087         if (cph != null) {
7088             // We record the binder invoker's uid in thread-local storage before
7089             // going to the content provider to open the file.  Later, in the code
7090             // that handles all permissions checks, we look for this uid and use
7091             // that rather than the Activity Manager's own uid.  The effect is that
7092             // we do the check against the caller's permissions even though it looks
7093             // to the content provider like the Activity Manager itself is making
7094             // the request.
7095             sCallerIdentity.set(new Identity(
7096                     Binder.getCallingPid(), Binder.getCallingUid()));
7097             try {
7098                 pfd = cph.provider.openFile(uri, "r");
7099             } catch (FileNotFoundException e) {
7100                 // do nothing; pfd will be returned null
7101             } finally {
7102                 // Ensure that whatever happens, we clean up the identity state
7103                 sCallerIdentity.remove();
7104             }
7105
7106             // We've got the fd now, so we're done with the provider.
7107             removeContentProviderExternalUnchecked(name, null, userId);
7108         } else {
7109             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7110         }
7111         return pfd;
7112     }
7113
7114     // Actually is sleeping or shutting down or whatever else in the future
7115     // is an inactive state.
7116     public boolean isSleeping() {
7117         return mSleeping || mShuttingDown;
7118     }
7119
7120     public void goingToSleep() {
7121         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7122                 != PackageManager.PERMISSION_GRANTED) {
7123             throw new SecurityException("Requires permission "
7124                     + android.Manifest.permission.DEVICE_POWER);
7125         }
7126
7127         synchronized(this) {
7128             mWentToSleep = true;
7129             updateEventDispatchingLocked();
7130
7131             if (!mSleeping) {
7132                 mSleeping = true;
7133                 mMainStack.stopIfSleepingLocked();
7134
7135                 // Initialize the wake times of all processes.
7136                 checkExcessivePowerUsageLocked(false);
7137                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7138                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7139                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7140             }
7141         }
7142     }
7143
7144     public boolean shutdown(int timeout) {
7145         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7146                 != PackageManager.PERMISSION_GRANTED) {
7147             throw new SecurityException("Requires permission "
7148                     + android.Manifest.permission.SHUTDOWN);
7149         }
7150         
7151         boolean timedout = false;
7152         
7153         synchronized(this) {
7154             mShuttingDown = true;
7155             updateEventDispatchingLocked();
7156
7157             if (mMainStack.mResumedActivity != null) {
7158                 mMainStack.stopIfSleepingLocked();
7159                 final long endTime = System.currentTimeMillis() + timeout;
7160                 while (mMainStack.mResumedActivity != null
7161                         || mMainStack.mPausingActivity != null) {
7162                     long delay = endTime - System.currentTimeMillis();
7163                     if (delay <= 0) {
7164                         Slog.w(TAG, "Activity manager shutdown timed out");
7165                         timedout = true;
7166                         break;
7167                     }
7168                     try {
7169                         this.wait();
7170                     } catch (InterruptedException e) {
7171                     }
7172                 }
7173             }
7174         }
7175         
7176         mUsageStatsService.shutdown();
7177         mBatteryStatsService.shutdown();
7178         
7179         return timedout;
7180     }
7181     
7182     public final void activitySlept(IBinder token) {
7183         if (localLOGV) Slog.v(
7184             TAG, "Activity slept: token=" + token);
7185
7186         ActivityRecord r = null;
7187
7188         final long origId = Binder.clearCallingIdentity();
7189
7190         synchronized (this) {
7191             r = mMainStack.isInStackLocked(token);
7192             if (r != null) {
7193                 mMainStack.activitySleptLocked(r);
7194             }
7195         }
7196
7197         Binder.restoreCallingIdentity(origId);
7198     }
7199
7200     private void comeOutOfSleepIfNeededLocked() {
7201         if (!mWentToSleep && !mLockScreenShown) {
7202             if (mSleeping) {
7203                 mSleeping = false;
7204                 mMainStack.awakeFromSleepingLocked();
7205                 mMainStack.resumeTopActivityLocked(null);
7206             }
7207         }
7208     }
7209
7210     public void wakingUp() {
7211         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7212                 != PackageManager.PERMISSION_GRANTED) {
7213             throw new SecurityException("Requires permission "
7214                     + android.Manifest.permission.DEVICE_POWER);
7215         }
7216
7217         synchronized(this) {
7218             mWentToSleep = false;
7219             updateEventDispatchingLocked();
7220             comeOutOfSleepIfNeededLocked();
7221         }
7222     }
7223
7224     private void updateEventDispatchingLocked() {
7225         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7226     }
7227
7228     public void setLockScreenShown(boolean shown) {
7229         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7230                 != PackageManager.PERMISSION_GRANTED) {
7231             throw new SecurityException("Requires permission "
7232                     + android.Manifest.permission.DEVICE_POWER);
7233         }
7234
7235         synchronized(this) {
7236             mLockScreenShown = shown;
7237             comeOutOfSleepIfNeededLocked();
7238         }
7239     }
7240
7241     public void stopAppSwitches() {
7242         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7243                 != PackageManager.PERMISSION_GRANTED) {
7244             throw new SecurityException("Requires permission "
7245                     + android.Manifest.permission.STOP_APP_SWITCHES);
7246         }
7247         
7248         synchronized(this) {
7249             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7250                     + APP_SWITCH_DELAY_TIME;
7251             mDidAppSwitch = false;
7252             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7253             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7254             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7255         }
7256     }
7257     
7258     public void resumeAppSwitches() {
7259         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7260                 != PackageManager.PERMISSION_GRANTED) {
7261             throw new SecurityException("Requires permission "
7262                     + android.Manifest.permission.STOP_APP_SWITCHES);
7263         }
7264         
7265         synchronized(this) {
7266             // Note that we don't execute any pending app switches... we will
7267             // let those wait until either the timeout, or the next start
7268             // activity request.
7269             mAppSwitchesAllowedTime = 0;
7270         }
7271     }
7272     
7273     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7274             String name) {
7275         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7276             return true;
7277         }
7278             
7279         final int perm = checkComponentPermission(
7280                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7281                 callingUid, -1, true);
7282         if (perm == PackageManager.PERMISSION_GRANTED) {
7283             return true;
7284         }
7285         
7286         Slog.w(TAG, name + " request from " + callingUid + " stopped");
7287         return false;
7288     }
7289     
7290     public void setDebugApp(String packageName, boolean waitForDebugger,
7291             boolean persistent) {
7292         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7293                 "setDebugApp()");
7294
7295         // Note that this is not really thread safe if there are multiple
7296         // callers into it at the same time, but that's not a situation we
7297         // care about.
7298         if (persistent) {
7299             final ContentResolver resolver = mContext.getContentResolver();
7300             Settings.Global.putString(
7301                 resolver, Settings.Global.DEBUG_APP,
7302                 packageName);
7303             Settings.Global.putInt(
7304                 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
7305                 waitForDebugger ? 1 : 0);
7306         }
7307
7308         synchronized (this) {
7309             if (!persistent) {
7310                 mOrigDebugApp = mDebugApp;
7311                 mOrigWaitForDebugger = mWaitForDebugger;
7312             }
7313             mDebugApp = packageName;
7314             mWaitForDebugger = waitForDebugger;
7315             mDebugTransient = !persistent;
7316             if (packageName != null) {
7317                 final long origId = Binder.clearCallingIdentity();
7318                 forceStopPackageLocked(packageName, -1, false, false, true, true,
7319                         UserHandle.USER_ALL);
7320                 Binder.restoreCallingIdentity(origId);
7321             }
7322         }
7323     }
7324
7325     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7326         synchronized (this) {
7327             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7328             if (!isDebuggable) {
7329                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7330                     throw new SecurityException("Process not debuggable: " + app.packageName);
7331                 }
7332             }
7333
7334             mOpenGlTraceApp = processName;
7335         }
7336     }
7337
7338     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7339             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7340         synchronized (this) {
7341             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7342             if (!isDebuggable) {
7343                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7344                     throw new SecurityException("Process not debuggable: " + app.packageName);
7345                 }
7346             }
7347             mProfileApp = processName;
7348             mProfileFile = profileFile;
7349             if (mProfileFd != null) {
7350                 try {
7351                     mProfileFd.close();
7352                 } catch (IOException e) {
7353                 }
7354                 mProfileFd = null;
7355             }
7356             mProfileFd = profileFd;
7357             mProfileType = 0;
7358             mAutoStopProfiler = autoStopProfiler;
7359         }
7360     }
7361
7362     public void setAlwaysFinish(boolean enabled) {
7363         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7364                 "setAlwaysFinish()");
7365
7366         Settings.Global.putInt(
7367                 mContext.getContentResolver(),
7368                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7369         
7370         synchronized (this) {
7371             mAlwaysFinishActivities = enabled;
7372         }
7373     }
7374
7375     public void setActivityController(IActivityController controller) {
7376         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7377                 "setActivityController()");
7378         synchronized (this) {
7379             mController = controller;
7380         }
7381     }
7382
7383     public boolean isUserAMonkey() {
7384         // For now the fact that there is a controller implies
7385         // we have a monkey.
7386         synchronized (this) {
7387             return mController != null;
7388         }
7389     }
7390
7391     public void requestBugReport() {
7392         // No permission check because this can't do anything harmful --
7393         // it will just eventually cause the user to be presented with
7394         // a UI to select where the bug report goes.
7395         SystemProperties.set("ctl.start", "bugreport");
7396     }
7397
7398     public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7399         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7400                 != PackageManager.PERMISSION_GRANTED) {
7401             throw new SecurityException("Requires permission "
7402                     + android.Manifest.permission.FILTER_EVENTS);
7403         }
7404
7405         ProcessRecord proc;
7406
7407         // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7408         synchronized (this) {
7409             synchronized (mPidsSelfLocked) {
7410                 proc = mPidsSelfLocked.get(pid);
7411             }
7412             if (proc != null) {
7413                 if (proc.debugging) {
7414                     return -1;
7415                 }
7416
7417                 if (mDidDexOpt) {
7418                     // Give more time since we were dexopting.
7419                     mDidDexOpt = false;
7420                     return -1;
7421                 }
7422
7423                 if (proc.instrumentationClass != null) {
7424                     Bundle info = new Bundle();
7425                     info.putString("shortMsg", "keyDispatchingTimedOut");
7426                     info.putString("longMsg", "Timed out while dispatching key event");
7427                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7428                     proc = null;
7429                 }
7430             }
7431         }
7432
7433         if (proc != null) {
7434             appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7435             if (proc.instrumentationClass != null || proc.usingWrapper) {
7436                 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7437             }
7438         }
7439
7440         return KEY_DISPATCHING_TIMEOUT;
7441     }
7442
7443     public void registerProcessObserver(IProcessObserver observer) {
7444         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7445                 "registerProcessObserver()");
7446         synchronized (this) {
7447             mProcessObservers.register(observer);
7448         }
7449     }
7450
7451     public void unregisterProcessObserver(IProcessObserver observer) {
7452         synchronized (this) {
7453             mProcessObservers.unregister(observer);
7454         }
7455     }
7456
7457     public void setImmersive(IBinder token, boolean immersive) {
7458         synchronized(this) {
7459             final ActivityRecord r = mMainStack.isInStackLocked(token);
7460             if (r == null) {
7461                 throw new IllegalArgumentException();
7462             }
7463             r.immersive = immersive;
7464
7465             // update associated state if we're frontmost
7466             if (r == mFocusedActivity) {
7467                 if (DEBUG_IMMERSIVE) {
7468                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
7469                 }
7470                 applyUpdateLockStateLocked(r);
7471             }
7472         }
7473     }
7474
7475     public boolean isImmersive(IBinder token) {
7476         synchronized (this) {
7477             ActivityRecord r = mMainStack.isInStackLocked(token);
7478             if (r == null) {
7479                 throw new IllegalArgumentException();
7480             }
7481             return r.immersive;
7482         }
7483     }
7484
7485     public boolean isTopActivityImmersive() {
7486         enforceNotIsolatedCaller("startActivity");
7487         synchronized (this) {
7488             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7489             return (r != null) ? r.immersive : false;
7490         }
7491     }
7492
7493     public final void enterSafeMode() {
7494         synchronized(this) {
7495             // It only makes sense to do this before the system is ready
7496             // and started launching other packages.
7497             if (!mSystemReady) {
7498                 try {
7499                     AppGlobals.getPackageManager().enterSafeMode();
7500                 } catch (RemoteException e) {
7501                 }
7502             }
7503         }
7504     }
7505
7506     public final void showSafeModeOverlay() {
7507         View v = LayoutInflater.from(mContext).inflate(
7508                 com.android.internal.R.layout.safe_mode, null);
7509         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7510         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7511         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7512         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7513         lp.gravity = Gravity.BOTTOM | Gravity.START;
7514         lp.format = v.getBackground().getOpacity();
7515         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7516                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7517         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7518         ((WindowManager)mContext.getSystemService(
7519                 Context.WINDOW_SERVICE)).addView(v, lp);
7520     }
7521
7522     public void noteWakeupAlarm(IIntentSender sender) {
7523         if (!(sender instanceof PendingIntentRecord)) {
7524             return;
7525         }
7526         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7527         synchronized (stats) {
7528             if (mBatteryStatsService.isOnBattery()) {
7529                 mBatteryStatsService.enforceCallingPermission();
7530                 PendingIntentRecord rec = (PendingIntentRecord)sender;
7531                 int MY_UID = Binder.getCallingUid();
7532                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7533                 BatteryStatsImpl.Uid.Pkg pkg =
7534                     stats.getPackageStatsLocked(uid, rec.key.packageName);
7535                 pkg.incWakeupsLocked();
7536             }
7537         }
7538     }
7539
7540     public boolean killPids(int[] pids, String pReason, boolean secure) {
7541         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7542             throw new SecurityException("killPids only available to the system");
7543         }
7544         String reason = (pReason == null) ? "Unknown" : pReason;
7545         // XXX Note: don't acquire main activity lock here, because the window
7546         // manager calls in with its locks held.
7547         
7548         boolean killed = false;
7549         synchronized (mPidsSelfLocked) {
7550             int[] types = new int[pids.length];
7551             int worstType = 0;
7552             for (int i=0; i<pids.length; i++) {
7553                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7554                 if (proc != null) {
7555                     int type = proc.setAdj;
7556                     types[i] = type;
7557                     if (type > worstType) {
7558                         worstType = type;
7559                     }
7560                 }
7561             }
7562             
7563             // If the worst oom_adj is somewhere in the hidden proc LRU range,
7564             // then constrain it so we will kill all hidden procs.
7565             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7566                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7567                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7568             }
7569
7570             // If this is not a secure call, don't let it kill processes that
7571             // are important.
7572             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7573                 worstType = ProcessList.SERVICE_ADJ;
7574             }
7575
7576             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7577             for (int i=0; i<pids.length; i++) {
7578                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7579                 if (proc == null) {
7580                     continue;
7581                 }
7582                 int adj = proc.setAdj;
7583                 if (adj >= worstType && !proc.killedBackground) {
7584                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7585                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7586                             proc.processName, adj, reason);
7587                     killed = true;
7588                     proc.killedBackground = true;
7589                     Process.killProcessQuiet(pids[i]);
7590                 }
7591             }
7592         }
7593         return killed;
7594     }
7595
7596     @Override
7597     public boolean killProcessesBelowForeground(String reason) {
7598         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7599             throw new SecurityException("killProcessesBelowForeground() only available to system");
7600         }
7601
7602         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7603     }
7604
7605     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7606         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7607             throw new SecurityException("killProcessesBelowAdj() only available to system");
7608         }
7609
7610         boolean killed = false;
7611         synchronized (mPidsSelfLocked) {
7612             final int size = mPidsSelfLocked.size();
7613             for (int i = 0; i < size; i++) {
7614                 final int pid = mPidsSelfLocked.keyAt(i);
7615                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7616                 if (proc == null) continue;
7617
7618                 final int adj = proc.setAdj;
7619                 if (adj > belowAdj && !proc.killedBackground) {
7620                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7621                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7622                             proc.pid, proc.processName, adj, reason);
7623                     killed = true;
7624                     proc.killedBackground = true;
7625                     Process.killProcessQuiet(pid);
7626                 }
7627             }
7628         }
7629         return killed;
7630     }
7631
7632     public final void startRunning(String pkg, String cls, String action,
7633             String data) {
7634         synchronized(this) {
7635             if (mStartRunning) {
7636                 return;
7637             }
7638             mStartRunning = true;
7639             mTopComponent = pkg != null && cls != null
7640                     ? new ComponentName(pkg, cls) : null;
7641             mTopAction = action != null ? action : Intent.ACTION_MAIN;
7642             mTopData = data;
7643             if (!mSystemReady) {
7644                 return;
7645             }
7646         }
7647
7648         systemReady(null);
7649     }
7650
7651     private void retrieveSettings() {
7652         final ContentResolver resolver = mContext.getContentResolver();
7653         String debugApp = Settings.Global.getString(
7654             resolver, Settings.Global.DEBUG_APP);
7655         boolean waitForDebugger = Settings.Global.getInt(
7656             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
7657         boolean alwaysFinishActivities = Settings.Global.getInt(
7658             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7659
7660         Configuration configuration = new Configuration();
7661         Settings.System.getConfiguration(resolver, configuration);
7662
7663         synchronized (this) {
7664             mDebugApp = mOrigDebugApp = debugApp;
7665             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7666             mAlwaysFinishActivities = alwaysFinishActivities;
7667             // This happens before any activities are started, so we can
7668             // change mConfiguration in-place.
7669             updateConfigurationLocked(configuration, null, false, true);
7670             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7671         }
7672     }
7673
7674     public boolean testIsSystemReady() {
7675         // no need to synchronize(this) just to read & return the value
7676         return mSystemReady;
7677     }
7678     
7679     private static File getCalledPreBootReceiversFile() {
7680         File dataDir = Environment.getDataDirectory();
7681         File systemDir = new File(dataDir, "system");
7682         File fname = new File(systemDir, "called_pre_boots.dat");
7683         return fname;
7684     }
7685
7686     static final int LAST_DONE_VERSION = 10000;
7687
7688     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7689         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7690         File file = getCalledPreBootReceiversFile();
7691         FileInputStream fis = null;
7692         try {
7693             fis = new FileInputStream(file);
7694             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7695             int fvers = dis.readInt();
7696             if (fvers == LAST_DONE_VERSION) {
7697                 String vers = dis.readUTF();
7698                 String codename = dis.readUTF();
7699                 String build = dis.readUTF();
7700                 if (android.os.Build.VERSION.RELEASE.equals(vers)
7701                         && android.os.Build.VERSION.CODENAME.equals(codename)
7702                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7703                     int num = dis.readInt();
7704                     while (num > 0) {
7705                         num--;
7706                         String pkg = dis.readUTF();
7707                         String cls = dis.readUTF();
7708                         lastDoneReceivers.add(new ComponentName(pkg, cls));
7709                     }
7710                 }
7711             }
7712         } catch (FileNotFoundException e) {
7713         } catch (IOException e) {
7714             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7715         } finally {
7716             if (fis != null) {
7717                 try {
7718                     fis.close();
7719                 } catch (IOException e) {
7720                 }
7721             }
7722         }
7723         return lastDoneReceivers;
7724     }
7725     
7726     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7727         File file = getCalledPreBootReceiversFile();
7728         FileOutputStream fos = null;
7729         DataOutputStream dos = null;
7730         try {
7731             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7732             fos = new FileOutputStream(file);
7733             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7734             dos.writeInt(LAST_DONE_VERSION);
7735             dos.writeUTF(android.os.Build.VERSION.RELEASE);
7736             dos.writeUTF(android.os.Build.VERSION.CODENAME);
7737             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7738             dos.writeInt(list.size());
7739             for (int i=0; i<list.size(); i++) {
7740                 dos.writeUTF(list.get(i).getPackageName());
7741                 dos.writeUTF(list.get(i).getClassName());
7742             }
7743         } catch (IOException e) {
7744             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7745             file.delete();
7746         } finally {
7747             FileUtils.sync(fos);
7748             if (dos != null) {
7749                 try {
7750                     dos.close();
7751                 } catch (IOException e) {
7752                     // TODO Auto-generated catch block
7753                     e.printStackTrace();
7754                 }
7755             }
7756         }
7757     }
7758     
7759     public void systemReady(final Runnable goingCallback) {
7760         synchronized(this) {
7761             if (mSystemReady) {
7762                 if (goingCallback != null) goingCallback.run();
7763                 return;
7764             }
7765             
7766             // Check to see if there are any update receivers to run.
7767             if (!mDidUpdate) {
7768                 if (mWaitingUpdate) {
7769                     return;
7770                 }
7771                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7772                 List<ResolveInfo> ris = null;
7773                 try {
7774                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
7775                             intent, null, 0, 0);
7776                 } catch (RemoteException e) {
7777                 }
7778                 if (ris != null) {
7779                     for (int i=ris.size()-1; i>=0; i--) {
7780                         if ((ris.get(i).activityInfo.applicationInfo.flags
7781                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7782                             ris.remove(i);
7783                         }
7784                     }
7785                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7786
7787                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7788
7789                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7790                     for (int i=0; i<ris.size(); i++) {
7791                         ActivityInfo ai = ris.get(i).activityInfo;
7792                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
7793                         if (lastDoneReceivers.contains(comp)) {
7794                             ris.remove(i);
7795                             i--;
7796                         }
7797                     }
7798
7799                     final int[] users = getUsersLocked();
7800                     for (int i=0; i<ris.size(); i++) {
7801                         ActivityInfo ai = ris.get(i).activityInfo;
7802                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
7803                         doneReceivers.add(comp);
7804                         intent.setComponent(comp);
7805                         for (int j=0; j<users.length; j++) {
7806                             IIntentReceiver finisher = null;
7807                             if (i == ris.size()-1 && j == users.length-1) {
7808                                 finisher = new IIntentReceiver.Stub() {
7809                                     public void performReceive(Intent intent, int resultCode,
7810                                             String data, Bundle extras, boolean ordered,
7811                                             boolean sticky, int sendingUser) {
7812                                         // The raw IIntentReceiver interface is called
7813                                         // with the AM lock held, so redispatch to
7814                                         // execute our code without the lock.
7815                                         mHandler.post(new Runnable() {
7816                                             public void run() {
7817                                                 synchronized (ActivityManagerService.this) {
7818                                                     mDidUpdate = true;
7819                                                 }
7820                                                 writeLastDonePreBootReceivers(doneReceivers);
7821                                                 showBootMessage(mContext.getText(
7822                                                         R.string.android_upgrading_complete),
7823                                                         false);
7824                                                 systemReady(goingCallback);
7825                                             }
7826                                         });
7827                                     }
7828                                 };
7829                             }
7830                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
7831                                     + " for user " + users[j]);
7832                             broadcastIntentLocked(null, null, intent, null, finisher,
7833                                     0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7834                                     users[j]);
7835                             if (finisher != null) {
7836                                 mWaitingUpdate = true;
7837                             }
7838                         }
7839                     }
7840                 }
7841                 if (mWaitingUpdate) {
7842                     return;
7843                 }
7844                 mDidUpdate = true;
7845             }
7846             
7847             mSystemReady = true;
7848             if (!mStartRunning) {
7849                 return;
7850             }
7851         }
7852
7853         ArrayList<ProcessRecord> procsToKill = null;
7854         synchronized(mPidsSelfLocked) {
7855             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7856                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7857                 if (!isAllowedWhileBooting(proc.info)){
7858                     if (procsToKill == null) {
7859                         procsToKill = new ArrayList<ProcessRecord>();
7860                     }
7861                     procsToKill.add(proc);
7862                 }
7863             }
7864         }
7865         
7866         synchronized(this) {
7867             if (procsToKill != null) {
7868                 for (int i=procsToKill.size()-1; i>=0; i--) {
7869                     ProcessRecord proc = procsToKill.get(i);
7870                     Slog.i(TAG, "Removing system update proc: " + proc);
7871                     removeProcessLocked(proc, true, false, "system update done");
7872                 }
7873             }
7874             
7875             // Now that we have cleaned up any update processes, we
7876             // are ready to start launching real processes and know that
7877             // we won't trample on them any more.
7878             mProcessesReady = true;
7879         }
7880         
7881         Slog.i(TAG, "System now ready");
7882         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7883             SystemClock.uptimeMillis());
7884
7885         synchronized(this) {
7886             // Make sure we have no pre-ready processes sitting around.
7887             
7888             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7889                 ResolveInfo ri = mContext.getPackageManager()
7890                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7891                                 STOCK_PM_FLAGS);
7892                 CharSequence errorMsg = null;
7893                 if (ri != null) {
7894                     ActivityInfo ai = ri.activityInfo;
7895                     ApplicationInfo app = ai.applicationInfo;
7896                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7897                         mTopAction = Intent.ACTION_FACTORY_TEST;
7898                         mTopData = null;
7899                         mTopComponent = new ComponentName(app.packageName,
7900                                 ai.name);
7901                     } else {
7902                         errorMsg = mContext.getResources().getText(
7903                                 com.android.internal.R.string.factorytest_not_system);
7904                     }
7905                 } else {
7906                     errorMsg = mContext.getResources().getText(
7907                             com.android.internal.R.string.factorytest_no_action);
7908                 }
7909                 if (errorMsg != null) {
7910                     mTopAction = null;
7911                     mTopData = null;
7912                     mTopComponent = null;
7913                     Message msg = Message.obtain();
7914                     msg.what = SHOW_FACTORY_ERROR_MSG;
7915                     msg.getData().putCharSequence("msg", errorMsg);
7916                     mHandler.sendMessage(msg);
7917                 }
7918             }
7919         }
7920
7921         retrieveSettings();
7922
7923         if (goingCallback != null) goingCallback.run();
7924         
7925         synchronized (this) {
7926             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7927                 try {
7928                     List apps = AppGlobals.getPackageManager().
7929                         getPersistentApplications(STOCK_PM_FLAGS);
7930                     if (apps != null) {
7931                         int N = apps.size();
7932                         int i;
7933                         for (i=0; i<N; i++) {
7934                             ApplicationInfo info
7935                                 = (ApplicationInfo)apps.get(i);
7936                             if (info != null &&
7937                                     !info.packageName.equals("android")) {
7938                                 addAppLocked(info, false);
7939                             }
7940                         }
7941                     }
7942                 } catch (RemoteException ex) {
7943                     // pm is in same process, this will never happen.
7944                 }
7945             }
7946
7947             // Start up initial activity.
7948             mBooting = true;
7949             
7950             try {
7951                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7952                     Message msg = Message.obtain();
7953                     msg.what = SHOW_UID_ERROR_MSG;
7954                     mHandler.sendMessage(msg);
7955                 }
7956             } catch (RemoteException e) {
7957             }
7958
7959             long ident = Binder.clearCallingIdentity();
7960             try {
7961                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7962                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7963                         | Intent.FLAG_RECEIVER_FOREGROUND);
7964                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7965                 broadcastIntentLocked(null, null, intent,
7966                         null, null, 0, null, null, null,
7967                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7968                 intent = new Intent(Intent.ACTION_USER_STARTING);
7969                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7970                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7971                 broadcastIntentLocked(null, null, intent,
7972                         null, new IIntentReceiver.Stub() {
7973                             @Override
7974                             public void performReceive(Intent intent, int resultCode, String data,
7975                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
7976                                     throws RemoteException {
7977                             }
7978                         }, 0, null, null,
7979                         android.Manifest.permission.INTERACT_ACROSS_USERS,
7980                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
7981             } finally {
7982                 Binder.restoreCallingIdentity(ident);
7983             }
7984             mMainStack.resumeTopActivityLocked(null);
7985             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7986         }
7987     }
7988
7989     private boolean makeAppCrashingLocked(ProcessRecord app,
7990             String shortMsg, String longMsg, String stackTrace) {
7991         app.crashing = true;
7992         app.crashingReport = generateProcessError(app,
7993                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7994         startAppProblemLocked(app);
7995         app.stopFreezingAllLocked();
7996         return handleAppCrashLocked(app);
7997     }
7998
7999     private void makeAppNotRespondingLocked(ProcessRecord app,
8000             String activity, String shortMsg, String longMsg) {
8001         app.notResponding = true;
8002         app.notRespondingReport = generateProcessError(app,
8003                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8004                 activity, shortMsg, longMsg, null);
8005         startAppProblemLocked(app);
8006         app.stopFreezingAllLocked();
8007     }
8008     
8009     /**
8010      * Generate a process error record, suitable for attachment to a ProcessRecord.
8011      * 
8012      * @param app The ProcessRecord in which the error occurred.
8013      * @param condition Crashing, Application Not Responding, etc.  Values are defined in 
8014      *                      ActivityManager.AppErrorStateInfo
8015      * @param activity The activity associated with the crash, if known.
8016      * @param shortMsg Short message describing the crash.
8017      * @param longMsg Long message describing the crash.
8018      * @param stackTrace Full crash stack trace, may be null.
8019      *
8020      * @return Returns a fully-formed AppErrorStateInfo record.
8021      */
8022     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 
8023             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
8024         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8025
8026         report.condition = condition;
8027         report.processName = app.processName;
8028         report.pid = app.pid;
8029         report.uid = app.info.uid;
8030         report.tag = activity;
8031         report.shortMsg = shortMsg;
8032         report.longMsg = longMsg;
8033         report.stackTrace = stackTrace;
8034
8035         return report;
8036     }
8037
8038     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
8039         synchronized (this) {
8040             app.crashing = false;
8041             app.crashingReport = null;
8042             app.notResponding = false;
8043             app.notRespondingReport = null;
8044             if (app.anrDialog == fromDialog) {
8045                 app.anrDialog = null;
8046             }
8047             if (app.waitDialog == fromDialog) {
8048                 app.waitDialog = null;
8049             }
8050             if (app.pid > 0 && app.pid != MY_PID) {
8051                 handleAppCrashLocked(app);
8052                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
8053                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
8054                         app.processName, app.setAdj, "user's request after error");
8055                 Process.killProcessQuiet(app.pid);
8056             }
8057         }
8058     }
8059
8060     private boolean handleAppCrashLocked(ProcessRecord app) {
8061         if (mHeadless) {
8062             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8063             return false;
8064         }
8065         long now = SystemClock.uptimeMillis();
8066
8067         Long crashTime;
8068         if (!app.isolated) {
8069             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8070         } else {
8071             crashTime = null;
8072         }
8073         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8074             // This process loses!
8075             Slog.w(TAG, "Process " + app.info.processName
8076                     + " has crashed too many times: killing!");
8077             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8078                     app.userId, app.info.processName, app.uid);
8079             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8080                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8081                 if (r.app == app) {
8082                     Slog.w(TAG, "  Force finishing activity "
8083                         + r.intent.getComponent().flattenToShortString());
8084                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8085                             null, "crashed", false);
8086                 }
8087             }
8088             if (!app.persistent) {
8089                 // We don't want to start this process again until the user
8090                 // explicitly does so...  but for persistent process, we really
8091                 // need to keep it running.  If a persistent process is actually
8092                 // repeatedly crashing, then badness for everyone.
8093                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8094                         app.info.processName);
8095                 if (!app.isolated) {
8096                     // XXX We don't have a way to mark isolated processes
8097                     // as bad, since they don't have a peristent identity.
8098                     mBadProcesses.put(app.info.processName, app.uid, now);
8099                     mProcessCrashTimes.remove(app.info.processName, app.uid);
8100                 }
8101                 app.bad = true;
8102                 app.removed = true;
8103                 // Don't let services in this process be restarted and potentially
8104                 // annoy the user repeatedly.  Unless it is persistent, since those
8105                 // processes run critical code.
8106                 removeProcessLocked(app, false, false, "crash");
8107                 mMainStack.resumeTopActivityLocked(null);
8108                 return false;
8109             }
8110             mMainStack.resumeTopActivityLocked(null);
8111         } else {
8112             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8113             if (r != null && r.app == app) {
8114                 // If the top running activity is from this crashing
8115                 // process, then terminate it to avoid getting in a loop.
8116                 Slog.w(TAG, "  Force finishing activity "
8117                         + r.intent.getComponent().flattenToShortString());
8118                 int index = mMainStack.indexOfActivityLocked(r);
8119                 r.stack.finishActivityLocked(r, index,
8120                         Activity.RESULT_CANCELED, null, "crashed", false);
8121                 // Also terminate any activities below it that aren't yet
8122                 // stopped, to avoid a situation where one will get
8123                 // re-start our crashing activity once it gets resumed again.
8124                 index--;
8125                 if (index >= 0) {
8126                     r = (ActivityRecord)mMainStack.mHistory.get(index);
8127                     if (r.state == ActivityState.RESUMED
8128                             || r.state == ActivityState.PAUSING
8129                             || r.state == ActivityState.PAUSED) {
8130                         if (!r.isHomeActivity || mHomeProcess != r.app) {
8131                             Slog.w(TAG, "  Force finishing activity "
8132                                     + r.intent.getComponent().flattenToShortString());
8133                             r.stack.finishActivityLocked(r, index,
8134                                     Activity.RESULT_CANCELED, null, "crashed", false);
8135                         }
8136                     }
8137                 }
8138             }
8139         }
8140
8141         // Bump up the crash count of any services currently running in the proc.
8142         if (app.services.size() != 0) {
8143             // Any services running in the application need to be placed
8144             // back in the pending list.
8145             Iterator<ServiceRecord> it = app.services.iterator();
8146             while (it.hasNext()) {
8147                 ServiceRecord sr = it.next();
8148                 sr.crashCount++;
8149             }
8150         }
8151
8152         // If the crashing process is what we consider to be the "home process" and it has been
8153         // replaced by a third-party app, clear the package preferred activities from packages
8154         // with a home activity running in the process to prevent a repeatedly crashing app
8155         // from blocking the user to manually clear the list.
8156         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8157                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8158             Iterator it = mHomeProcess.activities.iterator();
8159             while (it.hasNext()) {
8160                 ActivityRecord r = (ActivityRecord)it.next();
8161                 if (r.isHomeActivity) {
8162                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8163                     try {
8164                         ActivityThread.getPackageManager()
8165                                 .clearPackagePreferredActivities(r.packageName);
8166                     } catch (RemoteException c) {
8167                         // pm is in same process, this will never happen.
8168                     }
8169                 }
8170             }
8171         }
8172
8173         if (!app.isolated) {
8174             // XXX Can't keep track of crash times for isolated processes,
8175             // because they don't have a perisistent identity.
8176             mProcessCrashTimes.put(app.info.processName, app.uid, now);
8177         }
8178
8179         return true;
8180     }
8181
8182     void startAppProblemLocked(ProcessRecord app) {
8183         if (app.userId == mCurrentUserId) {
8184             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8185                     mContext, app.info.packageName, app.info.flags);
8186         } else {
8187             // If this app is not running under the current user, then we
8188             // can't give it a report button because that would require
8189             // launching the report UI under a different user.
8190             app.errorReportReceiver = null;
8191         }
8192         skipCurrentReceiverLocked(app);
8193     }
8194
8195     void skipCurrentReceiverLocked(ProcessRecord app) {
8196         for (BroadcastQueue queue : mBroadcastQueues) {
8197             queue.skipCurrentReceiverLocked(app);
8198         }
8199     }
8200
8201     /**
8202      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8203      * The application process will exit immediately after this call returns.
8204      * @param app object of the crashing app, null for the system server
8205      * @param crashInfo describing the exception
8206      */
8207     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8208         ProcessRecord r = findAppProcess(app, "Crash");
8209         final String processName = app == null ? "system_server"
8210                 : (r == null ? "unknown" : r.processName);
8211
8212         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8213                 UserHandle.getUserId(Binder.getCallingUid()), processName,
8214                 r == null ? -1 : r.info.flags,
8215                 crashInfo.exceptionClassName,
8216                 crashInfo.exceptionMessage,
8217                 crashInfo.throwFileName,
8218                 crashInfo.throwLineNumber);
8219
8220         addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8221
8222         crashApplication(r, crashInfo);
8223     }
8224
8225     public void handleApplicationStrictModeViolation(
8226             IBinder app,
8227             int violationMask,
8228             StrictMode.ViolationInfo info) {
8229         ProcessRecord r = findAppProcess(app, "StrictMode");
8230         if (r == null) {
8231             return;
8232         }
8233
8234         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8235             Integer stackFingerprint = info.hashCode();
8236             boolean logIt = true;
8237             synchronized (mAlreadyLoggedViolatedStacks) {
8238                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8239                     logIt = false;
8240                     // TODO: sub-sample into EventLog for these, with
8241                     // the info.durationMillis?  Then we'd get
8242                     // the relative pain numbers, without logging all
8243                     // the stack traces repeatedly.  We'd want to do
8244                     // likewise in the client code, which also does
8245                     // dup suppression, before the Binder call.
8246                 } else {
8247                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8248                         mAlreadyLoggedViolatedStacks.clear();
8249                     }
8250                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8251                 }
8252             }
8253             if (logIt) {
8254                 logStrictModeViolationToDropBox(r, info);
8255             }
8256         }
8257
8258         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8259             AppErrorResult result = new AppErrorResult();
8260             synchronized (this) {
8261                 final long origId = Binder.clearCallingIdentity();
8262
8263                 Message msg = Message.obtain();
8264                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8265                 HashMap<String, Object> data = new HashMap<String, Object>();
8266                 data.put("result", result);
8267                 data.put("app", r);
8268                 data.put("violationMask", violationMask);
8269                 data.put("info", info);
8270                 msg.obj = data;
8271                 mHandler.sendMessage(msg);
8272
8273                 Binder.restoreCallingIdentity(origId);
8274             }
8275             int res = result.get();
8276             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8277         }
8278     }
8279
8280     // Depending on the policy in effect, there could be a bunch of
8281     // these in quick succession so we try to batch these together to
8282     // minimize disk writes, number of dropbox entries, and maximize
8283     // compression, by having more fewer, larger records.
8284     private void logStrictModeViolationToDropBox(
8285             ProcessRecord process,
8286             StrictMode.ViolationInfo info) {
8287         if (info == null) {
8288             return;
8289         }
8290         final boolean isSystemApp = process == null ||
8291                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8292                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8293         final String processName = process == null ? "unknown" : process.processName;
8294         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8295         final DropBoxManager dbox = (DropBoxManager)
8296                 mContext.getSystemService(Context.DROPBOX_SERVICE);
8297
8298         // Exit early if the dropbox isn't configured to accept this report type.
8299         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8300
8301         boolean bufferWasEmpty;
8302         boolean needsFlush;
8303         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8304         synchronized (sb) {
8305             bufferWasEmpty = sb.length() == 0;
8306             appendDropBoxProcessHeaders(process, processName, sb);
8307             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8308             sb.append("System-App: ").append(isSystemApp).append("\n");
8309             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8310             if (info.violationNumThisLoop != 0) {
8311                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8312             }
8313             if (info.numAnimationsRunning != 0) {
8314                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8315             }
8316             if (info.broadcastIntentAction != null) {
8317                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8318             }
8319             if (info.durationMillis != -1) {
8320                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8321             }
8322             if (info.numInstances != -1) {
8323                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8324             }
8325             if (info.tags != null) {
8326                 for (String tag : info.tags) {
8327                     sb.append("Span-Tag: ").append(tag).append("\n");
8328                 }
8329             }
8330             sb.append("\n");
8331             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8332                 sb.append(info.crashInfo.stackTrace);
8333             }
8334             sb.append("\n");
8335
8336             // Only buffer up to ~64k.  Various logging bits truncate
8337             // things at 128k.
8338             needsFlush = (sb.length() > 64 * 1024);
8339         }
8340
8341         // Flush immediately if the buffer's grown too large, or this
8342         // is a non-system app.  Non-system apps are isolated with a
8343         // different tag & policy and not batched.
8344         //
8345         // Batching is useful during internal testing with
8346         // StrictMode settings turned up high.  Without batching,
8347         // thousands of separate files could be created on boot.
8348         if (!isSystemApp || needsFlush) {
8349             new Thread("Error dump: " + dropboxTag) {
8350                 @Override
8351                 public void run() {
8352                     String report;
8353                     synchronized (sb) {
8354                         report = sb.toString();
8355                         sb.delete(0, sb.length());
8356                         sb.trimToSize();
8357                     }
8358                     if (report.length() != 0) {
8359                         dbox.addText(dropboxTag, report);
8360                     }
8361                 }
8362             }.start();
8363             return;
8364         }
8365
8366         // System app batching:
8367         if (!bufferWasEmpty) {
8368             // An existing dropbox-writing thread is outstanding, so
8369             // we don't need to start it up.  The existing thread will
8370             // catch the buffer appends we just did.
8371             return;
8372         }
8373
8374         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8375         // (After this point, we shouldn't access AMS internal data structures.)
8376         new Thread("Error dump: " + dropboxTag) {
8377             @Override
8378             public void run() {
8379                 // 5 second sleep to let stacks arrive and be batched together
8380                 try {
8381                     Thread.sleep(5000);  // 5 seconds
8382                 } catch (InterruptedException e) {}
8383
8384                 String errorReport;
8385                 synchronized (mStrictModeBuffer) {
8386                     errorReport = mStrictModeBuffer.toString();
8387                     if (errorReport.length() == 0) {
8388                         return;
8389                     }
8390                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8391                     mStrictModeBuffer.trimToSize();
8392                 }
8393                 dbox.addText(dropboxTag, errorReport);
8394             }
8395         }.start();
8396     }
8397
8398     /**
8399      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8400      * @param app object of the crashing app, null for the system server
8401      * @param tag reported by the caller
8402      * @param crashInfo describing the context of the error
8403      * @return true if the process should exit immediately (WTF is fatal)
8404      */
8405     public boolean handleApplicationWtf(IBinder app, String tag,
8406             ApplicationErrorReport.CrashInfo crashInfo) {
8407         ProcessRecord r = findAppProcess(app, "WTF");
8408         final String processName = app == null ? "system_server"
8409                 : (r == null ? "unknown" : r.processName);
8410
8411         EventLog.writeEvent(EventLogTags.AM_WTF,
8412                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8413                 processName,
8414                 r == null ? -1 : r.info.flags,
8415                 tag, crashInfo.exceptionMessage);
8416
8417         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8418
8419         if (r != null && r.pid != Process.myPid() &&
8420                 Settings.Global.getInt(mContext.getContentResolver(),
8421                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
8422             crashApplication(r, crashInfo);
8423             return true;
8424         } else {
8425             return false;
8426         }
8427     }
8428
8429     /**
8430      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8431      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8432      */
8433     private ProcessRecord findAppProcess(IBinder app, String reason) {
8434         if (app == null) {
8435             return null;
8436         }
8437
8438         synchronized (this) {
8439             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8440                 final int NA = apps.size();
8441                 for (int ia=0; ia<NA; ia++) {
8442                     ProcessRecord p = apps.valueAt(ia);
8443                     if (p.thread != null && p.thread.asBinder() == app) {
8444                         return p;
8445                     }
8446                 }
8447             }
8448
8449             Slog.w(TAG, "Can't find mystery application for " + reason
8450                     + " from pid=" + Binder.getCallingPid()
8451                     + " uid=" + Binder.getCallingUid() + ": " + app);
8452             return null;
8453         }
8454     }
8455
8456     /**
8457      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8458      * to append various headers to the dropbox log text.
8459      */
8460     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8461             StringBuilder sb) {
8462         // Watchdog thread ends up invoking this function (with
8463         // a null ProcessRecord) to add the stack file to dropbox.
8464         // Do not acquire a lock on this (am) in such cases, as it
8465         // could cause a potential deadlock, if and when watchdog
8466         // is invoked due to unavailability of lock on am and it
8467         // would prevent watchdog from killing system_server.
8468         if (process == null) {
8469             sb.append("Process: ").append(processName).append("\n");
8470             return;
8471         }
8472         // Note: ProcessRecord 'process' is guarded by the service
8473         // instance.  (notably process.pkgList, which could otherwise change
8474         // concurrently during execution of this method)
8475         synchronized (this) {
8476             sb.append("Process: ").append(processName).append("\n");
8477             int flags = process.info.flags;
8478             IPackageManager pm = AppGlobals.getPackageManager();
8479             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8480             for (String pkg : process.pkgList) {
8481                 sb.append("Package: ").append(pkg);
8482                 try {
8483                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8484                     if (pi != null) {
8485                         sb.append(" v").append(pi.versionCode);
8486                         if (pi.versionName != null) {
8487                             sb.append(" (").append(pi.versionName).append(")");
8488                         }
8489                     }
8490                 } catch (RemoteException e) {
8491                     Slog.e(TAG, "Error getting package info: " + pkg, e);
8492                 }
8493                 sb.append("\n");
8494             }
8495         }
8496     }
8497
8498     private static String processClass(ProcessRecord process) {
8499         if (process == null || process.pid == MY_PID) {
8500             return "system_server";
8501         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8502             return "system_app";
8503         } else {
8504             return "data_app";
8505         }
8506     }
8507
8508     /**
8509      * Write a description of an error (crash, WTF, ANR) to the drop box.
8510      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8511      * @param process which caused the error, null means the system server
8512      * @param activity which triggered the error, null if unknown
8513      * @param parent activity related to the error, null if unknown
8514      * @param subject line related to the error, null if absent
8515      * @param report in long form describing the error, null if absent
8516      * @param logFile to include in the report, null if none
8517      * @param crashInfo giving an application stack trace, null if absent
8518      */
8519     public void addErrorToDropBox(String eventType,
8520             ProcessRecord process, String processName, ActivityRecord activity,
8521             ActivityRecord parent, String subject,
8522             final String report, final File logFile,
8523             final ApplicationErrorReport.CrashInfo crashInfo) {
8524         // NOTE -- this must never acquire the ActivityManagerService lock,
8525         // otherwise the watchdog may be prevented from resetting the system.
8526
8527         final String dropboxTag = processClass(process) + "_" + eventType;
8528         final DropBoxManager dbox = (DropBoxManager)
8529                 mContext.getSystemService(Context.DROPBOX_SERVICE);
8530
8531         // Exit early if the dropbox isn't configured to accept this report type.
8532         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8533
8534         final StringBuilder sb = new StringBuilder(1024);
8535         appendDropBoxProcessHeaders(process, processName, sb);
8536         if (activity != null) {
8537             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8538         }
8539         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8540             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8541         }
8542         if (parent != null && parent != activity) {
8543             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8544         }
8545         if (subject != null) {
8546             sb.append("Subject: ").append(subject).append("\n");
8547         }
8548         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8549         if (Debug.isDebuggerConnected()) {
8550             sb.append("Debugger: Connected\n");
8551         }
8552         sb.append("\n");
8553
8554         // Do the rest in a worker thread to avoid blocking the caller on I/O
8555         // (After this point, we shouldn't access AMS internal data structures.)
8556         Thread worker = new Thread("Error dump: " + dropboxTag) {
8557             @Override
8558             public void run() {
8559                 if (report != null) {
8560                     sb.append(report);
8561                 }
8562                 if (logFile != null) {
8563                     try {
8564                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8565                     } catch (IOException e) {
8566                         Slog.e(TAG, "Error reading " + logFile, e);
8567                     }
8568                 }
8569                 if (crashInfo != null && crashInfo.stackTrace != null) {
8570                     sb.append(crashInfo.stackTrace);
8571                 }
8572
8573                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8574                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8575                 if (lines > 0) {
8576                     sb.append("\n");
8577
8578                     // Merge several logcat streams, and take the last N lines
8579                     InputStreamReader input = null;
8580                     try {
8581                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8582                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8583                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8584
8585                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
8586                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
8587                         input = new InputStreamReader(logcat.getInputStream());
8588
8589                         int num;
8590                         char[] buf = new char[8192];
8591                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8592                     } catch (IOException e) {
8593                         Slog.e(TAG, "Error running logcat", e);
8594                     } finally {
8595                         if (input != null) try { input.close(); } catch (IOException e) {}
8596                     }
8597                 }
8598
8599                 dbox.addText(dropboxTag, sb.toString());
8600             }
8601         };
8602
8603         if (process == null) {
8604             // If process is null, we are being called from some internal code
8605             // and may be about to die -- run this synchronously.
8606             worker.run();
8607         } else {
8608             worker.start();
8609         }
8610     }
8611
8612     /**
8613      * Bring up the "unexpected error" dialog box for a crashing app.
8614      * Deal with edge cases (intercepts from instrumented applications,
8615      * ActivityController, error intent receivers, that sort of thing).
8616      * @param r the application crashing
8617      * @param crashInfo describing the failure
8618      */
8619     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8620         long timeMillis = System.currentTimeMillis();
8621         String shortMsg = crashInfo.exceptionClassName;
8622         String longMsg = crashInfo.exceptionMessage;
8623         String stackTrace = crashInfo.stackTrace;
8624         if (shortMsg != null && longMsg != null) {
8625             longMsg = shortMsg + ": " + longMsg;
8626         } else if (shortMsg != null) {
8627             longMsg = shortMsg;
8628         }
8629
8630         AppErrorResult result = new AppErrorResult();
8631         synchronized (this) {
8632             if (mController != null) {
8633                 try {
8634                     String name = r != null ? r.processName : null;
8635                     int pid = r != null ? r.pid : Binder.getCallingPid();
8636                     if (!mController.appCrashed(name, pid,
8637                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8638                         Slog.w(TAG, "Force-killing crashed app " + name
8639                                 + " at watcher's request");
8640                         Process.killProcess(pid);
8641                         return;
8642                     }
8643                 } catch (RemoteException e) {
8644                     mController = null;
8645                 }
8646             }
8647
8648             final long origId = Binder.clearCallingIdentity();
8649
8650             // If this process is running instrumentation, finish it.
8651             if (r != null && r.instrumentationClass != null) {
8652                 Slog.w(TAG, "Error in app " + r.processName
8653                       + " running instrumentation " + r.instrumentationClass + ":");
8654                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8655                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8656                 Bundle info = new Bundle();
8657                 info.putString("shortMsg", shortMsg);
8658                 info.putString("longMsg", longMsg);
8659                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8660                 Binder.restoreCallingIdentity(origId);
8661                 return;
8662             }
8663
8664             // If we can't identify the process or it's already exceeded its crash quota,
8665             // quit right away without showing a crash dialog.
8666             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8667                 Binder.restoreCallingIdentity(origId);
8668                 return;
8669             }
8670
8671             Message msg = Message.obtain();
8672             msg.what = SHOW_ERROR_MSG;
8673             HashMap data = new HashMap();
8674             data.put("result", result);
8675             data.put("app", r);
8676             msg.obj = data;
8677             mHandler.sendMessage(msg);
8678
8679             Binder.restoreCallingIdentity(origId);
8680         }
8681
8682         int res = result.get();
8683
8684         Intent appErrorIntent = null;
8685         synchronized (this) {
8686             if (r != null && !r.isolated) {
8687                 // XXX Can't keep track of crash time for isolated processes,
8688                 // since they don't have a persistent identity.
8689                 mProcessCrashTimes.put(r.info.processName, r.uid,
8690                         SystemClock.uptimeMillis());
8691             }
8692             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8693                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8694             }
8695         }
8696
8697         if (appErrorIntent != null) {
8698             try {
8699                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8700             } catch (ActivityNotFoundException e) {
8701                 Slog.w(TAG, "bug report receiver dissappeared", e);
8702             }
8703         }
8704     }
8705
8706     Intent createAppErrorIntentLocked(ProcessRecord r,
8707             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8708         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8709         if (report == null) {
8710             return null;
8711         }
8712         Intent result = new Intent(Intent.ACTION_APP_ERROR);
8713         result.setComponent(r.errorReportReceiver);
8714         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8715         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8716         return result;
8717     }
8718
8719     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8720             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8721         if (r.errorReportReceiver == null) {
8722             return null;
8723         }
8724
8725         if (!r.crashing && !r.notResponding) {
8726             return null;
8727         }
8728
8729         ApplicationErrorReport report = new ApplicationErrorReport();
8730         report.packageName = r.info.packageName;
8731         report.installerPackageName = r.errorReportReceiver.getPackageName();
8732         report.processName = r.processName;
8733         report.time = timeMillis;
8734         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8735
8736         if (r.crashing) {
8737             report.type = ApplicationErrorReport.TYPE_CRASH;
8738             report.crashInfo = crashInfo;
8739         } else if (r.notResponding) {
8740             report.type = ApplicationErrorReport.TYPE_ANR;
8741             report.anrInfo = new ApplicationErrorReport.AnrInfo();
8742
8743             report.anrInfo.activity = r.notRespondingReport.tag;
8744             report.anrInfo.cause = r.notRespondingReport.shortMsg;
8745             report.anrInfo.info = r.notRespondingReport.longMsg;
8746         }
8747
8748         return report;
8749     }
8750
8751     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8752         enforceNotIsolatedCaller("getProcessesInErrorState");
8753         // assume our apps are happy - lazy create the list
8754         List<ActivityManager.ProcessErrorStateInfo> errList = null;
8755
8756         final boolean allUsers = ActivityManager.checkUidPermission(
8757                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8758                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8759         int userId = UserHandle.getUserId(Binder.getCallingUid());
8760
8761         synchronized (this) {
8762
8763             // iterate across all processes
8764             for (int i=mLruProcesses.size()-1; i>=0; i--) {
8765                 ProcessRecord app = mLruProcesses.get(i);
8766                 if (!allUsers && app.userId != userId) {
8767                     continue;
8768                 }
8769                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8770                     // This one's in trouble, so we'll generate a report for it
8771                     // crashes are higher priority (in case there's a crash *and* an anr)
8772                     ActivityManager.ProcessErrorStateInfo report = null;
8773                     if (app.crashing) {
8774                         report = app.crashingReport;
8775                     } else if (app.notResponding) {
8776                         report = app.notRespondingReport;
8777                     }
8778                     
8779                     if (report != null) {
8780                         if (errList == null) {
8781                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8782                         }
8783                         errList.add(report);
8784                     } else {
8785                         Slog.w(TAG, "Missing app error report, app = " + app.processName + 
8786                                 " crashing = " + app.crashing +
8787                                 " notResponding = " + app.notResponding);
8788                     }
8789                 }
8790             }
8791         }
8792
8793         return errList;
8794     }
8795
8796     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8797         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8798             if (currApp != null) {
8799                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8800             }
8801             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8802         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8803             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8804         } else if (adj >= ProcessList.HOME_APP_ADJ) {
8805             if (currApp != null) {
8806                 currApp.lru = 0;
8807             }
8808             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8809         } else if (adj >= ProcessList.SERVICE_ADJ) {
8810             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8811         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8812             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8813         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8814             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8815         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8816             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8817         } else {
8818             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8819         }
8820     }
8821
8822     private void fillInProcMemInfo(ProcessRecord app,
8823             ActivityManager.RunningAppProcessInfo outInfo) {
8824         outInfo.pid = app.pid;
8825         outInfo.uid = app.info.uid;
8826         if (mHeavyWeightProcess == app) {
8827             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8828         }
8829         if (app.persistent) {
8830             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8831         }
8832         if (app.hasActivities) {
8833             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8834         }
8835         outInfo.lastTrimLevel = app.trimMemoryLevel;
8836         int adj = app.curAdj;
8837         outInfo.importance = oomAdjToImportance(adj, outInfo);
8838         outInfo.importanceReasonCode = app.adjTypeCode;
8839     }
8840
8841     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8842         enforceNotIsolatedCaller("getRunningAppProcesses");
8843         // Lazy instantiation of list
8844         List<ActivityManager.RunningAppProcessInfo> runList = null;
8845         final boolean allUsers = ActivityManager.checkUidPermission(
8846                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8847                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8848         int userId = UserHandle.getUserId(Binder.getCallingUid());
8849         synchronized (this) {
8850             // Iterate across all processes
8851             for (int i=mLruProcesses.size()-1; i>=0; i--) {
8852                 ProcessRecord app = mLruProcesses.get(i);
8853                 if (!allUsers && app.userId != userId) {
8854                     continue;
8855                 }
8856                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8857                     // Generate process state info for running application
8858                     ActivityManager.RunningAppProcessInfo currApp = 
8859                         new ActivityManager.RunningAppProcessInfo(app.processName,
8860                                 app.pid, app.getPackageList());
8861                     fillInProcMemInfo(app, currApp);
8862                     if (app.adjSource instanceof ProcessRecord) {
8863                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8864                         currApp.importanceReasonImportance = oomAdjToImportance(
8865                                 app.adjSourceOom, null);
8866                     } else if (app.adjSource instanceof ActivityRecord) {
8867                         ActivityRecord r = (ActivityRecord)app.adjSource;
8868                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8869                     }
8870                     if (app.adjTarget instanceof ComponentName) {
8871                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8872                     }
8873                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8874                     //        + " lru=" + currApp.lru);
8875                     if (runList == null) {
8876                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8877                     }
8878                     runList.add(currApp);
8879                 }
8880             }
8881         }
8882         return runList;
8883     }
8884
8885     public List<ApplicationInfo> getRunningExternalApplications() {
8886         enforceNotIsolatedCaller("getRunningExternalApplications");
8887         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8888         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8889         if (runningApps != null && runningApps.size() > 0) {
8890             Set<String> extList = new HashSet<String>();
8891             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8892                 if (app.pkgList != null) {
8893                     for (String pkg : app.pkgList) {
8894                         extList.add(pkg);
8895                     }
8896                 }
8897             }
8898             IPackageManager pm = AppGlobals.getPackageManager();
8899             for (String pkg : extList) {
8900                 try {
8901                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8902                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8903                         retList.add(info);
8904                     }
8905                 } catch (RemoteException e) {
8906                 }
8907             }
8908         }
8909         return retList;
8910     }
8911
8912     @Override
8913     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8914         enforceNotIsolatedCaller("getMyMemoryState");
8915         synchronized (this) {
8916             ProcessRecord proc;
8917             synchronized (mPidsSelfLocked) {
8918                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
8919             }
8920             fillInProcMemInfo(proc, outInfo);
8921         }
8922     }
8923
8924     @Override
8925     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8926         if (checkCallingPermission(android.Manifest.permission.DUMP)
8927                 != PackageManager.PERMISSION_GRANTED) {
8928             pw.println("Permission Denial: can't dump ActivityManager from from pid="
8929                     + Binder.getCallingPid()
8930                     + ", uid=" + Binder.getCallingUid()
8931                     + " without permission "
8932                     + android.Manifest.permission.DUMP);
8933             return;
8934         }
8935
8936         boolean dumpAll = false;
8937         boolean dumpClient = false;
8938         String dumpPackage = null;
8939         
8940         int opti = 0;
8941         while (opti < args.length) {
8942             String opt = args[opti];
8943             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8944                 break;
8945             }
8946             opti++;
8947             if ("-a".equals(opt)) {
8948                 dumpAll = true;
8949             } else if ("-c".equals(opt)) {
8950                 dumpClient = true;
8951             } else if ("-h".equals(opt)) {
8952                 pw.println("Activity manager dump options:");
8953                 pw.println("  [-a] [-c] [-h] [cmd] ...");
8954                 pw.println("  cmd may be one of:");
8955                 pw.println("    a[ctivities]: activity stack state");
8956                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
8957                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8958                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8959                 pw.println("    o[om]: out of memory management");
8960                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8961                 pw.println("    provider [COMP_SPEC]: provider client-side state");
8962                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8963                 pw.println("    service [COMP_SPEC]: service client-side state");
8964                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
8965                 pw.println("    all: dump all activities");
8966                 pw.println("    top: dump the top activity");
8967                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8968                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8969                 pw.println("    a partial substring in a component name, a");
8970                 pw.println("    hex object identifier.");
8971                 pw.println("  -a: include all available server state.");
8972                 pw.println("  -c: include client state.");
8973                 return;
8974             } else {
8975                 pw.println("Unknown argument: " + opt + "; use -h for help");
8976             }
8977         }
8978
8979         long origId = Binder.clearCallingIdentity();
8980         boolean more = false;
8981         // Is the caller requesting to dump a particular piece of data?
8982         if (opti < args.length) {
8983             String cmd = args[opti];
8984             opti++;
8985             if ("activities".equals(cmd) || "a".equals(cmd)) {
8986                 synchronized (this) {
8987                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8988                 }
8989             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8990                 String[] newArgs;
8991                 String name;
8992                 if (opti >= args.length) {
8993                     name = null;
8994                     newArgs = EMPTY_STRING_ARRAY;
8995                 } else {
8996                     name = args[opti];
8997                     opti++;
8998                     newArgs = new String[args.length - opti];
8999                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9000                             args.length - opti);
9001                 }
9002                 synchronized (this) {
9003                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
9004                 }
9005             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
9006                 String[] newArgs;
9007                 String name;
9008                 if (opti >= args.length) {
9009                     name = null;
9010                     newArgs = EMPTY_STRING_ARRAY;
9011                 } else {
9012                     name = args[opti];
9013                     opti++;
9014                     newArgs = new String[args.length - opti];
9015                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9016                             args.length - opti);
9017                 }
9018                 synchronized (this) {
9019                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
9020                 }
9021             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
9022                 String[] newArgs;
9023                 String name;
9024                 if (opti >= args.length) {
9025                     name = null;
9026                     newArgs = EMPTY_STRING_ARRAY;
9027                 } else {
9028                     name = args[opti];
9029                     opti++;
9030                     newArgs = new String[args.length - opti];
9031                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9032                             args.length - opti);
9033                 }
9034                 synchronized (this) {
9035                     dumpProcessesLocked(fd, pw, args, opti, true, name);
9036                 }
9037             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
9038                 synchronized (this) {
9039                     dumpOomLocked(fd, pw, args, opti, true);
9040                 }
9041             } else if ("provider".equals(cmd)) {
9042                 String[] newArgs;
9043                 String name;
9044                 if (opti >= args.length) {
9045                     name = null;
9046                     newArgs = EMPTY_STRING_ARRAY;
9047                 } else {
9048                     name = args[opti];
9049                     opti++;
9050                     newArgs = new String[args.length - opti];
9051                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9052                 }
9053                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9054                     pw.println("No providers match: " + name);
9055                     pw.println("Use -h for help.");
9056                 }
9057             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9058                 synchronized (this) {
9059                     dumpProvidersLocked(fd, pw, args, opti, true, null);
9060                 }
9061             } else if ("service".equals(cmd)) {
9062                 String[] newArgs;
9063                 String name;
9064                 if (opti >= args.length) {
9065                     name = null;
9066                     newArgs = EMPTY_STRING_ARRAY;
9067                 } else {
9068                     name = args[opti];
9069                     opti++;
9070                     newArgs = new String[args.length - opti];
9071                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9072                             args.length - opti);
9073                 }
9074                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9075                     pw.println("No services match: " + name);
9076                     pw.println("Use -h for help.");
9077                 }
9078             } else if ("package".equals(cmd)) {
9079                 String[] newArgs;
9080                 if (opti >= args.length) {
9081                     pw.println("package: no package name specified");
9082                     pw.println("Use -h for help.");
9083                 } else {
9084                     dumpPackage = args[opti];
9085                     opti++;
9086                     newArgs = new String[args.length - opti];
9087                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9088                             args.length - opti);
9089                     args = newArgs;
9090                     opti = 0;
9091                     more = true;
9092                 }
9093             } else if ("services".equals(cmd) || "s".equals(cmd)) {
9094                 synchronized (this) {
9095                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9096                 }
9097             } else {
9098                 // Dumping a single activity?
9099                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9100                     pw.println("Bad activity command, or no activities match: " + cmd);
9101                     pw.println("Use -h for help.");
9102                 }
9103             }
9104             if (!more) {
9105                 Binder.restoreCallingIdentity(origId);
9106                 return;
9107             }
9108         }
9109
9110         // No piece of data specified, dump everything.
9111         synchronized (this) {
9112             boolean needSep;
9113             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9114             if (needSep) {
9115                 pw.println(" ");
9116             }
9117             if (dumpAll) {
9118                 pw.println("-------------------------------------------------------------------------------");
9119             }
9120             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9121             if (needSep) {
9122                 pw.println(" ");
9123             }
9124             if (dumpAll) {
9125                 pw.println("-------------------------------------------------------------------------------");
9126             }
9127             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9128             if (needSep) {
9129                 pw.println(" ");
9130             }
9131             if (dumpAll) {
9132                 pw.println("-------------------------------------------------------------------------------");
9133             }
9134             needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9135             if (needSep) {
9136                 pw.println(" ");
9137             }
9138             if (dumpAll) {
9139                 pw.println("-------------------------------------------------------------------------------");
9140             }
9141             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9142             if (needSep) {
9143                 pw.println(" ");
9144             }
9145             if (dumpAll) {
9146                 pw.println("-------------------------------------------------------------------------------");
9147             }
9148             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9149         }
9150         Binder.restoreCallingIdentity(origId);
9151     }
9152
9153     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9154             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9155         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9156         pw.println("  Main stack:");
9157         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9158                 dumpPackage);
9159         pw.println(" ");
9160         pw.println("  Running activities (most recent first):");
9161         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9162                 dumpPackage);
9163         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9164             pw.println(" ");
9165             pw.println("  Activities waiting for another to become visible:");
9166             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9167                     !dumpAll, false, dumpPackage);
9168         }
9169         if (mMainStack.mStoppingActivities.size() > 0) {
9170             pw.println(" ");
9171             pw.println("  Activities waiting to stop:");
9172             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9173                     !dumpAll, false, dumpPackage);
9174         }
9175         if (mMainStack.mGoingToSleepActivities.size() > 0) {
9176             pw.println(" ");
9177             pw.println("  Activities waiting to sleep:");
9178             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9179                     !dumpAll, false, dumpPackage);
9180         }
9181         if (mMainStack.mFinishingActivities.size() > 0) {
9182             pw.println(" ");
9183             pw.println("  Activities waiting to finish:");
9184             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9185                     !dumpAll, false, dumpPackage);
9186         }
9187
9188         pw.println(" ");
9189         if (mMainStack.mPausingActivity != null) {
9190             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9191         }
9192         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9193         pw.println("  mFocusedActivity: " + mFocusedActivity);
9194         if (dumpAll) {
9195             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9196             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9197             pw.println("  mDismissKeyguardOnNextActivity: "
9198                     + mMainStack.mDismissKeyguardOnNextActivity);
9199         }
9200
9201         if (mRecentTasks.size() > 0) {
9202             pw.println();
9203             pw.println("  Recent tasks:");
9204
9205             final int N = mRecentTasks.size();
9206             for (int i=0; i<N; i++) {
9207                 TaskRecord tr = mRecentTasks.get(i);
9208                 if (dumpPackage != null) {
9209                     if (tr.realActivity == null ||
9210                             !dumpPackage.equals(tr.realActivity)) {
9211                         continue;
9212                     }
9213                 }
9214                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9215                         pw.println(tr);
9216                 if (dumpAll) {
9217                     mRecentTasks.get(i).dump(pw, "    ");
9218                 }
9219             }
9220         }
9221         
9222         if (dumpAll) {
9223             pw.println(" ");
9224             pw.println("  mCurTask: " + mCurTask);
9225         }
9226         
9227         return true;
9228     }
9229
9230     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9231             int opti, boolean dumpAll, String dumpPackage) {
9232         boolean needSep = false;
9233         int numPers = 0;
9234
9235         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9236
9237         if (dumpAll) {
9238             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9239                 final int NA = procs.size();
9240                 for (int ia=0; ia<NA; ia++) {
9241                     ProcessRecord r = procs.valueAt(ia);
9242                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9243                         continue;
9244                     }
9245                     if (!needSep) {
9246                         pw.println("  All known processes:");
9247                         needSep = true;
9248                     }
9249                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9250                         pw.print(" UID "); pw.print(procs.keyAt(ia));
9251                         pw.print(" "); pw.println(r);
9252                     r.dump(pw, "    ");
9253                     if (r.persistent) {
9254                         numPers++;
9255                     }
9256                 }
9257             }
9258         }
9259
9260         if (mIsolatedProcesses.size() > 0) {
9261             if (needSep) pw.println(" ");
9262             needSep = true;
9263             pw.println("  Isolated process list (sorted by uid):");
9264             for (int i=0; i<mIsolatedProcesses.size(); i++) {
9265                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9266                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9267                     continue;
9268                 }
9269                 pw.println(String.format("%sIsolated #%2d: %s",
9270                         "    ", i, r.toString()));
9271             }
9272         }
9273
9274         if (mLruProcesses.size() > 0) {
9275             if (needSep) pw.println(" ");
9276             needSep = true;
9277             pw.println("  Process LRU list (sorted by oom_adj):");
9278             dumpProcessOomList(pw, this, mLruProcesses, "    ",
9279                     "Proc", "PERS", false, dumpPackage);
9280             needSep = true;
9281         }
9282
9283         if (dumpAll) {
9284             synchronized (mPidsSelfLocked) {
9285                 boolean printed = false;
9286                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9287                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
9288                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9289                         continue;
9290                     }
9291                     if (!printed) {
9292                         if (needSep) pw.println(" ");
9293                         needSep = true;
9294                         pw.println("  PID mappings:");
9295                         printed = true;
9296                     }
9297                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9298                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9299                 }
9300             }
9301         }
9302         
9303         if (mForegroundProcesses.size() > 0) {
9304             synchronized (mPidsSelfLocked) {
9305                 boolean printed = false;
9306                 for (int i=0; i<mForegroundProcesses.size(); i++) {
9307                     ProcessRecord r = mPidsSelfLocked.get( 
9308                             mForegroundProcesses.valueAt(i).pid);
9309                     if (dumpPackage != null && (r == null
9310                             || !dumpPackage.equals(r.info.packageName))) {
9311                         continue;
9312                     }
9313                     if (!printed) {
9314                         if (needSep) pw.println(" ");
9315                         needSep = true;
9316                         pw.println("  Foreground Processes:");
9317                         printed = true;
9318                     }
9319                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9320                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9321                 }
9322             }
9323         }
9324         
9325         if (mPersistentStartingProcesses.size() > 0) {
9326             if (needSep) pw.println(" ");
9327             needSep = true;
9328             pw.println("  Persisent processes that are starting:");
9329             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9330                     "Starting Norm", "Restarting PERS", dumpPackage);
9331         }
9332
9333         if (mRemovedProcesses.size() > 0) {
9334             if (needSep) pw.println(" ");
9335             needSep = true;
9336             pw.println("  Processes that are being removed:");
9337             dumpProcessList(pw, this, mRemovedProcesses, "    ",
9338                     "Removed Norm", "Removed PERS", dumpPackage);
9339         }
9340         
9341         if (mProcessesOnHold.size() > 0) {
9342             if (needSep) pw.println(" ");
9343             needSep = true;
9344             pw.println("  Processes that are on old until the system is ready:");
9345             dumpProcessList(pw, this, mProcessesOnHold, "    ",
9346                     "OnHold Norm", "OnHold PERS", dumpPackage);
9347         }
9348
9349         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9350         
9351         if (mProcessCrashTimes.getMap().size() > 0) {
9352             boolean printed = false;
9353             long now = SystemClock.uptimeMillis();
9354             for (Map.Entry<String, SparseArray<Long>> procs
9355                     : mProcessCrashTimes.getMap().entrySet()) {
9356                 String pname = procs.getKey();
9357                 SparseArray<Long> uids = procs.getValue();
9358                 final int N = uids.size();
9359                 for (int i=0; i<N; i++) {
9360                     int puid = uids.keyAt(i);
9361                     ProcessRecord r = mProcessNames.get(pname, puid);
9362                     if (dumpPackage != null && (r == null
9363                             || !dumpPackage.equals(r.info.packageName))) {
9364                         continue;
9365                     }
9366                     if (!printed) {
9367                         if (needSep) pw.println(" ");
9368                         needSep = true;
9369                         pw.println("  Time since processes crashed:");
9370                         printed = true;
9371                     }
9372                     pw.print("    Process "); pw.print(pname);
9373                             pw.print(" uid "); pw.print(puid);
9374                             pw.print(": last crashed ");
9375                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9376                             pw.println(" ago");
9377                 }
9378             }
9379         }
9380
9381         if (mBadProcesses.getMap().size() > 0) {
9382             boolean printed = false;
9383             for (Map.Entry<String, SparseArray<Long>> procs
9384                     : mBadProcesses.getMap().entrySet()) {
9385                 String pname = procs.getKey();
9386                 SparseArray<Long> uids = procs.getValue();
9387                 final int N = uids.size();
9388                 for (int i=0; i<N; i++) {
9389                     int puid = uids.keyAt(i);
9390                     ProcessRecord r = mProcessNames.get(pname, puid);
9391                     if (dumpPackage != null && (r == null
9392                             || !dumpPackage.equals(r.info.packageName))) {
9393                         continue;
9394                     }
9395                     if (!printed) {
9396                         if (needSep) pw.println(" ");
9397                         needSep = true;
9398                         pw.println("  Bad processes:");
9399                     }
9400                     pw.print("    Bad process "); pw.print(pname);
9401                             pw.print(" uid "); pw.print(puid);
9402                             pw.print(": crashed at time ");
9403                             pw.println(uids.valueAt(i));
9404                 }
9405             }
9406         }
9407
9408         pw.println();
9409         pw.println("  mStartedUsers:");
9410         for (int i=0; i<mStartedUsers.size(); i++) {
9411             UserStartedState uss = mStartedUsers.valueAt(i);
9412             pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9413                     pw.print(": "); uss.dump("", pw);
9414         }
9415         pw.print("  mStartedUserArray: [");
9416         for (int i=0; i<mStartedUserArray.length; i++) {
9417             if (i > 0) pw.print(", ");
9418             pw.print(mStartedUserArray[i]);
9419         }
9420         pw.println("]");
9421         pw.print("  mUserLru: [");
9422         for (int i=0; i<mUserLru.size(); i++) {
9423             if (i > 0) pw.print(", ");
9424             pw.print(mUserLru.get(i));
9425         }
9426         pw.println("]");
9427         if (dumpAll) {
9428             pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9429         }
9430         pw.println("  mHomeProcess: " + mHomeProcess);
9431         pw.println("  mPreviousProcess: " + mPreviousProcess);
9432         if (dumpAll) {
9433             StringBuilder sb = new StringBuilder(128);
9434             sb.append("  mPreviousProcessVisibleTime: ");
9435             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9436             pw.println(sb);
9437         }
9438         if (mHeavyWeightProcess != null) {
9439             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9440         }
9441         pw.println("  mConfiguration: " + mConfiguration);
9442         if (dumpAll) {
9443             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9444             if (mCompatModePackages.getPackages().size() > 0) {
9445                 boolean printed = false;
9446                 for (Map.Entry<String, Integer> entry
9447                         : mCompatModePackages.getPackages().entrySet()) {
9448                     String pkg = entry.getKey();
9449                     int mode = entry.getValue();
9450                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9451                         continue;
9452                     }
9453                     if (!printed) {
9454                         pw.println("  mScreenCompatPackages:");
9455                         printed = true;
9456                     }
9457                     pw.print("    "); pw.print(pkg); pw.print(": ");
9458                             pw.print(mode); pw.println();
9459                 }
9460             }
9461         }
9462         if (mSleeping || mWentToSleep || mLockScreenShown) {
9463             pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9464                     + " mLockScreenShown " + mLockScreenShown);
9465         }
9466         if (mShuttingDown) {
9467             pw.println("  mShuttingDown=" + mShuttingDown);
9468         }
9469         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9470                 || mOrigWaitForDebugger) {
9471             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9472                     + " mDebugTransient=" + mDebugTransient
9473                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9474         }
9475         if (mOpenGlTraceApp != null) {
9476             pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9477         }
9478         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9479                 || mProfileFd != null) {
9480             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9481             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9482             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9483                     + mAutoStopProfiler);
9484         }
9485         if (mAlwaysFinishActivities || mController != null) {
9486             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9487                     + " mController=" + mController);
9488         }
9489         if (dumpAll) {
9490             pw.println("  Total persistent processes: " + numPers);
9491             pw.println("  mStartRunning=" + mStartRunning
9492                     + " mProcessesReady=" + mProcessesReady
9493                     + " mSystemReady=" + mSystemReady);
9494             pw.println("  mBooting=" + mBooting
9495                     + " mBooted=" + mBooted
9496                     + " mFactoryTest=" + mFactoryTest);
9497             pw.print("  mLastPowerCheckRealtime=");
9498                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9499                     pw.println("");
9500             pw.print("  mLastPowerCheckUptime=");
9501                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9502                     pw.println("");
9503             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9504             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9505             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9506             pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9507                     + " mNumHiddenProcs=" + mNumHiddenProcs
9508                     + " mNumServiceProcs=" + mNumServiceProcs
9509                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9510         }
9511         
9512         return true;
9513     }
9514
9515     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9516             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9517         if (mProcessesToGc.size() > 0) {
9518             boolean printed = false;
9519             long now = SystemClock.uptimeMillis();
9520             for (int i=0; i<mProcessesToGc.size(); i++) {
9521                 ProcessRecord proc = mProcessesToGc.get(i);
9522                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9523                     continue;
9524                 }
9525                 if (!printed) {
9526                     if (needSep) pw.println(" ");
9527                     needSep = true;
9528                     pw.println("  Processes that are waiting to GC:");
9529                     printed = true;
9530                 }
9531                 pw.print("    Process "); pw.println(proc);
9532                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9533                         pw.print(", last gced=");
9534                         pw.print(now-proc.lastRequestedGc);
9535                         pw.print(" ms ago, last lowMem=");
9536                         pw.print(now-proc.lastLowMemory);
9537                         pw.println(" ms ago");
9538
9539             }
9540         }
9541         return needSep;
9542     }
9543
9544     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9545             int opti, boolean dumpAll) {
9546         boolean needSep = false;
9547
9548         if (mLruProcesses.size() > 0) {
9549             if (needSep) pw.println(" ");
9550             needSep = true;
9551             pw.println("  OOM levels:");
9552             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9553             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9554             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9555             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9556             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9557             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9558             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9559             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9560             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9561             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9562             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9563             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9564             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9565
9566             if (needSep) pw.println(" ");
9567             needSep = true;
9568             pw.println("  Process OOM control:");
9569             dumpProcessOomList(pw, this, mLruProcesses, "    ",
9570                     "Proc", "PERS", true, null);
9571             needSep = true;
9572         }
9573
9574         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9575
9576         pw.println();
9577         pw.println("  mHomeProcess: " + mHomeProcess);
9578         pw.println("  mPreviousProcess: " + mPreviousProcess);
9579         if (mHeavyWeightProcess != null) {
9580             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9581         }
9582
9583         return true;
9584     }
9585
9586     /**
9587      * There are three ways to call this:
9588      *  - no provider specified: dump all the providers
9589      *  - a flattened component name that matched an existing provider was specified as the
9590      *    first arg: dump that one provider
9591      *  - the first arg isn't the flattened component name of an existing provider:
9592      *    dump all providers whose component contains the first arg as a substring
9593      */
9594     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9595             int opti, boolean dumpAll) {
9596         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9597     }
9598
9599     static class ItemMatcher {
9600         ArrayList<ComponentName> components;
9601         ArrayList<String> strings;
9602         ArrayList<Integer> objects;
9603         boolean all;
9604         
9605         ItemMatcher() {
9606             all = true;
9607         }
9608
9609         void build(String name) {
9610             ComponentName componentName = ComponentName.unflattenFromString(name);
9611             if (componentName != null) {
9612                 if (components == null) {
9613                     components = new ArrayList<ComponentName>();
9614                 }
9615                 components.add(componentName);
9616                 all = false;
9617             } else {
9618                 int objectId = 0;
9619                 // Not a '/' separated full component name; maybe an object ID?
9620                 try {
9621                     objectId = Integer.parseInt(name, 16);
9622                     if (objects == null) {
9623                         objects = new ArrayList<Integer>();
9624                     }
9625                     objects.add(objectId);
9626                     all = false;
9627                 } catch (RuntimeException e) {
9628                     // Not an integer; just do string match.
9629                     if (strings == null) {
9630                         strings = new ArrayList<String>();
9631                     }
9632                     strings.add(name);
9633                     all = false;
9634                 }
9635             }
9636         }
9637
9638         int build(String[] args, int opti) {
9639             for (; opti<args.length; opti++) {
9640                 String name = args[opti];
9641                 if ("--".equals(name)) {
9642                     return opti+1;
9643                 }
9644                 build(name);
9645             }
9646             return opti;
9647         }
9648
9649         boolean match(Object object, ComponentName comp) {
9650             if (all) {
9651                 return true;
9652             }
9653             if (components != null) {
9654                 for (int i=0; i<components.size(); i++) {
9655                     if (components.get(i).equals(comp)) {
9656                         return true;
9657                     }
9658                 }
9659             }
9660             if (objects != null) {
9661                 for (int i=0; i<objects.size(); i++) {
9662                     if (System.identityHashCode(object) == objects.get(i)) {
9663                         return true;
9664                     }
9665                 }
9666             }
9667             if (strings != null) {
9668                 String flat = comp.flattenToString();
9669                 for (int i=0; i<strings.size(); i++) {
9670                     if (flat.contains(strings.get(i))) {
9671                         return true;
9672                     }
9673                 }
9674             }
9675             return false;
9676         }
9677     }
9678
9679     /**
9680      * There are three things that cmd can be:
9681      *  - a flattened component name that matches an existing activity
9682      *  - the cmd arg isn't the flattened component name of an existing activity:
9683      *    dump all activity whose component contains the cmd as a substring
9684      *  - A hex number of the ActivityRecord object instance.
9685      */
9686     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9687             int opti, boolean dumpAll) {
9688         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9689
9690         if ("all".equals(name)) {
9691             synchronized (this) {
9692                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9693                     activities.add(r1);
9694                 }
9695             }
9696         } else if ("top".equals(name)) {
9697             synchronized (this) {
9698                 final int N = mMainStack.mHistory.size();
9699                 if (N > 0) {
9700                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9701                 }
9702             }
9703         } else {
9704             ItemMatcher matcher = new ItemMatcher();
9705             matcher.build(name);
9706
9707             synchronized (this) {
9708                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9709                     if (matcher.match(r1, r1.intent.getComponent())) {
9710                         activities.add(r1);
9711                     }
9712                 }
9713             }
9714         }
9715
9716         if (activities.size() <= 0) {
9717             return false;
9718         }
9719
9720         String[] newArgs = new String[args.length - opti];
9721         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9722
9723         TaskRecord lastTask = null;
9724         boolean needSep = false;
9725         for (int i=activities.size()-1; i>=0; i--) {
9726             ActivityRecord r = (ActivityRecord)activities.get(i);
9727             if (needSep) {
9728                 pw.println();
9729             }
9730             needSep = true;
9731             synchronized (this) {
9732                 if (lastTask != r.task) {
9733                     lastTask = r.task;
9734                     pw.print("TASK "); pw.print(lastTask.affinity);
9735                             pw.print(" id="); pw.println(lastTask.taskId);
9736                     if (dumpAll) {
9737                         lastTask.dump(pw, "  ");
9738                     }
9739                 }
9740             }
9741             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9742         }
9743         return true;
9744     }
9745
9746     /**
9747      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9748      * there is a thread associated with the activity.
9749      */
9750     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9751             final ActivityRecord r, String[] args, boolean dumpAll) {
9752         String innerPrefix = prefix + "  ";
9753         synchronized (this) {
9754             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9755                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9756                     pw.print(" pid=");
9757                     if (r.app != null) pw.println(r.app.pid);
9758                     else pw.println("(not running)");
9759             if (dumpAll) {
9760                 r.dump(pw, innerPrefix);
9761             }
9762         }
9763         if (r.app != null && r.app.thread != null) {
9764             // flush anything that is already in the PrintWriter since the thread is going
9765             // to write to the file descriptor directly
9766             pw.flush();
9767             try {
9768                 TransferPipe tp = new TransferPipe();
9769                 try {
9770                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9771                             r.appToken, innerPrefix, args);
9772                     tp.go(fd);
9773                 } finally {
9774                     tp.kill();
9775                 }
9776             } catch (IOException e) {
9777                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9778             } catch (RemoteException e) {
9779                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9780             }
9781         }
9782     }
9783
9784     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9785             int opti, boolean dumpAll, String dumpPackage) {
9786         boolean needSep = false;
9787         boolean onlyHistory = false;
9788
9789         if ("history".equals(dumpPackage)) {
9790             if (opti < args.length && "-s".equals(args[opti])) {
9791                 dumpAll = false;
9792             }
9793             onlyHistory = true;
9794             dumpPackage = null;
9795         }
9796
9797         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9798         if (!onlyHistory && dumpAll) {
9799             if (mRegisteredReceivers.size() > 0) {
9800                 boolean printed = false;
9801                 Iterator it = mRegisteredReceivers.values().iterator();
9802                 while (it.hasNext()) {
9803                     ReceiverList r = (ReceiverList)it.next();
9804                     if (dumpPackage != null && (r.app == null ||
9805                             !dumpPackage.equals(r.app.info.packageName))) {
9806                         continue;
9807                     }
9808                     if (!printed) {
9809                         pw.println("  Registered Receivers:");
9810                         needSep = true;
9811                         printed = true;
9812                     }
9813                     pw.print("  * "); pw.println(r);
9814                     r.dump(pw, "    ");
9815                 }
9816             }
9817
9818             if (mReceiverResolver.dump(pw, needSep ?
9819                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9820                     "    ", dumpPackage, false)) {
9821                 needSep = true;
9822             }
9823         }
9824
9825         for (BroadcastQueue q : mBroadcastQueues) {
9826             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9827         }
9828
9829         needSep = true;
9830         
9831         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9832             for (int user=0; user<mStickyBroadcasts.size(); user++) {
9833                 if (needSep) {
9834                     pw.println();
9835                 }
9836                 needSep = true;
9837                 pw.print("  Sticky broadcasts for user ");
9838                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9839                 StringBuilder sb = new StringBuilder(128);
9840                 for (Map.Entry<String, ArrayList<Intent>> ent
9841                         : mStickyBroadcasts.valueAt(user).entrySet()) {
9842                     pw.print("  * Sticky action "); pw.print(ent.getKey());
9843                     if (dumpAll) {
9844                         pw.println(":");
9845                         ArrayList<Intent> intents = ent.getValue();
9846                         final int N = intents.size();
9847                         for (int i=0; i<N; i++) {
9848                             sb.setLength(0);
9849                             sb.append("    Intent: ");
9850                             intents.get(i).toShortString(sb, false, true, false, false);
9851                             pw.println(sb.toString());
9852                             Bundle bundle = intents.get(i).getExtras();
9853                             if (bundle != null) {
9854                                 pw.print("      ");
9855                                 pw.println(bundle.toString());
9856                             }
9857                         }
9858                     } else {
9859                         pw.println("");
9860                     }
9861                 }
9862             }
9863         }
9864         
9865         if (!onlyHistory && dumpAll) {
9866             pw.println();
9867             for (BroadcastQueue queue : mBroadcastQueues) {
9868                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9869                         + queue.mBroadcastsScheduled);
9870             }
9871             pw.println("  mHandler:");
9872             mHandler.dump(new PrintWriterPrinter(pw), "    ");
9873             needSep = true;
9874         }
9875         
9876         return needSep;
9877     }
9878
9879     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9880             int opti, boolean dumpAll, String dumpPackage) {
9881         boolean needSep = true;
9882
9883         ItemMatcher matcher = new ItemMatcher();
9884         matcher.build(args, opti);
9885
9886         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9887
9888         mProviderMap.dumpProvidersLocked(pw, dumpAll);
9889
9890         if (mLaunchingProviders.size() > 0) {
9891             boolean printed = false;
9892             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9893                 ContentProviderRecord r = mLaunchingProviders.get(i);
9894                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9895                     continue;
9896                 }
9897                 if (!printed) {
9898                     if (needSep) pw.println(" ");
9899                     needSep = true;
9900                     pw.println("  Launching content providers:");
9901                     printed = true;
9902                 }
9903                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
9904                         pw.println(r);
9905             }
9906         }
9907
9908         if (mGrantedUriPermissions.size() > 0) {
9909             if (needSep) pw.println();
9910             needSep = true;
9911             pw.println("Granted Uri Permissions:");
9912             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9913                 int uid = mGrantedUriPermissions.keyAt(i);
9914                 HashMap<Uri, UriPermission> perms
9915                         = mGrantedUriPermissions.valueAt(i);
9916                 pw.print("  * UID "); pw.print(uid);
9917                         pw.println(" holds:");
9918                 for (UriPermission perm : perms.values()) {
9919                     pw.print("    "); pw.println(perm);
9920                     if (dumpAll) {
9921                         perm.dump(pw, "      ");
9922                     }
9923                 }
9924             }
9925             needSep = true;
9926         }
9927         
9928         return needSep;
9929     }
9930
9931     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9932             int opti, boolean dumpAll, String dumpPackage) {
9933         boolean needSep = false;
9934         
9935         if (mIntentSenderRecords.size() > 0) {
9936             boolean printed = false;
9937             Iterator<WeakReference<PendingIntentRecord>> it
9938                     = mIntentSenderRecords.values().iterator();
9939             while (it.hasNext()) {
9940                 WeakReference<PendingIntentRecord> ref = it.next();
9941                 PendingIntentRecord rec = ref != null ? ref.get(): null;
9942                 if (dumpPackage != null && (rec == null
9943                         || !dumpPackage.equals(rec.key.packageName))) {
9944                     continue;
9945                 }
9946                 if (!printed) {
9947                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9948                     printed = true;
9949                 }
9950                 needSep = true;
9951                 if (rec != null) {
9952                     pw.print("  * "); pw.println(rec);
9953                     if (dumpAll) {
9954                         rec.dump(pw, "    ");
9955                     }
9956                 } else {
9957                     pw.print("  * "); pw.println(ref);
9958                 }
9959             }
9960         }
9961         
9962         return needSep;
9963     }
9964
9965     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9966             String prefix, String label, boolean complete, boolean brief, boolean client,
9967             String dumpPackage) {
9968         TaskRecord lastTask = null;
9969         boolean needNL = false;
9970         final String innerPrefix = prefix + "      ";
9971         final String[] args = new String[0];
9972         for (int i=list.size()-1; i>=0; i--) {
9973             final ActivityRecord r = (ActivityRecord)list.get(i);
9974             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9975                 continue;
9976             }
9977             final boolean full = !brief && (complete || !r.isInHistory());
9978             if (needNL) {
9979                 pw.println(" ");
9980                 needNL = false;
9981             }
9982             if (lastTask != r.task) {
9983                 lastTask = r.task;
9984                 pw.print(prefix);
9985                 pw.print(full ? "* " : "  ");
9986                 pw.println(lastTask);
9987                 if (full) {
9988                     lastTask.dump(pw, prefix + "  ");
9989                 } else if (complete) {
9990                     // Complete + brief == give a summary.  Isn't that obvious?!?
9991                     if (lastTask.intent != null) {
9992                         pw.print(prefix); pw.print("  ");
9993                                 pw.println(lastTask.intent.toInsecureStringWithClip());
9994                     }
9995                 }
9996             }
9997             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9998             pw.print(" #"); pw.print(i); pw.print(": ");
9999             pw.println(r);
10000             if (full) {
10001                 r.dump(pw, innerPrefix);
10002             } else if (complete) {
10003                 // Complete + brief == give a summary.  Isn't that obvious?!?
10004                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
10005                 if (r.app != null) {
10006                     pw.print(innerPrefix); pw.println(r.app);
10007                 }
10008             }
10009             if (client && r.app != null && r.app.thread != null) {
10010                 // flush anything that is already in the PrintWriter since the thread is going
10011                 // to write to the file descriptor directly
10012                 pw.flush();
10013                 try {
10014                     TransferPipe tp = new TransferPipe();
10015                     try {
10016                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10017                                 r.appToken, innerPrefix, args);
10018                         // Short timeout, since blocking here can
10019                         // deadlock with the application.
10020                         tp.go(fd, 2000);
10021                     } finally {
10022                         tp.kill();
10023                     }
10024                 } catch (IOException e) {
10025                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10026                 } catch (RemoteException e) {
10027                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10028                 }
10029                 needNL = true;
10030             }
10031         }
10032     }
10033
10034     private static String buildOomTag(String prefix, String space, int val, int base) {
10035         if (val == base) {
10036             if (space == null) return prefix;
10037             return prefix + "  ";
10038         }
10039         return prefix + "+" + Integer.toString(val-base);
10040     }
10041     
10042     private static final int dumpProcessList(PrintWriter pw,
10043             ActivityManagerService service, List list,
10044             String prefix, String normalLabel, String persistentLabel,
10045             String dumpPackage) {
10046         int numPers = 0;
10047         final int N = list.size()-1;
10048         for (int i=N; i>=0; i--) {
10049             ProcessRecord r = (ProcessRecord)list.get(i);
10050             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10051                 continue;
10052             }
10053             pw.println(String.format("%s%s #%2d: %s",
10054                     prefix, (r.persistent ? persistentLabel : normalLabel),
10055                     i, r.toString()));
10056             if (r.persistent) {
10057                 numPers++;
10058             }
10059         }
10060         return numPers;
10061     }
10062
10063     private static final boolean dumpProcessOomList(PrintWriter pw,
10064             ActivityManagerService service, List<ProcessRecord> origList,
10065             String prefix, String normalLabel, String persistentLabel,
10066             boolean inclDetails, String dumpPackage) {
10067
10068         ArrayList<Pair<ProcessRecord, Integer>> list
10069                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10070         for (int i=0; i<origList.size(); i++) {
10071             ProcessRecord r = origList.get(i);
10072             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10073                 continue;
10074             }
10075             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10076         }
10077
10078         if (list.size() <= 0) {
10079             return false;
10080         }
10081  
10082         Comparator<Pair<ProcessRecord, Integer>> comparator
10083                 = new Comparator<Pair<ProcessRecord, Integer>>() {
10084             @Override
10085             public int compare(Pair<ProcessRecord, Integer> object1,
10086                     Pair<ProcessRecord, Integer> object2) {
10087                 if (object1.first.setAdj != object2.first.setAdj) {
10088                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10089                 }
10090                 if (object1.second.intValue() != object2.second.intValue()) {
10091                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10092                 }
10093                 return 0;
10094             }
10095         };
10096
10097         Collections.sort(list, comparator);
10098
10099         final long curRealtime = SystemClock.elapsedRealtime();
10100         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10101         final long curUptime = SystemClock.uptimeMillis();
10102         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10103
10104         for (int i=list.size()-1; i>=0; i--) {
10105             ProcessRecord r = list.get(i).first;
10106             String oomAdj;
10107             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10108                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10109             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10110                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10111             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10112                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10113             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10114                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10115             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10116                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10117             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10118                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10119             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10120                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10121             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10122                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10123             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10124                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10125             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10126                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10127             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10128                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10129             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10130                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10131             } else {
10132                 oomAdj = Integer.toString(r.setAdj);
10133             }
10134             String schedGroup;
10135             switch (r.setSchedGroup) {
10136                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10137                     schedGroup = "B";
10138                     break;
10139                 case Process.THREAD_GROUP_DEFAULT:
10140                     schedGroup = "F";
10141                     break;
10142                 default:
10143                     schedGroup = Integer.toString(r.setSchedGroup);
10144                     break;
10145             }
10146             String foreground;
10147             if (r.foregroundActivities) {
10148                 foreground = "A";
10149             } else if (r.foregroundServices) {
10150                 foreground = "S";
10151             } else {
10152                 foreground = " ";
10153             }
10154             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10155                     prefix, (r.persistent ? persistentLabel : normalLabel),
10156                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10157                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10158             if (r.adjSource != null || r.adjTarget != null) {
10159                 pw.print(prefix);
10160                 pw.print("    ");
10161                 if (r.adjTarget instanceof ComponentName) {
10162                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10163                 } else if (r.adjTarget != null) {
10164                     pw.print(r.adjTarget.toString());
10165                 } else {
10166                     pw.print("{null}");
10167                 }
10168                 pw.print("<=");
10169                 if (r.adjSource instanceof ProcessRecord) {
10170                     pw.print("Proc{");
10171                     pw.print(((ProcessRecord)r.adjSource).toShortString());
10172                     pw.println("}");
10173                 } else if (r.adjSource != null) {
10174                     pw.println(r.adjSource.toString());
10175                 } else {
10176                     pw.println("{null}");
10177                 }
10178             }
10179             if (inclDetails) {
10180                 pw.print(prefix);
10181                 pw.print("    ");
10182                 pw.print("oom: max="); pw.print(r.maxAdj);
10183                 pw.print(" hidden="); pw.print(r.hiddenAdj);
10184                 pw.print(" client="); pw.print(r.clientHiddenAdj);
10185                 pw.print(" empty="); pw.print(r.emptyAdj);
10186                 pw.print(" curRaw="); pw.print(r.curRawAdj);
10187                 pw.print(" setRaw="); pw.print(r.setRawAdj);
10188                 pw.print(" cur="); pw.print(r.curAdj);
10189                 pw.print(" set="); pw.println(r.setAdj);
10190                 pw.print(prefix);
10191                 pw.print("    ");
10192                 pw.print("keeping="); pw.print(r.keeping);
10193                 pw.print(" hidden="); pw.print(r.hidden);
10194                 pw.print(" empty="); pw.print(r.empty);
10195                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10196
10197                 if (!r.keeping) {
10198                     if (r.lastWakeTime != 0) {
10199                         long wtime;
10200                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10201                         synchronized (stats) {
10202                             wtime = stats.getProcessWakeTime(r.info.uid,
10203                                     r.pid, curRealtime);
10204                         }
10205                         long timeUsed = wtime - r.lastWakeTime;
10206                         pw.print(prefix);
10207                         pw.print("    ");
10208                         pw.print("keep awake over ");
10209                         TimeUtils.formatDuration(realtimeSince, pw);
10210                         pw.print(" used ");
10211                         TimeUtils.formatDuration(timeUsed, pw);
10212                         pw.print(" (");
10213                         pw.print((timeUsed*100)/realtimeSince);
10214                         pw.println("%)");
10215                     }
10216                     if (r.lastCpuTime != 0) {
10217                         long timeUsed = r.curCpuTime - r.lastCpuTime;
10218                         pw.print(prefix);
10219                         pw.print("    ");
10220                         pw.print("run cpu over ");
10221                         TimeUtils.formatDuration(uptimeSince, pw);
10222                         pw.print(" used ");
10223                         TimeUtils.formatDuration(timeUsed, pw);
10224                         pw.print(" (");
10225                         pw.print((timeUsed*100)/uptimeSince);
10226                         pw.println("%)");
10227                     }
10228                 }
10229             }
10230         }
10231         return true;
10232     }
10233
10234     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10235         ArrayList<ProcessRecord> procs;
10236         synchronized (this) {
10237             if (args != null && args.length > start
10238                     && args[start].charAt(0) != '-') {
10239                 procs = new ArrayList<ProcessRecord>();
10240                 int pid = -1;
10241                 try {
10242                     pid = Integer.parseInt(args[start]);
10243                 } catch (NumberFormatException e) {
10244
10245                 }
10246                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10247                     ProcessRecord proc = mLruProcesses.get(i);
10248                     if (proc.pid == pid) {
10249                         procs.add(proc);
10250                     } else if (proc.processName.equals(args[start])) {
10251                         procs.add(proc);
10252                     }
10253                 }
10254                 if (procs.size() <= 0) {
10255                     pw.println("No process found for: " + args[start]);
10256                     return null;
10257                 }
10258             } else {
10259                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10260             }
10261         }
10262         return procs;
10263     }
10264
10265     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10266             PrintWriter pw, String[] args) {
10267         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10268         if (procs == null) {
10269             return;
10270         }
10271
10272         long uptime = SystemClock.uptimeMillis();
10273         long realtime = SystemClock.elapsedRealtime();
10274         pw.println("Applications Graphics Acceleration Info:");
10275         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10276         
10277         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10278             ProcessRecord r = procs.get(i);
10279             if (r.thread != null) {
10280                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10281                 pw.flush();
10282                 try {
10283                     TransferPipe tp = new TransferPipe();
10284                     try {
10285                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10286                         tp.go(fd);
10287                     } finally {
10288                         tp.kill();
10289                     }
10290                 } catch (IOException e) {
10291                     pw.println("Failure while dumping the app: " + r);
10292                     pw.flush();
10293                 } catch (RemoteException e) {
10294                     pw.println("Got a RemoteException while dumping the app " + r);
10295                     pw.flush();
10296                 }
10297             }
10298         }
10299     }
10300
10301     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10302         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10303         if (procs == null) {
10304             return;
10305         }
10306
10307         pw.println("Applications Database Info:");
10308
10309         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10310             ProcessRecord r = procs.get(i);
10311             if (r.thread != null) {
10312                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10313                 pw.flush();
10314                 try {
10315                     TransferPipe tp = new TransferPipe();
10316                     try {
10317                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10318                         tp.go(fd);
10319                     } finally {
10320                         tp.kill();
10321                     }
10322                 } catch (IOException e) {
10323                     pw.println("Failure while dumping the app: " + r);
10324                     pw.flush();
10325                 } catch (RemoteException e) {
10326                     pw.println("Got a RemoteException while dumping the app " + r);
10327                     pw.flush();
10328                 }
10329             }
10330         }
10331     }
10332
10333     final static class MemItem {
10334         final String label;
10335         final String shortLabel;
10336         final long pss;
10337         final int id;
10338         ArrayList<MemItem> subitems;
10339
10340         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10341             label = _label;
10342             shortLabel = _shortLabel;
10343             pss = _pss;
10344             id = _id;
10345         }
10346     }
10347
10348     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10349             boolean sort) {
10350         if (sort) {
10351             Collections.sort(items, new Comparator<MemItem>() {
10352                 @Override
10353                 public int compare(MemItem lhs, MemItem rhs) {
10354                     if (lhs.pss < rhs.pss) {
10355                         return 1;
10356                     } else if (lhs.pss > rhs.pss) {
10357                         return -1;
10358                     }
10359                     return 0;
10360                 }
10361             });
10362         }
10363
10364         for (int i=0; i<items.size(); i++) {
10365             MemItem mi = items.get(i);
10366             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10367             if (mi.subitems != null) {
10368                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10369             }
10370         }
10371     }
10372
10373     // These are in KB.
10374     static final long[] DUMP_MEM_BUCKETS = new long[] {
10375         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10376         120*1024, 160*1024, 200*1024,
10377         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10378         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10379     };
10380
10381     static final void appendMemBucket(StringBuilder out, long memKB, String label,
10382             boolean stackLike) {
10383         int start = label.lastIndexOf('.');
10384         if (start >= 0) start++;
10385         else start = 0;
10386         int end = label.length();
10387         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10388             if (DUMP_MEM_BUCKETS[i] >= memKB) {
10389                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10390                 out.append(bucket);
10391                 out.append(stackLike ? "MB." : "MB ");
10392                 out.append(label, start, end);
10393                 return;
10394             }
10395         }
10396         out.append(memKB/1024);
10397         out.append(stackLike ? "MB." : "MB ");
10398         out.append(label, start, end);
10399     }
10400
10401     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10402             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10403             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10404             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10405             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10406     };
10407     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10408             "System", "Persistent", "Foreground",
10409             "Visible", "Perceptible", "Heavy Weight",
10410             "Backup", "A Services", "Home", "Previous",
10411             "B Services", "Background"
10412     };
10413
10414     final void dumpApplicationMemoryUsage(FileDescriptor fd,
10415             PrintWriter pw, String prefix, String[] args, boolean brief,
10416             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10417         boolean dumpAll = false;
10418         boolean oomOnly = false;
10419         
10420         int opti = 0;
10421         while (opti < args.length) {
10422             String opt = args[opti];
10423             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10424                 break;
10425             }
10426             opti++;
10427             if ("-a".equals(opt)) {
10428                 dumpAll = true;
10429             } else if ("--oom".equals(opt)) {
10430                 oomOnly = true;
10431             } else if ("-h".equals(opt)) {
10432                 pw.println("meminfo dump options: [-a] [--oom] [process]");
10433                 pw.println("  -a: include all available information for each process.");
10434                 pw.println("  --oom: only show processes organized by oom adj.");
10435                 pw.println("If [process] is specified it can be the name or ");
10436                 pw.println("pid of a specific process to dump.");
10437                 return;
10438             } else {
10439                 pw.println("Unknown argument: " + opt + "; use -h for help");
10440             }
10441         }
10442         
10443         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10444         if (procs == null) {
10445             return;
10446         }
10447
10448         final boolean isCheckinRequest = scanArgs(args, "--checkin");
10449         long uptime = SystemClock.uptimeMillis();
10450         long realtime = SystemClock.elapsedRealtime();
10451
10452         if (procs.size() == 1 || isCheckinRequest) {
10453             dumpAll = true;
10454         }
10455
10456         if (isCheckinRequest) {
10457             // short checkin version
10458             pw.println(uptime + "," + realtime);
10459             pw.flush();
10460         } else {
10461             pw.println("Applications Memory Usage (kB):");
10462             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10463         }
10464
10465         String[] innerArgs = new String[args.length-opti];
10466         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10467
10468         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10469         long nativePss=0, dalvikPss=0, otherPss=0;
10470         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10471
10472         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10473         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10474                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
10475
10476         long totalPss = 0;
10477
10478         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10479             ProcessRecord r = procs.get(i);
10480             if (r.thread != null) {
10481                 if (!isCheckinRequest && dumpAll) {
10482                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10483                     pw.flush();
10484                 }
10485                 Debug.MemoryInfo mi = null;
10486                 if (dumpAll) {
10487                     try {
10488                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10489                     } catch (RemoteException e) {
10490                         if (!isCheckinRequest) {
10491                             pw.println("Got RemoteException!");
10492                             pw.flush();
10493                         }
10494                     }
10495                 } else {
10496                     mi = new Debug.MemoryInfo();
10497                     Debug.getMemoryInfo(r.pid, mi);
10498                 }
10499
10500                 if (!isCheckinRequest && mi != null) {
10501                     long myTotalPss = mi.getTotalPss();
10502                     totalPss += myTotalPss;
10503                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10504                             r.processName, myTotalPss, 0);
10505                     procMems.add(pssItem);
10506
10507                     nativePss += mi.nativePss;
10508                     dalvikPss += mi.dalvikPss;
10509                     otherPss += mi.otherPss;
10510                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10511                         long mem = mi.getOtherPss(j);
10512                         miscPss[j] += mem;
10513                         otherPss -= mem;
10514                     }
10515
10516                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10517                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10518                                 || oomIndex == (oomPss.length-1)) {
10519                             oomPss[oomIndex] += myTotalPss;
10520                             if (oomProcs[oomIndex] == null) {
10521                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
10522                             }
10523                             oomProcs[oomIndex].add(pssItem);
10524                             break;
10525                         }
10526                     }
10527                 }
10528             }
10529         }
10530
10531         if (!isCheckinRequest && procs.size() > 1) {
10532             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10533
10534             catMems.add(new MemItem("Native", "Native", nativePss, -1));
10535             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10536             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10537             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10538                 String label = Debug.MemoryInfo.getOtherLabel(j);
10539                 catMems.add(new MemItem(label, label, miscPss[j], j));
10540             }
10541
10542             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10543             for (int j=0; j<oomPss.length; j++) {
10544                 if (oomPss[j] != 0) {
10545                     String label = DUMP_MEM_OOM_LABEL[j];
10546                     MemItem item = new MemItem(label, label, oomPss[j],
10547                             DUMP_MEM_OOM_ADJ[j]);
10548                     item.subitems = oomProcs[j];
10549                     oomMems.add(item);
10550                 }
10551             }
10552
10553             if (outTag != null || outStack != null) {
10554                 if (outTag != null) {
10555                     appendMemBucket(outTag, totalPss, "total", false);
10556                 }
10557                 if (outStack != null) {
10558                     appendMemBucket(outStack, totalPss, "total", true);
10559                 }
10560                 boolean firstLine = true;
10561                 for (int i=0; i<oomMems.size(); i++) {
10562                     MemItem miCat = oomMems.get(i);
10563                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
10564                         continue;
10565                     }
10566                     if (miCat.id < ProcessList.SERVICE_ADJ
10567                             || miCat.id == ProcessList.HOME_APP_ADJ
10568                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10569                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10570                             outTag.append(" / ");
10571                         }
10572                         if (outStack != null) {
10573                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10574                                 if (firstLine) {
10575                                     outStack.append(":");
10576                                     firstLine = false;
10577                                 }
10578                                 outStack.append("\n\t at ");
10579                             } else {
10580                                 outStack.append("$");
10581                             }
10582                         }
10583                         for (int j=0; j<miCat.subitems.size(); j++) {
10584                             MemItem mi = miCat.subitems.get(j);
10585                             if (j > 0) {
10586                                 if (outTag != null) {
10587                                     outTag.append(" ");
10588                                 }
10589                                 if (outStack != null) {
10590                                     outStack.append("$");
10591                                 }
10592                             }
10593                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10594                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10595                             }
10596                             if (outStack != null) {
10597                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10598                             }
10599                         }
10600                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10601                             outStack.append("(");
10602                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10603                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10604                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
10605                                     outStack.append(":");
10606                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
10607                                 }
10608                             }
10609                             outStack.append(")");
10610                         }
10611                     }
10612                 }
10613             }
10614
10615             if (!brief && !oomOnly) {
10616                 pw.println();
10617                 pw.println("Total PSS by process:");
10618                 dumpMemItems(pw, "  ", procMems, true);
10619                 pw.println();
10620             }
10621             pw.println("Total PSS by OOM adjustment:");
10622             dumpMemItems(pw, "  ", oomMems, false);
10623             if (!oomOnly) {
10624                 PrintWriter out = categoryPw != null ? categoryPw : pw;
10625                 out.println();
10626                 out.println("Total PSS by category:");
10627                 dumpMemItems(out, "  ", catMems, true);
10628             }
10629             pw.println();
10630             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10631             final int[] SINGLE_LONG_FORMAT = new int[] {
10632                 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10633             };
10634             long[] longOut = new long[1];
10635             Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10636                     SINGLE_LONG_FORMAT, null, longOut, null);
10637             long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10638             longOut[0] = 0;
10639             Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10640                     SINGLE_LONG_FORMAT, null, longOut, null);
10641             long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10642             longOut[0] = 0;
10643             Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10644                     SINGLE_LONG_FORMAT, null, longOut, null);
10645             long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10646             longOut[0] = 0;
10647             Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10648                     SINGLE_LONG_FORMAT, null, longOut, null);
10649             long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10650             pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10651                     pw.print(shared); pw.println(" kB");
10652             pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10653                     pw.print(voltile); pw.println(" kB volatile");
10654         }
10655     }
10656
10657     /**
10658      * Searches array of arguments for the specified string
10659      * @param args array of argument strings
10660      * @param value value to search for
10661      * @return true if the value is contained in the array
10662      */
10663     private static boolean scanArgs(String[] args, String value) {
10664         if (args != null) {
10665             for (String arg : args) {
10666                 if (value.equals(arg)) {
10667                     return true;
10668                 }
10669             }
10670         }
10671         return false;
10672     }
10673
10674     private final boolean removeDyingProviderLocked(ProcessRecord proc,
10675             ContentProviderRecord cpr, boolean always) {
10676         final boolean inLaunching = mLaunchingProviders.contains(cpr);
10677
10678         if (!inLaunching || always) {
10679             synchronized (cpr) {
10680                 cpr.launchingApp = null;
10681                 cpr.notifyAll();
10682             }
10683             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10684             String names[] = cpr.info.authority.split(";");
10685             for (int j = 0; j < names.length; j++) {
10686                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10687             }
10688         }
10689
10690         for (int i=0; i<cpr.connections.size(); i++) {
10691             ContentProviderConnection conn = cpr.connections.get(i);
10692             if (conn.waiting) {
10693                 // If this connection is waiting for the provider, then we don't
10694                 // need to mess with its process unless we are always removing
10695                 // or for some reason the provider is not currently launching.
10696                 if (inLaunching && !always) {
10697                     continue;
10698                 }
10699             }
10700             ProcessRecord capp = conn.client;
10701             conn.dead = true;
10702             if (conn.stableCount > 0) {
10703                 if (!capp.persistent && capp.thread != null
10704                         && capp.pid != 0
10705                         && capp.pid != MY_PID) {
10706                     Slog.i(TAG, "Kill " + capp.processName
10707                             + " (pid " + capp.pid + "): provider " + cpr.info.name
10708                             + " in dying process " + (proc != null ? proc.processName : "??"));
10709                     EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10710                             capp.processName, capp.setAdj, "dying provider "
10711                                     + cpr.name.toShortString());
10712                     Process.killProcessQuiet(capp.pid);
10713                 }
10714             } else if (capp.thread != null && conn.provider.provider != null) {
10715                 try {
10716                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10717                 } catch (RemoteException e) {
10718                 }
10719                 // In the protocol here, we don't expect the client to correctly
10720                 // clean up this connection, we'll just remove it.
10721                 cpr.connections.remove(i);
10722                 conn.client.conProviders.remove(conn);
10723             }
10724         }
10725
10726         if (inLaunching && always) {
10727             mLaunchingProviders.remove(cpr);
10728         }
10729         return inLaunching;
10730     }
10731     
10732     /**
10733      * Main code for cleaning up a process when it has gone away.  This is
10734      * called both as a result of the process dying, or directly when stopping 
10735      * a process when running in single process mode.
10736      */
10737     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10738             boolean restarting, boolean allowRestart, int index) {
10739         if (index >= 0) {
10740             mLruProcesses.remove(index);
10741         }
10742
10743         mProcessesToGc.remove(app);
10744         
10745         // Dismiss any open dialogs.
10746         if (app.crashDialog != null) {
10747             app.crashDialog.dismiss();
10748             app.crashDialog = null;
10749         }
10750         if (app.anrDialog != null) {
10751             app.anrDialog.dismiss();
10752             app.anrDialog = null;
10753         }
10754         if (app.waitDialog != null) {
10755             app.waitDialog.dismiss();
10756             app.waitDialog = null;
10757         }
10758
10759         app.crashing = false;
10760         app.notResponding = false;
10761         
10762         app.resetPackageList();
10763         app.unlinkDeathRecipient();
10764         app.thread = null;
10765         app.forcingToForeground = null;
10766         app.foregroundServices = false;
10767         app.foregroundActivities = false;
10768         app.hasShownUi = false;
10769         app.hasAboveClient = false;
10770
10771         mServices.killServicesLocked(app, allowRestart);
10772
10773         boolean restart = false;
10774
10775         // Remove published content providers.
10776         if (!app.pubProviders.isEmpty()) {
10777             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10778             while (it.hasNext()) {
10779                 ContentProviderRecord cpr = it.next();
10780
10781                 final boolean always = app.bad || !allowRestart;
10782                 if (removeDyingProviderLocked(app, cpr, always) || always) {
10783                     // We left the provider in the launching list, need to
10784                     // restart it.
10785                     restart = true;
10786                 }
10787
10788                 cpr.provider = null;
10789                 cpr.proc = null;
10790             }
10791             app.pubProviders.clear();
10792         }
10793         
10794         // Take care of any launching providers waiting for this process.
10795         if (checkAppInLaunchingProvidersLocked(app, false)) {
10796             restart = true;
10797         }
10798         
10799         // Unregister from connected content providers.
10800         if (!app.conProviders.isEmpty()) {
10801             for (int i=0; i<app.conProviders.size(); i++) {
10802                 ContentProviderConnection conn = app.conProviders.get(i);
10803                 conn.provider.connections.remove(conn);
10804             }
10805             app.conProviders.clear();
10806         }
10807
10808         // At this point there may be remaining entries in mLaunchingProviders
10809         // where we were the only one waiting, so they are no longer of use.
10810         // Look for these and clean up if found.
10811         // XXX Commented out for now.  Trying to figure out a way to reproduce
10812         // the actual situation to identify what is actually going on.
10813         if (false) {
10814             for (int i=0; i<mLaunchingProviders.size(); i++) {
10815                 ContentProviderRecord cpr = (ContentProviderRecord)
10816                         mLaunchingProviders.get(i);
10817                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10818                     synchronized (cpr) {
10819                         cpr.launchingApp = null;
10820                         cpr.notifyAll();
10821                     }
10822                 }
10823             }
10824         }
10825         
10826         skipCurrentReceiverLocked(app);
10827
10828         // Unregister any receivers.
10829         if (app.receivers.size() > 0) {
10830             Iterator<ReceiverList> it = app.receivers.iterator();
10831             while (it.hasNext()) {
10832                 removeReceiverLocked(it.next());
10833             }
10834             app.receivers.clear();
10835         }
10836         
10837         // If the app is undergoing backup, tell the backup manager about it
10838         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10839             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10840                     + mBackupTarget.appInfo + " died during backup");
10841             try {
10842                 IBackupManager bm = IBackupManager.Stub.asInterface(
10843                         ServiceManager.getService(Context.BACKUP_SERVICE));
10844                 bm.agentDisconnected(app.info.packageName);
10845             } catch (RemoteException e) {
10846                 // can't happen; backup manager is local
10847             }
10848         }
10849
10850         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10851             ProcessChangeItem item = mPendingProcessChanges.get(i);
10852             if (item.pid == app.pid) {
10853                 mPendingProcessChanges.remove(i);
10854                 mAvailProcessChanges.add(item);
10855             }
10856         }
10857         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10858
10859         // If the caller is restarting this app, then leave it in its
10860         // current lists and let the caller take care of it.
10861         if (restarting) {
10862             return;
10863         }
10864
10865         if (!app.persistent || app.isolated) {
10866             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10867                     "Removing non-persistent process during cleanup: " + app);
10868             mProcessNames.remove(app.processName, app.uid);
10869             mIsolatedProcesses.remove(app.uid);
10870             if (mHeavyWeightProcess == app) {
10871                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10872                         mHeavyWeightProcess.userId, 0));
10873                 mHeavyWeightProcess = null;
10874             }
10875         } else if (!app.removed) {
10876             // This app is persistent, so we need to keep its record around.
10877             // If it is not already on the pending app list, add it there
10878             // and start a new process for it.
10879             if (mPersistentStartingProcesses.indexOf(app) < 0) {
10880                 mPersistentStartingProcesses.add(app);
10881                 restart = true;
10882             }
10883         }
10884         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10885                 "Clean-up removing on hold: " + app);
10886         mProcessesOnHold.remove(app);
10887
10888         if (app == mHomeProcess) {
10889             mHomeProcess = null;
10890         }
10891         if (app == mPreviousProcess) {
10892             mPreviousProcess = null;
10893         }
10894
10895         if (restart && !app.isolated) {
10896             // We have components that still need to be running in the
10897             // process, so re-launch it.
10898             mProcessNames.put(app.processName, app.uid, app);
10899             startProcessLocked(app, "restart", app.processName);
10900         } else if (app.pid > 0 && app.pid != MY_PID) {
10901             // Goodbye!
10902             synchronized (mPidsSelfLocked) {
10903                 mPidsSelfLocked.remove(app.pid);
10904                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10905             }
10906             app.setPid(0);
10907         }
10908     }
10909
10910     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10911         // Look through the content providers we are waiting to have launched,
10912         // and if any run in this process then either schedule a restart of
10913         // the process or kill the client waiting for it if this process has
10914         // gone bad.
10915         int NL = mLaunchingProviders.size();
10916         boolean restart = false;
10917         for (int i=0; i<NL; i++) {
10918             ContentProviderRecord cpr = mLaunchingProviders.get(i);
10919             if (cpr.launchingApp == app) {
10920                 if (!alwaysBad && !app.bad) {
10921                     restart = true;
10922                 } else {
10923                     removeDyingProviderLocked(app, cpr, true);
10924                     // cpr should have been removed from mLaunchingProviders
10925                     NL = mLaunchingProviders.size();
10926                     i--;
10927                 }
10928             }
10929         }
10930         return restart;
10931     }
10932     
10933     // =========================================================
10934     // SERVICES
10935     // =========================================================
10936
10937     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10938             int flags) {
10939         enforceNotIsolatedCaller("getServices");
10940         synchronized (this) {
10941             return mServices.getRunningServiceInfoLocked(maxNum, flags);
10942         }
10943     }
10944
10945     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10946         enforceNotIsolatedCaller("getRunningServiceControlPanel");
10947         synchronized (this) {
10948             return mServices.getRunningServiceControlPanelLocked(name);
10949         }
10950     }
10951     
10952     public ComponentName startService(IApplicationThread caller, Intent service,
10953             String resolvedType, int userId) {
10954         enforceNotIsolatedCaller("startService");
10955         // Refuse possible leaked file descriptors
10956         if (service != null && service.hasFileDescriptors() == true) {
10957             throw new IllegalArgumentException("File descriptors passed in Intent");
10958         }
10959
10960         if (DEBUG_SERVICE)
10961             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10962         synchronized(this) {
10963             final int callingPid = Binder.getCallingPid();
10964             final int callingUid = Binder.getCallingUid();
10965             checkValidCaller(callingUid, userId);
10966             final long origId = Binder.clearCallingIdentity();
10967             ComponentName res = mServices.startServiceLocked(caller, service,
10968                     resolvedType, callingPid, callingUid, userId);
10969             Binder.restoreCallingIdentity(origId);
10970             return res;
10971         }
10972     }
10973
10974     ComponentName startServiceInPackage(int uid,
10975             Intent service, String resolvedType, int userId) {
10976         synchronized(this) {
10977             if (DEBUG_SERVICE)
10978                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10979             final long origId = Binder.clearCallingIdentity();
10980             ComponentName res = mServices.startServiceLocked(null, service,
10981                     resolvedType, -1, uid, userId);
10982             Binder.restoreCallingIdentity(origId);
10983             return res;
10984         }
10985     }
10986
10987     public int stopService(IApplicationThread caller, Intent service,
10988             String resolvedType, int userId) {
10989         enforceNotIsolatedCaller("stopService");
10990         // Refuse possible leaked file descriptors
10991         if (service != null && service.hasFileDescriptors() == true) {
10992             throw new IllegalArgumentException("File descriptors passed in Intent");
10993         }
10994
10995         checkValidCaller(Binder.getCallingUid(), userId);
10996
10997         synchronized(this) {
10998             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10999         }
11000     }
11001
11002     public IBinder peekService(Intent service, String resolvedType) {
11003         enforceNotIsolatedCaller("peekService");
11004         // Refuse possible leaked file descriptors
11005         if (service != null && service.hasFileDescriptors() == true) {
11006             throw new IllegalArgumentException("File descriptors passed in Intent");
11007         }
11008         synchronized(this) {
11009             return mServices.peekServiceLocked(service, resolvedType);
11010         }
11011     }
11012     
11013     public boolean stopServiceToken(ComponentName className, IBinder token,
11014             int startId) {
11015         synchronized(this) {
11016             return mServices.stopServiceTokenLocked(className, token, startId);
11017         }
11018     }
11019
11020     public void setServiceForeground(ComponentName className, IBinder token,
11021             int id, Notification notification, boolean removeNotification) {
11022         synchronized(this) {
11023             mServices.setServiceForegroundLocked(className, token, id, notification,
11024                     removeNotification);
11025         }
11026     }
11027
11028     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
11029             boolean requireFull, String name, String callerPackage) {
11030         final int callingUserId = UserHandle.getUserId(callingUid);
11031         if (callingUserId != userId) {
11032             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
11033                 if ((requireFull || checkComponentPermission(
11034                         android.Manifest.permission.INTERACT_ACROSS_USERS,
11035                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
11036                         && checkComponentPermission(
11037                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11038                                 callingPid, callingUid, -1, true)
11039                                 != PackageManager.PERMISSION_GRANTED) {
11040                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
11041                         // In this case, they would like to just execute as their
11042                         // owner user instead of failing.
11043                         userId = callingUserId;
11044                     } else {
11045                         StringBuilder builder = new StringBuilder(128);
11046                         builder.append("Permission Denial: ");
11047                         builder.append(name);
11048                         if (callerPackage != null) {
11049                             builder.append(" from ");
11050                             builder.append(callerPackage);
11051                         }
11052                         builder.append(" asks to run as user ");
11053                         builder.append(userId);
11054                         builder.append(" but is calling from user ");
11055                         builder.append(UserHandle.getUserId(callingUid));
11056                         builder.append("; this requires ");
11057                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
11058                         if (!requireFull) {
11059                             builder.append(" or ");
11060                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11061                         }
11062                         String msg = builder.toString();
11063                         Slog.w(TAG, msg);
11064                         throw new SecurityException(msg);
11065                     }
11066                 }
11067             }
11068             if (userId == UserHandle.USER_CURRENT
11069                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
11070                 // Note that we may be accessing this outside of a lock...
11071                 // shouldn't be a big deal, if this is being called outside
11072                 // of a locked context there is intrinsically a race with
11073                 // the value the caller will receive and someone else changing it.
11074                 userId = mCurrentUserId;
11075             }
11076             if (!allowAll && userId < 0) {
11077                 throw new IllegalArgumentException(
11078                         "Call does not support special user #" + userId);
11079             }
11080         }
11081         return userId;
11082     }
11083
11084     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11085             String className, int flags) {
11086         boolean result = false;
11087         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11088             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11089                 if (ActivityManager.checkUidPermission(
11090                         android.Manifest.permission.INTERACT_ACROSS_USERS,
11091                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11092                     ComponentName comp = new ComponentName(aInfo.packageName, className);
11093                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
11094                             + " requests FLAG_SINGLE_USER, but app does not hold "
11095                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
11096                     Slog.w(TAG, msg);
11097                     throw new SecurityException(msg);
11098                 }
11099                 result = true;
11100             }
11101         } else if (componentProcessName == aInfo.packageName) {
11102             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11103         } else if ("system".equals(componentProcessName)) {
11104             result = true;
11105         }
11106         if (DEBUG_MU) {
11107             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11108                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11109         }
11110         return result;
11111     }
11112
11113     public int bindService(IApplicationThread caller, IBinder token,
11114             Intent service, String resolvedType,
11115             IServiceConnection connection, int flags, int userId) {
11116         enforceNotIsolatedCaller("bindService");
11117         // Refuse possible leaked file descriptors
11118         if (service != null && service.hasFileDescriptors() == true) {
11119             throw new IllegalArgumentException("File descriptors passed in Intent");
11120         }
11121
11122         synchronized(this) {
11123             return mServices.bindServiceLocked(caller, token, service, resolvedType,
11124                     connection, flags, userId);
11125         }
11126     }
11127
11128     public boolean unbindService(IServiceConnection connection) {
11129         synchronized (this) {
11130             return mServices.unbindServiceLocked(connection);
11131         }
11132     }
11133
11134     public void publishService(IBinder token, Intent intent, IBinder service) {
11135         // Refuse possible leaked file descriptors
11136         if (intent != null && intent.hasFileDescriptors() == true) {
11137             throw new IllegalArgumentException("File descriptors passed in Intent");
11138         }
11139
11140         synchronized(this) {
11141             if (!(token instanceof ServiceRecord)) {
11142                 throw new IllegalArgumentException("Invalid service token");
11143             }
11144             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11145         }
11146     }
11147
11148     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11149         // Refuse possible leaked file descriptors
11150         if (intent != null && intent.hasFileDescriptors() == true) {
11151             throw new IllegalArgumentException("File descriptors passed in Intent");
11152         }
11153
11154         synchronized(this) {
11155             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11156         }
11157     }
11158
11159     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11160         synchronized(this) {
11161             if (!(token instanceof ServiceRecord)) {
11162                 throw new IllegalArgumentException("Invalid service token");
11163             }
11164             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11165         }
11166     }
11167     
11168     // =========================================================
11169     // BACKUP AND RESTORE
11170     // =========================================================
11171     
11172     // Cause the target app to be launched if necessary and its backup agent
11173     // instantiated.  The backup agent will invoke backupAgentCreated() on the
11174     // activity manager to announce its creation.
11175     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11176         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
11177         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
11178
11179         synchronized(this) {
11180             // !!! TODO: currently no check here that we're already bound
11181             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11182             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11183             synchronized (stats) {
11184                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11185             }
11186
11187             // Backup agent is now in use, its package can't be stopped.
11188             try {
11189                 AppGlobals.getPackageManager().setPackageStoppedState(
11190                         app.packageName, false, UserHandle.getUserId(app.uid));
11191             } catch (RemoteException e) {
11192             } catch (IllegalArgumentException e) {
11193                 Slog.w(TAG, "Failed trying to unstop package "
11194                         + app.packageName + ": " + e);
11195             }
11196
11197             BackupRecord r = new BackupRecord(ss, app, backupMode);
11198             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11199                     ? new ComponentName(app.packageName, app.backupAgentName)
11200                     : new ComponentName("android", "FullBackupAgent");
11201             // startProcessLocked() returns existing proc's record if it's already running
11202             ProcessRecord proc = startProcessLocked(app.processName, app,
11203                     false, 0, "backup", hostingName, false, false);
11204             if (proc == null) {
11205                 Slog.e(TAG, "Unable to start backup agent process " + r);
11206                 return false;
11207             }
11208
11209             r.app = proc;
11210             mBackupTarget = r;
11211             mBackupAppName = app.packageName;
11212
11213             // Try not to kill the process during backup
11214             updateOomAdjLocked(proc);
11215
11216             // If the process is already attached, schedule the creation of the backup agent now.
11217             // If it is not yet live, this will be done when it attaches to the framework.
11218             if (proc.thread != null) {
11219                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11220                 try {
11221                     proc.thread.scheduleCreateBackupAgent(app,
11222                             compatibilityInfoForPackageLocked(app), backupMode);
11223                 } catch (RemoteException e) {
11224                     // Will time out on the backup manager side
11225                 }
11226             } else {
11227                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11228             }
11229             // Invariants: at this point, the target app process exists and the application
11230             // is either already running or in the process of coming up.  mBackupTarget and
11231             // mBackupAppName describe the app, so that when it binds back to the AM we
11232             // know that it's scheduled for a backup-agent operation.
11233         }
11234         
11235         return true;
11236     }
11237
11238     @Override
11239     public void clearPendingBackup() {
11240         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
11241         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
11242
11243         synchronized (this) {
11244             mBackupTarget = null;
11245             mBackupAppName = null;
11246         }
11247     }
11248
11249     // A backup agent has just come up                    
11250     public void backupAgentCreated(String agentPackageName, IBinder agent) {
11251         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11252                 + " = " + agent);
11253
11254         synchronized(this) {
11255             if (!agentPackageName.equals(mBackupAppName)) {
11256                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11257                 return;
11258             }
11259         }
11260
11261         long oldIdent = Binder.clearCallingIdentity();
11262         try {
11263             IBackupManager bm = IBackupManager.Stub.asInterface(
11264                     ServiceManager.getService(Context.BACKUP_SERVICE));
11265             bm.agentConnected(agentPackageName, agent);
11266         } catch (RemoteException e) {
11267             // can't happen; the backup manager service is local
11268         } catch (Exception e) {
11269             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11270             e.printStackTrace();
11271         } finally {
11272             Binder.restoreCallingIdentity(oldIdent);
11273         }
11274     }
11275
11276     // done with this agent
11277     public void unbindBackupAgent(ApplicationInfo appInfo) {
11278         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11279         if (appInfo == null) {
11280             Slog.w(TAG, "unbind backup agent for null app");
11281             return;
11282         }
11283
11284         synchronized(this) {
11285             try {
11286                 if (mBackupAppName == null) {
11287                     Slog.w(TAG, "Unbinding backup agent with no active backup");
11288                     return;
11289                 }
11290
11291                 if (!mBackupAppName.equals(appInfo.packageName)) {
11292                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11293                     return;
11294                 }
11295
11296                 // Not backing this app up any more; reset its OOM adjustment
11297                 final ProcessRecord proc = mBackupTarget.app;
11298                 updateOomAdjLocked(proc);
11299
11300                 // If the app crashed during backup, 'thread' will be null here
11301                 if (proc.thread != null) {
11302                     try {
11303                         proc.thread.scheduleDestroyBackupAgent(appInfo,
11304                                 compatibilityInfoForPackageLocked(appInfo));
11305                     } catch (Exception e) {
11306                         Slog.e(TAG, "Exception when unbinding backup agent:");
11307                         e.printStackTrace();
11308                     }
11309                 }
11310             } finally {
11311                 mBackupTarget = null;
11312                 mBackupAppName = null;
11313             }
11314         }
11315     }
11316     // =========================================================
11317     // BROADCASTS
11318     // =========================================================
11319
11320     private final List getStickiesLocked(String action, IntentFilter filter,
11321             List cur, int userId) {
11322         final ContentResolver resolver = mContext.getContentResolver();
11323         HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11324         if (stickies == null) {
11325             return cur;
11326         }
11327         final ArrayList<Intent> list = stickies.get(action);
11328         if (list == null) {
11329             return cur;
11330         }
11331         int N = list.size();
11332         for (int i=0; i<N; i++) {
11333             Intent intent = list.get(i);
11334             if (filter.match(resolver, intent, true, TAG) >= 0) {
11335                 if (cur == null) {
11336                     cur = new ArrayList<Intent>();
11337                 }
11338                 cur.add(intent);
11339             }
11340         }
11341         return cur;
11342     }
11343
11344     boolean isPendingBroadcastProcessLocked(int pid) {
11345         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11346                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11347     }
11348
11349     void skipPendingBroadcastLocked(int pid) {
11350             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11351             for (BroadcastQueue queue : mBroadcastQueues) {
11352                 queue.skipPendingBroadcastLocked(pid);
11353             }
11354     }
11355
11356     // The app just attached; send any pending broadcasts that it should receive
11357     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11358         boolean didSomething = false;
11359         for (BroadcastQueue queue : mBroadcastQueues) {
11360             didSomething |= queue.sendPendingBroadcastsLocked(app);
11361         }
11362         return didSomething;
11363     }
11364
11365     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11366             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11367         enforceNotIsolatedCaller("registerReceiver");
11368         int callingUid;
11369         int callingPid;
11370         synchronized(this) {
11371             ProcessRecord callerApp = null;
11372             if (caller != null) {
11373                 callerApp = getRecordForAppLocked(caller);
11374                 if (callerApp == null) {
11375                     throw new SecurityException(
11376                             "Unable to find app for caller " + caller
11377                             + " (pid=" + Binder.getCallingPid()
11378                             + ") when registering receiver " + receiver);
11379                 }
11380                 if (callerApp.info.uid != Process.SYSTEM_UID &&
11381                         !callerApp.pkgList.contains(callerPackage)) {
11382                     throw new SecurityException("Given caller package " + callerPackage
11383                             + " is not running in process " + callerApp);
11384                 }
11385                 callingUid = callerApp.info.uid;
11386                 callingPid = callerApp.pid;
11387             } else {
11388                 callerPackage = null;
11389                 callingUid = Binder.getCallingUid();
11390                 callingPid = Binder.getCallingPid();
11391             }
11392
11393             userId = this.handleIncomingUser(callingPid, callingUid, userId,
11394                     true, true, "registerReceiver", callerPackage);
11395
11396             List allSticky = null;
11397
11398             // Look for any matching sticky broadcasts...
11399             Iterator actions = filter.actionsIterator();
11400             if (actions != null) {
11401                 while (actions.hasNext()) {
11402                     String action = (String)actions.next();
11403                     allSticky = getStickiesLocked(action, filter, allSticky,
11404                             UserHandle.USER_ALL);
11405                     allSticky = getStickiesLocked(action, filter, allSticky,
11406                             UserHandle.getUserId(callingUid));
11407                 }
11408             } else {
11409                 allSticky = getStickiesLocked(null, filter, allSticky,
11410                         UserHandle.USER_ALL);
11411                 allSticky = getStickiesLocked(null, filter, allSticky,
11412                         UserHandle.getUserId(callingUid));
11413             }
11414
11415             // The first sticky in the list is returned directly back to
11416             // the client.
11417             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11418
11419             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11420                     + ": " + sticky);
11421
11422             if (receiver == null) {
11423                 return sticky;
11424             }
11425
11426             ReceiverList rl
11427                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11428             if (rl == null) {
11429                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11430                         userId, receiver);
11431                 if (rl.app != null) {
11432                     rl.app.receivers.add(rl);
11433                 } else {
11434                     try {
11435                         receiver.asBinder().linkToDeath(rl, 0);
11436                     } catch (RemoteException e) {
11437                         return sticky;
11438                     }
11439                     rl.linkedToDeath = true;
11440                 }
11441                 mRegisteredReceivers.put(receiver.asBinder(), rl);
11442             } else if (rl.uid != callingUid) {
11443                 throw new IllegalArgumentException(
11444                         "Receiver requested to register for uid " + callingUid
11445                         + " was previously registered for uid " + rl.uid);
11446             } else if (rl.pid != callingPid) {
11447                 throw new IllegalArgumentException(
11448                         "Receiver requested to register for pid " + callingPid
11449                         + " was previously registered for pid " + rl.pid);
11450             } else if (rl.userId != userId) {
11451                 throw new IllegalArgumentException(
11452                         "Receiver requested to register for user " + userId
11453                         + " was previously registered for user " + rl.userId);
11454             }
11455             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11456                     permission, callingUid, userId);
11457             rl.add(bf);
11458             if (!bf.debugCheck()) {
11459                 Slog.w(TAG, "==> For Dynamic broadast");
11460             }
11461             mReceiverResolver.addFilter(bf);
11462
11463             // Enqueue broadcasts for all existing stickies that match
11464             // this filter.
11465             if (allSticky != null) {
11466                 ArrayList receivers = new ArrayList();
11467                 receivers.add(bf);
11468
11469                 int N = allSticky.size();
11470                 for (int i=0; i<N; i++) {
11471                     Intent intent = (Intent)allSticky.get(i);
11472                     BroadcastQueue queue = broadcastQueueForIntent(intent);
11473                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11474                             null, -1, -1, null, receivers, null, 0, null, null,
11475                             false, true, true, -1);
11476                     queue.enqueueParallelBroadcastLocked(r);
11477                     queue.scheduleBroadcastsLocked();
11478                 }
11479             }
11480
11481             return sticky;
11482         }
11483     }
11484
11485     public void unregisterReceiver(IIntentReceiver receiver) {
11486         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11487
11488         final long origId = Binder.clearCallingIdentity();
11489         try {
11490             boolean doTrim = false;
11491
11492             synchronized(this) {
11493                 ReceiverList rl
11494                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11495                 if (rl != null) {
11496                     if (rl.curBroadcast != null) {
11497                         BroadcastRecord r = rl.curBroadcast;
11498                         final boolean doNext = finishReceiverLocked(
11499                                 receiver.asBinder(), r.resultCode, r.resultData,
11500                                 r.resultExtras, r.resultAbort, true);
11501                         if (doNext) {
11502                             doTrim = true;
11503                             r.queue.processNextBroadcast(false);
11504                         }
11505                     }
11506
11507                     if (rl.app != null) {
11508                         rl.app.receivers.remove(rl);
11509                     }
11510                     removeReceiverLocked(rl);
11511                     if (rl.linkedToDeath) {
11512                         rl.linkedToDeath = false;
11513                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
11514                     }
11515                 }
11516             }
11517
11518             // If we actually concluded any broadcasts, we might now be able
11519             // to trim the recipients' apps from our working set
11520             if (doTrim) {
11521                 trimApplications();
11522                 return;
11523             }
11524
11525         } finally {
11526             Binder.restoreCallingIdentity(origId);
11527         }
11528     }
11529
11530     void removeReceiverLocked(ReceiverList rl) {
11531         mRegisteredReceivers.remove(rl.receiver.asBinder());
11532         int N = rl.size();
11533         for (int i=0; i<N; i++) {
11534             mReceiverResolver.removeFilter(rl.get(i));
11535         }
11536     }
11537     
11538     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11539         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11540             ProcessRecord r = mLruProcesses.get(i);
11541             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11542                 try {
11543                     r.thread.dispatchPackageBroadcast(cmd, packages);
11544                 } catch (RemoteException ex) {
11545                 }
11546             }
11547         }
11548     }
11549
11550     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11551             int[] users) {
11552         List<ResolveInfo> receivers = null;
11553         try {
11554             HashSet<ComponentName> singleUserReceivers = null;
11555             boolean scannedFirstReceivers = false;
11556             for (int user : users) {
11557                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11558                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11559                 if (user != 0 && newReceivers != null) {
11560                     // If this is not the primary user, we need to check for
11561                     // any receivers that should be filtered out.
11562                     for (int i=0; i<newReceivers.size(); i++) {
11563                         ResolveInfo ri = newReceivers.get(i);
11564                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11565                             newReceivers.remove(i);
11566                             i--;
11567                         }
11568                     }
11569                 }
11570                 if (newReceivers != null && newReceivers.size() == 0) {
11571                     newReceivers = null;
11572                 }
11573                 if (receivers == null) {
11574                     receivers = newReceivers;
11575                 } else if (newReceivers != null) {
11576                     // We need to concatenate the additional receivers
11577                     // found with what we have do far.  This would be easy,
11578                     // but we also need to de-dup any receivers that are
11579                     // singleUser.
11580                     if (!scannedFirstReceivers) {
11581                         // Collect any single user receivers we had already retrieved.
11582                         scannedFirstReceivers = true;
11583                         for (int i=0; i<receivers.size(); i++) {
11584                             ResolveInfo ri = receivers.get(i);
11585                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11586                                 ComponentName cn = new ComponentName(
11587                                         ri.activityInfo.packageName, ri.activityInfo.name);
11588                                 if (singleUserReceivers == null) {
11589                                     singleUserReceivers = new HashSet<ComponentName>();
11590                                 }
11591                                 singleUserReceivers.add(cn);
11592                             }
11593                         }
11594                     }
11595                     // Add the new results to the existing results, tracking
11596                     // and de-dupping single user receivers.
11597                     for (int i=0; i<newReceivers.size(); i++) {
11598                         ResolveInfo ri = newReceivers.get(i);
11599                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11600                             ComponentName cn = new ComponentName(
11601                                     ri.activityInfo.packageName, ri.activityInfo.name);
11602                             if (singleUserReceivers == null) {
11603                                 singleUserReceivers = new HashSet<ComponentName>();
11604                             }
11605                             if (!singleUserReceivers.contains(cn)) {
11606                                 singleUserReceivers.add(cn);
11607                                 receivers.add(ri);
11608                             }
11609                         } else {
11610                             receivers.add(ri);
11611                         }
11612                     }
11613                 }
11614             }
11615         } catch (RemoteException ex) {
11616             // pm is in same process, this will never happen.
11617         }
11618         return receivers;
11619     }
11620
11621     private final int broadcastIntentLocked(ProcessRecord callerApp,
11622             String callerPackage, Intent intent, String resolvedType,
11623             IIntentReceiver resultTo, int resultCode, String resultData,
11624             Bundle map, String requiredPermission,
11625             boolean ordered, boolean sticky, int callingPid, int callingUid,
11626             int userId) {
11627         intent = new Intent(intent);
11628
11629         // By default broadcasts do not go to stopped apps.
11630         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11631
11632         if (DEBUG_BROADCAST_LIGHT) Slog.v(
11633             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11634             + " ordered=" + ordered + " userid=" + userId);
11635         if ((resultTo != null) && !ordered) {
11636             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11637         }
11638
11639         userId = handleIncomingUser(callingPid, callingUid, userId,
11640                 true, false, "broadcast", callerPackage);
11641
11642         // Make sure that the user who is receiving this broadcast is started.
11643         // If not, we will just skip it.
11644         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11645             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11646                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11647                 Slog.w(TAG, "Skipping broadcast of " + intent
11648                         + ": user " + userId + " is stopped");
11649                 return ActivityManager.BROADCAST_SUCCESS;
11650             }
11651         }
11652
11653         /*
11654          * Prevent non-system code (defined here to be non-persistent
11655          * processes) from sending protected broadcasts.
11656          */
11657         int callingAppId = UserHandle.getAppId(callingUid);
11658         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11659             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11660             callingUid == 0) {
11661             // Always okay.
11662         } else if (callerApp == null || !callerApp.persistent) {
11663             try {
11664                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
11665                         intent.getAction())) {
11666                     String msg = "Permission Denial: not allowed to send broadcast "
11667                             + intent.getAction() + " from pid="
11668                             + callingPid + ", uid=" + callingUid;
11669                     Slog.w(TAG, msg);
11670                     throw new SecurityException(msg);
11671                 }
11672             } catch (RemoteException e) {
11673                 Slog.w(TAG, "Remote exception", e);
11674                 return ActivityManager.BROADCAST_SUCCESS;
11675             }
11676         }
11677
11678         // Handle special intents: if this broadcast is from the package
11679         // manager about a package being removed, we need to remove all of
11680         // its activities from the history stack.
11681         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11682                 intent.getAction());
11683         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11684                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11685                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11686                 || uidRemoved) {
11687             if (checkComponentPermission(
11688                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11689                     callingPid, callingUid, -1, true)
11690                     == PackageManager.PERMISSION_GRANTED) {
11691                 if (uidRemoved) {
11692                     final Bundle intentExtras = intent.getExtras();
11693                     final int uid = intentExtras != null
11694                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11695                     if (uid >= 0) {
11696                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11697                         synchronized (bs) {
11698                             bs.removeUidStatsLocked(uid);
11699                         }
11700                     }
11701                 } else {
11702                     // If resources are unavailable just force stop all
11703                     // those packages and flush the attribute cache as well.
11704                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11705                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11706                         if (list != null && (list.length > 0)) {
11707                             for (String pkg : list) {
11708                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11709                             }
11710                             sendPackageBroadcastLocked(
11711                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11712                         }
11713                     } else {
11714                         Uri data = intent.getData();
11715                         String ssp;
11716                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11717                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11718                                 forceStopPackageLocked(ssp,
11719                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11720                                         false, userId);
11721                             }
11722                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11723                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11724                                         new String[] {ssp}, userId);
11725                             }
11726                         }
11727                     }
11728                 }
11729             } else {
11730                 String msg = "Permission Denial: " + intent.getAction()
11731                         + " broadcast from " + callerPackage + " (pid=" + callingPid
11732                         + ", uid=" + callingUid + ")"
11733                         + " requires "
11734                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11735                 Slog.w(TAG, msg);
11736                 throw new SecurityException(msg);
11737             }
11738
11739         // Special case for adding a package: by default turn on compatibility
11740         // mode.
11741         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11742             Uri data = intent.getData();
11743             String ssp;
11744             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11745                 mCompatModePackages.handlePackageAddedLocked(ssp,
11746                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11747             }
11748         }
11749
11750         /*
11751          * If this is the time zone changed action, queue up a message that will reset the timezone
11752          * of all currently running processes. This message will get queued up before the broadcast
11753          * happens.
11754          */
11755         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11756             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11757         }
11758
11759         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11760             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11761         }
11762
11763         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11764             ProxyProperties proxy = intent.getParcelableExtra("proxy");
11765             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11766         }
11767
11768         // Add to the sticky list if requested.
11769         if (sticky) {
11770             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11771                     callingPid, callingUid)
11772                     != PackageManager.PERMISSION_GRANTED) {
11773                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11774                         + callingPid + ", uid=" + callingUid
11775                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11776                 Slog.w(TAG, msg);
11777                 throw new SecurityException(msg);
11778             }
11779             if (requiredPermission != null) {
11780                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
11781                         + " and enforce permission " + requiredPermission);
11782                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11783             }
11784             if (intent.getComponent() != null) {
11785                 throw new SecurityException(
11786                         "Sticky broadcasts can't target a specific component");
11787             }
11788             // We use userId directly here, since the "all" target is maintained
11789             // as a separate set of sticky broadcasts.
11790             if (userId != UserHandle.USER_ALL) {
11791                 // But first, if this is not a broadcast to all users, then
11792                 // make sure it doesn't conflict with an existing broadcast to
11793                 // all users.
11794                 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11795                         UserHandle.USER_ALL);
11796                 if (stickies != null) {
11797                     ArrayList<Intent> list = stickies.get(intent.getAction());
11798                     if (list != null) {
11799                         int N = list.size();
11800                         int i;
11801                         for (i=0; i<N; i++) {
11802                             if (intent.filterEquals(list.get(i))) {
11803                                 throw new IllegalArgumentException(
11804                                         "Sticky broadcast " + intent + " for user "
11805                                         + userId + " conflicts with existing global broadcast");
11806                             }
11807                         }
11808                     }
11809                 }
11810             }
11811             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11812             if (stickies == null) {
11813                 stickies = new HashMap<String, ArrayList<Intent>>();
11814                 mStickyBroadcasts.put(userId, stickies);
11815             }
11816             ArrayList<Intent> list = stickies.get(intent.getAction());
11817             if (list == null) {
11818                 list = new ArrayList<Intent>();
11819                 stickies.put(intent.getAction(), list);
11820             }
11821             int N = list.size();
11822             int i;
11823             for (i=0; i<N; i++) {
11824                 if (intent.filterEquals(list.get(i))) {
11825                     // This sticky already exists, replace it.
11826                     list.set(i, new Intent(intent));
11827                     break;
11828                 }
11829             }
11830             if (i >= N) {
11831                 list.add(new Intent(intent));
11832             }
11833         }
11834
11835         int[] users;
11836         if (userId == UserHandle.USER_ALL) {
11837             // Caller wants broadcast to go to all started users.
11838             users = mStartedUserArray;
11839         } else {
11840             // Caller wants broadcast to go to one specific user.
11841             users = new int[] {userId};
11842         }
11843
11844         // Figure out who all will receive this broadcast.
11845         List receivers = null;
11846         List<BroadcastFilter> registeredReceivers = null;
11847         // Need to resolve the intent to interested receivers...
11848         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11849                  == 0) {
11850             receivers = collectReceiverComponents(intent, resolvedType, users);
11851         }
11852         if (intent.getComponent() == null) {
11853             registeredReceivers = mReceiverResolver.queryIntent(intent,
11854                     resolvedType, false, userId);
11855         }
11856
11857         final boolean replacePending =
11858                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11859         
11860         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11861                 + " replacePending=" + replacePending);
11862         
11863         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11864         if (!ordered && NR > 0) {
11865             // If we are not serializing this broadcast, then send the
11866             // registered receivers separately so they don't wait for the
11867             // components to be launched.
11868             final BroadcastQueue queue = broadcastQueueForIntent(intent);
11869             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11870                     callerPackage, callingPid, callingUid, requiredPermission,
11871                     registeredReceivers, resultTo, resultCode, resultData, map,
11872                     ordered, sticky, false, userId);
11873             if (DEBUG_BROADCAST) Slog.v(
11874                     TAG, "Enqueueing parallel broadcast " + r);
11875             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11876             if (!replaced) {
11877                 queue.enqueueParallelBroadcastLocked(r);
11878                 queue.scheduleBroadcastsLocked();
11879             }
11880             registeredReceivers = null;
11881             NR = 0;
11882         }
11883
11884         // Merge into one list.
11885         int ir = 0;
11886         if (receivers != null) {
11887             // A special case for PACKAGE_ADDED: do not allow the package
11888             // being added to see this broadcast.  This prevents them from
11889             // using this as a back door to get run as soon as they are
11890             // installed.  Maybe in the future we want to have a special install
11891             // broadcast or such for apps, but we'd like to deliberately make
11892             // this decision.
11893             String skipPackages[] = null;
11894             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11895                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11896                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11897                 Uri data = intent.getData();
11898                 if (data != null) {
11899                     String pkgName = data.getSchemeSpecificPart();
11900                     if (pkgName != null) {
11901                         skipPackages = new String[] { pkgName };
11902                     }
11903                 }
11904             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11905                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11906             }
11907             if (skipPackages != null && (skipPackages.length > 0)) {
11908                 for (String skipPackage : skipPackages) {
11909                     if (skipPackage != null) {
11910                         int NT = receivers.size();
11911                         for (int it=0; it<NT; it++) {
11912                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
11913                             if (curt.activityInfo.packageName.equals(skipPackage)) {
11914                                 receivers.remove(it);
11915                                 it--;
11916                                 NT--;
11917                             }
11918                         }
11919                     }
11920                 }
11921             }
11922
11923             int NT = receivers != null ? receivers.size() : 0;
11924             int it = 0;
11925             ResolveInfo curt = null;
11926             BroadcastFilter curr = null;
11927             while (it < NT && ir < NR) {
11928                 if (curt == null) {
11929                     curt = (ResolveInfo)receivers.get(it);
11930                 }
11931                 if (curr == null) {
11932                     curr = registeredReceivers.get(ir);
11933                 }
11934                 if (curr.getPriority() >= curt.priority) {
11935                     // Insert this broadcast record into the final list.
11936                     receivers.add(it, curr);
11937                     ir++;
11938                     curr = null;
11939                     it++;
11940                     NT++;
11941                 } else {
11942                     // Skip to the next ResolveInfo in the final list.
11943                     it++;
11944                     curt = null;
11945                 }
11946             }
11947         }
11948         while (ir < NR) {
11949             if (receivers == null) {
11950                 receivers = new ArrayList();
11951             }
11952             receivers.add(registeredReceivers.get(ir));
11953             ir++;
11954         }
11955
11956         if ((receivers != null && receivers.size() > 0)
11957                 || resultTo != null) {
11958             BroadcastQueue queue = broadcastQueueForIntent(intent);
11959             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11960                     callerPackage, callingPid, callingUid, requiredPermission,
11961                     receivers, resultTo, resultCode, resultData, map, ordered,
11962                     sticky, false, userId);
11963             if (DEBUG_BROADCAST) Slog.v(
11964                     TAG, "Enqueueing ordered broadcast " + r
11965                     + ": prev had " + queue.mOrderedBroadcasts.size());
11966             if (DEBUG_BROADCAST) {
11967                 int seq = r.intent.getIntExtra("seq", -1);
11968                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11969             }
11970             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 
11971             if (!replaced) {
11972                 queue.enqueueOrderedBroadcastLocked(r);
11973                 queue.scheduleBroadcastsLocked();
11974             }
11975         }
11976
11977         return ActivityManager.BROADCAST_SUCCESS;
11978     }
11979
11980     final Intent verifyBroadcastLocked(Intent intent) {
11981         // Refuse possible leaked file descriptors
11982         if (intent != null && intent.hasFileDescriptors() == true) {
11983             throw new IllegalArgumentException("File descriptors passed in Intent");
11984         }
11985
11986         int flags = intent.getFlags();
11987
11988         if (!mProcessesReady) {
11989             // if the caller really truly claims to know what they're doing, go
11990             // ahead and allow the broadcast without launching any receivers
11991             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11992                 intent = new Intent(intent);
11993                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11994             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11995                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11996                         + " before boot completion");
11997                 throw new IllegalStateException("Cannot broadcast before boot completed");
11998             }
11999         }
12000
12001         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12002             throw new IllegalArgumentException(
12003                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12004         }
12005
12006         return intent;
12007     }
12008
12009     public final int broadcastIntent(IApplicationThread caller,
12010             Intent intent, String resolvedType, IIntentReceiver resultTo,
12011             int resultCode, String resultData, Bundle map,
12012             String requiredPermission, boolean serialized, boolean sticky, int userId) {
12013         enforceNotIsolatedCaller("broadcastIntent");
12014         synchronized(this) {
12015             intent = verifyBroadcastLocked(intent);
12016             
12017             final ProcessRecord callerApp = getRecordForAppLocked(caller);
12018             final int callingPid = Binder.getCallingPid();
12019             final int callingUid = Binder.getCallingUid();
12020             final long origId = Binder.clearCallingIdentity();
12021             int res = broadcastIntentLocked(callerApp,
12022                     callerApp != null ? callerApp.info.packageName : null,
12023                     intent, resolvedType, resultTo,
12024                     resultCode, resultData, map, requiredPermission, serialized, sticky,
12025                     callingPid, callingUid, userId);
12026             Binder.restoreCallingIdentity(origId);
12027             return res;
12028         }
12029     }
12030
12031     int broadcastIntentInPackage(String packageName, int uid,
12032             Intent intent, String resolvedType, IIntentReceiver resultTo,
12033             int resultCode, String resultData, Bundle map,
12034             String requiredPermission, boolean serialized, boolean sticky, int userId) {
12035         synchronized(this) {
12036             intent = verifyBroadcastLocked(intent);
12037
12038             final long origId = Binder.clearCallingIdentity();
12039             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12040                     resultTo, resultCode, resultData, map, requiredPermission,
12041                     serialized, sticky, -1, uid, userId);
12042             Binder.restoreCallingIdentity(origId);
12043             return res;
12044         }
12045     }
12046
12047     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
12048         // Refuse possible leaked file descriptors
12049         if (intent != null && intent.hasFileDescriptors() == true) {
12050             throw new IllegalArgumentException("File descriptors passed in Intent");
12051         }
12052
12053         userId = handleIncomingUser(Binder.getCallingPid(),
12054                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
12055
12056         synchronized(this) {
12057             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12058                     != PackageManager.PERMISSION_GRANTED) {
12059                 String msg = "Permission Denial: unbroadcastIntent() from pid="
12060                         + Binder.getCallingPid()
12061                         + ", uid=" + Binder.getCallingUid()
12062                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12063                 Slog.w(TAG, msg);
12064                 throw new SecurityException(msg);
12065             }
12066             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12067             if (stickies != null) {
12068                 ArrayList<Intent> list = stickies.get(intent.getAction());
12069                 if (list != null) {
12070                     int N = list.size();
12071                     int i;
12072                     for (i=0; i<N; i++) {
12073                         if (intent.filterEquals(list.get(i))) {
12074                             list.remove(i);
12075                             break;
12076                         }
12077                     }
12078                     if (list.size() <= 0) {
12079                         stickies.remove(intent.getAction());
12080                     }
12081                 }
12082                 if (stickies.size() <= 0) {
12083                     mStickyBroadcasts.remove(userId);
12084                 }
12085             }
12086         }
12087     }
12088
12089     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12090             String resultData, Bundle resultExtras, boolean resultAbort,
12091             boolean explicit) {
12092         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12093         if (r == null) {
12094             Slog.w(TAG, "finishReceiver called but not found on queue");
12095             return false;
12096         }
12097
12098         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12099                 explicit);
12100     }
12101
12102     public void finishReceiver(IBinder who, int resultCode, String resultData,
12103             Bundle resultExtras, boolean resultAbort) {
12104         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12105
12106         // Refuse possible leaked file descriptors
12107         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12108             throw new IllegalArgumentException("File descriptors passed in Bundle");
12109         }
12110
12111         final long origId = Binder.clearCallingIdentity();
12112         try {
12113             boolean doNext = false;
12114             BroadcastRecord r = null;
12115
12116             synchronized(this) {
12117                 r = broadcastRecordForReceiverLocked(who);
12118                 if (r != null) {
12119                     doNext = r.queue.finishReceiverLocked(r, resultCode,
12120                         resultData, resultExtras, resultAbort, true);
12121                 }
12122             }
12123
12124             if (doNext) {
12125                 r.queue.processNextBroadcast(false);
12126             }
12127             trimApplications();
12128         } finally {
12129             Binder.restoreCallingIdentity(origId);
12130         }
12131     }
12132     
12133     // =========================================================
12134     // INSTRUMENTATION
12135     // =========================================================
12136
12137     public boolean startInstrumentation(ComponentName className,
12138             String profileFile, int flags, Bundle arguments,
12139             IInstrumentationWatcher watcher, int userId) {
12140         enforceNotIsolatedCaller("startInstrumentation");
12141         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12142                 userId, false, true, "startInstrumentation", null);
12143         // Refuse possible leaked file descriptors
12144         if (arguments != null && arguments.hasFileDescriptors()) {
12145             throw new IllegalArgumentException("File descriptors passed in Bundle");
12146         }
12147
12148         synchronized(this) {
12149             InstrumentationInfo ii = null;
12150             ApplicationInfo ai = null;
12151             try {
12152                 ii = mContext.getPackageManager().getInstrumentationInfo(
12153                     className, STOCK_PM_FLAGS);
12154                 ai = AppGlobals.getPackageManager().getApplicationInfo(
12155                         ii.targetPackage, STOCK_PM_FLAGS, userId);
12156             } catch (PackageManager.NameNotFoundException e) {
12157             } catch (RemoteException e) {
12158             }
12159             if (ii == null) {
12160                 reportStartInstrumentationFailure(watcher, className,
12161                         "Unable to find instrumentation info for: " + className);
12162                 return false;
12163             }
12164             if (ai == null) {
12165                 reportStartInstrumentationFailure(watcher, className,
12166                         "Unable to find instrumentation target package: " + ii.targetPackage);
12167                 return false;
12168             }
12169
12170             int match = mContext.getPackageManager().checkSignatures(
12171                     ii.targetPackage, ii.packageName);
12172             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12173                 String msg = "Permission Denial: starting instrumentation "
12174                         + className + " from pid="
12175                         + Binder.getCallingPid()
12176                         + ", uid=" + Binder.getCallingPid()
12177                         + " not allowed because package " + ii.packageName
12178                         + " does not have a signature matching the target "
12179                         + ii.targetPackage;
12180                 reportStartInstrumentationFailure(watcher, className, msg);
12181                 throw new SecurityException(msg);
12182             }
12183
12184             final long origId = Binder.clearCallingIdentity();
12185             // Instrumentation can kill and relaunch even persistent processes
12186             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12187             ProcessRecord app = addAppLocked(ai, false);
12188             app.instrumentationClass = className;
12189             app.instrumentationInfo = ai;
12190             app.instrumentationProfileFile = profileFile;
12191             app.instrumentationArguments = arguments;
12192             app.instrumentationWatcher = watcher;
12193             app.instrumentationResultClass = className;
12194             Binder.restoreCallingIdentity(origId);
12195         }
12196
12197         return true;
12198     }
12199     
12200     /**
12201      * Report errors that occur while attempting to start Instrumentation.  Always writes the 
12202      * error to the logs, but if somebody is watching, send the report there too.  This enables
12203      * the "am" command to report errors with more information.
12204      * 
12205      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12206      * @param cn The component name of the instrumentation.
12207      * @param report The error report.
12208      */
12209     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 
12210             ComponentName cn, String report) {
12211         Slog.w(TAG, report);
12212         try {
12213             if (watcher != null) {
12214                 Bundle results = new Bundle();
12215                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12216                 results.putString("Error", report);
12217                 watcher.instrumentationStatus(cn, -1, results);
12218             }
12219         } catch (RemoteException e) {
12220             Slog.w(TAG, e);
12221         }
12222     }
12223
12224     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12225         if (app.instrumentationWatcher != null) {
12226             try {
12227                 // NOTE:  IInstrumentationWatcher *must* be oneway here
12228                 app.instrumentationWatcher.instrumentationFinished(
12229                     app.instrumentationClass,
12230                     resultCode,
12231                     results);
12232             } catch (RemoteException e) {
12233             }
12234         }
12235         app.instrumentationWatcher = null;
12236         app.instrumentationClass = null;
12237         app.instrumentationInfo = null;
12238         app.instrumentationProfileFile = null;
12239         app.instrumentationArguments = null;
12240
12241         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12242     }
12243
12244     public void finishInstrumentation(IApplicationThread target,
12245             int resultCode, Bundle results) {
12246         int userId = UserHandle.getCallingUserId();
12247         // Refuse possible leaked file descriptors
12248         if (results != null && results.hasFileDescriptors()) {
12249             throw new IllegalArgumentException("File descriptors passed in Intent");
12250         }
12251
12252         synchronized(this) {
12253             ProcessRecord app = getRecordForAppLocked(target);
12254             if (app == null) {
12255                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
12256                 return;
12257             }
12258             final long origId = Binder.clearCallingIdentity();
12259             finishInstrumentationLocked(app, resultCode, results);
12260             Binder.restoreCallingIdentity(origId);
12261         }
12262     }
12263
12264     // =========================================================
12265     // CONFIGURATION
12266     // =========================================================
12267     
12268     public ConfigurationInfo getDeviceConfigurationInfo() {
12269         ConfigurationInfo config = new ConfigurationInfo();
12270         synchronized (this) {
12271             config.reqTouchScreen = mConfiguration.touchscreen;
12272             config.reqKeyboardType = mConfiguration.keyboard;
12273             config.reqNavigation = mConfiguration.navigation;
12274             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12275                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12276                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12277             }
12278             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12279                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12280                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12281             }
12282             config.reqGlEsVersion = GL_ES_VERSION;
12283         }
12284         return config;
12285     }
12286
12287     public Configuration getConfiguration() {
12288         Configuration ci;
12289         synchronized(this) {
12290             ci = new Configuration(mConfiguration);
12291         }
12292         return ci;
12293     }
12294
12295     public void updatePersistentConfiguration(Configuration values) {
12296         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12297                 "updateConfiguration()");
12298         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12299                 "updateConfiguration()");
12300         if (values == null) {
12301             throw new NullPointerException("Configuration must not be null");
12302         }
12303
12304         synchronized(this) {
12305             final long origId = Binder.clearCallingIdentity();
12306             updateConfigurationLocked(values, null, true, false);
12307             Binder.restoreCallingIdentity(origId);
12308         }
12309     }
12310
12311     public void updateConfiguration(Configuration values) {
12312         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12313                 "updateConfiguration()");
12314
12315         synchronized(this) {
12316             if (values == null && mWindowManager != null) {
12317                 // sentinel: fetch the current configuration from the window manager
12318                 values = mWindowManager.computeNewConfiguration();
12319             }
12320
12321             if (mWindowManager != null) {
12322                 mProcessList.applyDisplaySize(mWindowManager);
12323             }
12324
12325             final long origId = Binder.clearCallingIdentity();
12326             if (values != null) {
12327                 Settings.System.clearConfiguration(values);
12328             }
12329             updateConfigurationLocked(values, null, false, false);
12330             Binder.restoreCallingIdentity(origId);
12331         }
12332     }
12333
12334     /**
12335      * Do either or both things: (1) change the current configuration, and (2)
12336      * make sure the given activity is running with the (now) current
12337      * configuration.  Returns true if the activity has been left running, or
12338      * false if <var>starting</var> is being destroyed to match the new
12339      * configuration.
12340      * @param persistent TODO
12341      */
12342     boolean updateConfigurationLocked(Configuration values,
12343             ActivityRecord starting, boolean persistent, boolean initLocale) {
12344         // do nothing if we are headless
12345         if (mHeadless) return true;
12346
12347         int changes = 0;
12348         
12349         boolean kept = true;
12350         
12351         if (values != null) {
12352             Configuration newConfig = new Configuration(mConfiguration);
12353             changes = newConfig.updateFrom(values);
12354             if (changes != 0) {
12355                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12356                     Slog.i(TAG, "Updating configuration to: " + values);
12357                 }
12358                 
12359                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12360
12361                 if (values.locale != null && !initLocale) {
12362                     saveLocaleLocked(values.locale, 
12363                                      !values.locale.equals(mConfiguration.locale),
12364                                      values.userSetLocale);
12365                 }
12366
12367                 mConfigurationSeq++;
12368                 if (mConfigurationSeq <= 0) {
12369                     mConfigurationSeq = 1;
12370                 }
12371                 newConfig.seq = mConfigurationSeq;
12372                 mConfiguration = newConfig;
12373                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
12374
12375                 final Configuration configCopy = new Configuration(mConfiguration);
12376                 
12377                 // TODO: If our config changes, should we auto dismiss any currently
12378                 // showing dialogs?
12379                 mShowDialogs = shouldShowDialogs(newConfig);
12380
12381                 AttributeCache ac = AttributeCache.instance();
12382                 if (ac != null) {
12383                     ac.updateConfiguration(configCopy);
12384                 }
12385
12386                 // Make sure all resources in our process are updated
12387                 // right now, so that anyone who is going to retrieve
12388                 // resource values after we return will be sure to get
12389                 // the new ones.  This is especially important during
12390                 // boot, where the first config change needs to guarantee
12391                 // all resources have that config before following boot
12392                 // code is executed.
12393                 mSystemThread.applyConfigurationToResources(configCopy);
12394
12395                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12396                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12397                     msg.obj = new Configuration(configCopy);
12398                     mHandler.sendMessage(msg);
12399                 }
12400         
12401                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12402                     ProcessRecord app = mLruProcesses.get(i);
12403                     try {
12404                         if (app.thread != null) {
12405                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12406                                     + app.processName + " new config " + mConfiguration);
12407                             app.thread.scheduleConfigurationChanged(configCopy);
12408                         }
12409                     } catch (Exception e) {
12410                     }
12411                 }
12412                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12413                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12414                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
12415                         | Intent.FLAG_RECEIVER_FOREGROUND);
12416                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12417                         null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12418                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12419                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12420                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12421                     broadcastIntentLocked(null, null, intent,
12422                             null, null, 0, null, null,
12423                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12424                 }
12425             }
12426         }
12427         
12428         if (changes != 0 && starting == null) {
12429             // If the configuration changed, and the caller is not already
12430             // in the process of starting an activity, then find the top
12431             // activity to check if its configuration needs to change.
12432             starting = mMainStack.topRunningActivityLocked(null);
12433         }
12434         
12435         if (starting != null) {
12436             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12437             // And we need to make sure at this point that all other activities
12438             // are made visible with the correct configuration.
12439             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12440         }
12441         
12442         if (values != null && mWindowManager != null) {
12443             mWindowManager.setNewConfiguration(mConfiguration);
12444         }
12445         
12446         return kept;
12447     }
12448
12449     /**
12450      * Decide based on the configuration whether we should shouw the ANR,
12451      * crash, etc dialogs.  The idea is that if there is no affordnace to
12452      * press the on-screen buttons, we shouldn't show the dialog.
12453      *
12454      * A thought: SystemUI might also want to get told about this, the Power
12455      * dialog / global actions also might want different behaviors.
12456      */
12457     private static final boolean shouldShowDialogs(Configuration config) {
12458         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12459                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12460     }
12461     
12462     /**
12463      * Save the locale.  You must be inside a synchronized (this) block.
12464      */
12465     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12466         if(isDiff) {
12467             SystemProperties.set("user.language", l.getLanguage());
12468             SystemProperties.set("user.region", l.getCountry());
12469         } 
12470
12471         if(isPersist) {
12472             SystemProperties.set("persist.sys.language", l.getLanguage());
12473             SystemProperties.set("persist.sys.country", l.getCountry());
12474             SystemProperties.set("persist.sys.localevar", l.getVariant());
12475         }
12476     }
12477
12478     @Override
12479     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12480         ActivityRecord srec = ActivityRecord.forToken(token);
12481         return srec != null && srec.task.affinity != null &&
12482                 srec.task.affinity.equals(destAffinity);
12483     }
12484
12485     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12486             Intent resultData) {
12487         ComponentName dest = destIntent.getComponent();
12488
12489         synchronized (this) {
12490             ActivityRecord srec = ActivityRecord.forToken(token);
12491             if (srec == null) {
12492                 return false;
12493             }
12494             ArrayList<ActivityRecord> history = srec.stack.mHistory;
12495             final int start = history.indexOf(srec);
12496             if (start < 0) {
12497                 // Current activity is not in history stack; do nothing.
12498                 return false;
12499             }
12500             int finishTo = start - 1;
12501             ActivityRecord parent = null;
12502             boolean foundParentInTask = false;
12503             if (dest != null) {
12504                 TaskRecord tr = srec.task;
12505                 for (int i = start - 1; i >= 0; i--) {
12506                     ActivityRecord r = history.get(i);
12507                     if (tr != r.task) {
12508                         // Couldn't find parent in the same task; stop at the one above this.
12509                         // (Root of current task; in-app "home" behavior)
12510                         // Always at least finish the current activity.
12511                         finishTo = Math.min(start - 1, i + 1);
12512                         parent = history.get(finishTo);
12513                         break;
12514                     } else if (r.info.packageName.equals(dest.getPackageName()) &&
12515                             r.info.name.equals(dest.getClassName())) {
12516                         finishTo = i;
12517                         parent = r;
12518                         foundParentInTask = true;
12519                         break;
12520                     }
12521                 }
12522             }
12523
12524             if (mController != null) {
12525                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12526                 if (next != null) {
12527                     // ask watcher if this is allowed
12528                     boolean resumeOK = true;
12529                     try {
12530                         resumeOK = mController.activityResuming(next.packageName);
12531                     } catch (RemoteException e) {
12532                         mController = null;
12533                     }
12534
12535                     if (!resumeOK) {
12536                         return false;
12537                     }
12538                 }
12539             }
12540             final long origId = Binder.clearCallingIdentity();
12541             for (int i = start; i > finishTo; i--) {
12542                 ActivityRecord r = history.get(i);
12543                 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12544                         "navigate-up", true);
12545                 // Only return the supplied result for the first activity finished
12546                 resultCode = Activity.RESULT_CANCELED;
12547                 resultData = null;
12548             }
12549
12550             if (parent != null && foundParentInTask) {
12551                 final int parentLaunchMode = parent.info.launchMode;
12552                 final int destIntentFlags = destIntent.getFlags();
12553                 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12554                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12555                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12556                         (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12557                     parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12558                 } else {
12559                     try {
12560                         ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12561                                 destIntent.getComponent(), 0, srec.userId);
12562                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12563                                 null, aInfo, parent.appToken, null,
12564                                 0, -1, parent.launchedFromUid, 0, null, true, null);
12565                         foundParentInTask = res == ActivityManager.START_SUCCESS;
12566                     } catch (RemoteException e) {
12567                         foundParentInTask = false;
12568                     }
12569                     mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12570                             resultData, "navigate-up", true);
12571                 }
12572             }
12573             Binder.restoreCallingIdentity(origId);
12574             return foundParentInTask;
12575         }
12576     }
12577
12578     public int getLaunchedFromUid(IBinder activityToken) {
12579         ActivityRecord srec = ActivityRecord.forToken(activityToken);
12580         if (srec == null) {
12581             return -1;
12582         }
12583         return srec.launchedFromUid;
12584     }
12585
12586     // =========================================================
12587     // LIFETIME MANAGEMENT
12588     // =========================================================
12589
12590     // Returns which broadcast queue the app is the current [or imminent] receiver
12591     // on, or 'null' if the app is not an active broadcast recipient.
12592     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12593         BroadcastRecord r = app.curReceiver;
12594         if (r != null) {
12595             return r.queue;
12596         }
12597
12598         // It's not the current receiver, but it might be starting up to become one
12599         synchronized (this) {
12600             for (BroadcastQueue queue : mBroadcastQueues) {
12601                 r = queue.mPendingBroadcast;
12602                 if (r != null && r.curApp == app) {
12603                     // found it; report which queue it's in
12604                     return queue;
12605                 }
12606             }
12607         }
12608
12609         return null;
12610     }
12611
12612     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12613             int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12614         if (mAdjSeq == app.adjSeq) {
12615             // This adjustment has already been computed.  If we are calling
12616             // from the top, we may have already computed our adjustment with
12617             // an earlier hidden adjustment that isn't really for us... if
12618             // so, use the new hidden adjustment.
12619             if (!recursed && app.hidden) {
12620                 if (app.hasActivities) {
12621                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12622                 } else if (app.hasClientActivities) {
12623                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12624                 } else {
12625                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12626                 }
12627             }
12628             return app.curRawAdj;
12629         }
12630
12631         if (app.thread == null) {
12632             app.adjSeq = mAdjSeq;
12633             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12634             return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12635         }
12636
12637         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12638         app.adjSource = null;
12639         app.adjTarget = null;
12640         app.empty = false;
12641         app.hidden = false;
12642         app.hasClientActivities = false;
12643
12644         final int activitiesSize = app.activities.size();
12645
12646         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12647             // The max adjustment doesn't allow this app to be anything
12648             // below foreground, so it is not worth doing work for it.
12649             app.adjType = "fixed";
12650             app.adjSeq = mAdjSeq;
12651             app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12652             app.hasActivities = false;
12653             app.foregroundActivities = false;
12654             app.keeping = true;
12655             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12656             // System process can do UI, and when they do we want to have
12657             // them trim their memory after the user leaves the UI.  To
12658             // facilitate this, here we need to determine whether or not it
12659             // is currently showing UI.
12660             app.systemNoUi = true;
12661             if (app == TOP_APP) {
12662                 app.systemNoUi = false;
12663                 app.hasActivities = true;
12664             } else if (activitiesSize > 0) {
12665                 for (int j = 0; j < activitiesSize; j++) {
12666                     final ActivityRecord r = app.activities.get(j);
12667                     if (r.visible) {
12668                         app.systemNoUi = false;
12669                     }
12670                     if (r.app == app) {
12671                         app.hasActivities = true;
12672                     }
12673                 }
12674             }
12675             return (app.curAdj=app.maxAdj);
12676         }
12677
12678         app.keeping = false;
12679         app.systemNoUi = false;
12680         app.hasActivities = false;
12681
12682         // Determine the importance of the process, starting with most
12683         // important to least, and assign an appropriate OOM adjustment.
12684         int adj;
12685         int schedGroup;
12686         boolean foregroundActivities = false;
12687         boolean interesting = false;
12688         BroadcastQueue queue;
12689         if (app == TOP_APP) {
12690             // The last app on the list is the foreground app.
12691             adj = ProcessList.FOREGROUND_APP_ADJ;
12692             schedGroup = Process.THREAD_GROUP_DEFAULT;
12693             app.adjType = "top-activity";
12694             foregroundActivities = true;
12695             interesting = true;
12696             app.hasActivities = true;
12697         } else if (app.instrumentationClass != null) {
12698             // Don't want to kill running instrumentation.
12699             adj = ProcessList.FOREGROUND_APP_ADJ;
12700             schedGroup = Process.THREAD_GROUP_DEFAULT;
12701             app.adjType = "instrumentation";
12702             interesting = true;
12703         } else if ((queue = isReceivingBroadcast(app)) != null) {
12704             // An app that is currently receiving a broadcast also
12705             // counts as being in the foreground for OOM killer purposes.
12706             // It's placed in a sched group based on the nature of the
12707             // broadcast as reflected by which queue it's active in.
12708             adj = ProcessList.FOREGROUND_APP_ADJ;
12709             schedGroup = (queue == mFgBroadcastQueue)
12710                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12711             app.adjType = "broadcast";
12712         } else if (app.executingServices.size() > 0) {
12713             // An app that is currently executing a service callback also
12714             // counts as being in the foreground.
12715             adj = ProcessList.FOREGROUND_APP_ADJ;
12716             schedGroup = Process.THREAD_GROUP_DEFAULT;
12717             app.adjType = "exec-service";
12718         } else {
12719             // Assume process is hidden (has activities); we will correct
12720             // later if this is not the case.
12721             adj = hiddenAdj;
12722             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12723             app.hidden = true;
12724             app.adjType = "bg-act";
12725         }
12726
12727         boolean hasStoppingActivities = false;
12728
12729         // Examine all activities if not already foreground.
12730         if (!foregroundActivities && activitiesSize > 0) {
12731             for (int j = 0; j < activitiesSize; j++) {
12732                 final ActivityRecord r = app.activities.get(j);
12733                 if (r.visible) {
12734                     // App has a visible activity; only upgrade adjustment.
12735                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
12736                         adj = ProcessList.VISIBLE_APP_ADJ;
12737                         app.adjType = "visible";
12738                     }
12739                     schedGroup = Process.THREAD_GROUP_DEFAULT;
12740                     app.hidden = false;
12741                     app.hasActivities = true;
12742                     foregroundActivities = true;
12743                     break;
12744                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12745                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12746                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12747                         app.adjType = "pausing";
12748                     }
12749                     app.hidden = false;
12750                     foregroundActivities = true;
12751                 } else if (r.state == ActivityState.STOPPING) {
12752                     // We will apply the actual adjustment later, because
12753                     // we want to allow this process to immediately go through
12754                     // any memory trimming that is in effect.
12755                     app.hidden = false;
12756                     foregroundActivities = true;
12757                     hasStoppingActivities = true;
12758                 }
12759                 if (r.app == app) {
12760                     app.hasActivities = true;
12761                 }
12762             }
12763         }
12764
12765         if (adj == hiddenAdj && !app.hasActivities) {
12766             if (app.hasClientActivities) {
12767                 adj = clientHiddenAdj;
12768                 app.adjType = "bg-client-act";
12769             } else {
12770                 // Whoops, this process is completely empty as far as we know
12771                 // at this point.
12772                 adj = emptyAdj;
12773                 app.empty = true;
12774                 app.adjType = "bg-empty";
12775             }
12776         }
12777
12778         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12779             if (app.foregroundServices) {
12780                 // The user is aware of this app, so make it visible.
12781                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12782                 app.hidden = false;
12783                 app.adjType = "fg-service";
12784                 schedGroup = Process.THREAD_GROUP_DEFAULT;
12785             } else if (app.forcingToForeground != null) {
12786                 // The user is aware of this app, so make it visible.
12787                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12788                 app.hidden = false;
12789                 app.adjType = "force-fg";
12790                 app.adjSource = app.forcingToForeground;
12791                 schedGroup = Process.THREAD_GROUP_DEFAULT;
12792             }
12793         }
12794
12795         if (app.foregroundServices) {
12796             interesting = true;
12797         }
12798
12799         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12800             // We don't want to kill the current heavy-weight process.
12801             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12802             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12803             app.hidden = false;
12804             app.adjType = "heavy";
12805         }
12806
12807         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12808             // This process is hosting what we currently consider to be the
12809             // home app, so we don't want to let it go into the background.
12810             adj = ProcessList.HOME_APP_ADJ;
12811             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12812             app.hidden = false;
12813             app.adjType = "home";
12814         }
12815
12816         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12817                 && app.activities.size() > 0) {
12818             // This was the previous process that showed UI to the user.
12819             // We want to try to keep it around more aggressively, to give
12820             // a good experience around switching between two apps.
12821             adj = ProcessList.PREVIOUS_APP_ADJ;
12822             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12823             app.hidden = false;
12824             app.adjType = "previous";
12825         }
12826
12827         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12828                 + " reason=" + app.adjType);
12829
12830         // By default, we use the computed adjustment.  It may be changed if
12831         // there are applications dependent on our services or providers, but
12832         // this gives us a baseline and makes sure we don't get into an
12833         // infinite recursion.
12834         app.adjSeq = mAdjSeq;
12835         app.curRawAdj = app.nonStoppingAdj = adj;
12836
12837         if (mBackupTarget != null && app == mBackupTarget.app) {
12838             // If possible we want to avoid killing apps while they're being backed up
12839             if (adj > ProcessList.BACKUP_APP_ADJ) {
12840                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12841                 adj = ProcessList.BACKUP_APP_ADJ;
12842                 app.adjType = "backup";
12843                 app.hidden = false;
12844             }
12845         }
12846
12847         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12848                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12849             final long now = SystemClock.uptimeMillis();
12850             // This process is more important if the top activity is
12851             // bound to the service.
12852             Iterator<ServiceRecord> jt = app.services.iterator();
12853             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12854                 ServiceRecord s = jt.next();
12855                 if (s.startRequested) {
12856                     if (app.hasShownUi && app != mHomeProcess) {
12857                         // If this process has shown some UI, let it immediately
12858                         // go to the LRU list because it may be pretty heavy with
12859                         // UI stuff.  We'll tag it with a label just to help
12860                         // debug and understand what is going on.
12861                         if (adj > ProcessList.SERVICE_ADJ) {
12862                             app.adjType = "started-bg-ui-services";
12863                         }
12864                     } else {
12865                         if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12866                             // This service has seen some activity within
12867                             // recent memory, so we will keep its process ahead
12868                             // of the background processes.
12869                             if (adj > ProcessList.SERVICE_ADJ) {
12870                                 adj = ProcessList.SERVICE_ADJ;
12871                                 app.adjType = "started-services";
12872                                 app.hidden = false;
12873                             }
12874                         }
12875                         // If we have let the service slide into the background
12876                         // state, still have some text describing what it is doing
12877                         // even though the service no longer has an impact.
12878                         if (adj > ProcessList.SERVICE_ADJ) {
12879                             app.adjType = "started-bg-services";
12880                         }
12881                     }
12882                     // Don't kill this process because it is doing work; it
12883                     // has said it is doing work.
12884                     app.keeping = true;
12885                 }
12886                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12887                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12888                     Iterator<ArrayList<ConnectionRecord>> kt
12889                             = s.connections.values().iterator();
12890                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12891                         ArrayList<ConnectionRecord> clist = kt.next();
12892                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12893                             // XXX should compute this based on the max of
12894                             // all connected clients.
12895                             ConnectionRecord cr = clist.get(i);
12896                             if (cr.binding.client == app) {
12897                                 // Binding to ourself is not interesting.
12898                                 continue;
12899                             }
12900                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12901                                 ProcessRecord client = cr.binding.client;
12902                                 int clientAdj = adj;
12903                                 int myHiddenAdj = hiddenAdj;
12904                                 if (myHiddenAdj > client.hiddenAdj) {
12905                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12906                                         myHiddenAdj = client.hiddenAdj;
12907                                     } else {
12908                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12909                                     }
12910                                 }
12911                                 int myClientHiddenAdj = clientHiddenAdj;
12912                                 if (myClientHiddenAdj > client.clientHiddenAdj) {
12913                                     if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12914                                         myClientHiddenAdj = client.clientHiddenAdj;
12915                                     } else {
12916                                         myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12917                                     }
12918                                 }
12919                                 int myEmptyAdj = emptyAdj;
12920                                 if (myEmptyAdj > client.emptyAdj) {
12921                                     if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12922                                         myEmptyAdj = client.emptyAdj;
12923                                     } else {
12924                                         myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12925                                     }
12926                                 }
12927                                 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12928                                         myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12929                                 String adjType = null;
12930                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12931                                     // Not doing bind OOM management, so treat
12932                                     // this guy more like a started service.
12933                                     if (app.hasShownUi && app != mHomeProcess) {
12934                                         // If this process has shown some UI, let it immediately
12935                                         // go to the LRU list because it may be pretty heavy with
12936                                         // UI stuff.  We'll tag it with a label just to help
12937                                         // debug and understand what is going on.
12938                                         if (adj > clientAdj) {
12939                                             adjType = "bound-bg-ui-services";
12940                                         }
12941                                         app.hidden = false;
12942                                         clientAdj = adj;
12943                                     } else {
12944                                         if (now >= (s.lastActivity
12945                                                 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12946                                             // This service has not seen activity within
12947                                             // recent memory, so allow it to drop to the
12948                                             // LRU list if there is no other reason to keep
12949                                             // it around.  We'll also tag it with a label just
12950                                             // to help debug and undertand what is going on.
12951                                             if (adj > clientAdj) {
12952                                                 adjType = "bound-bg-services";
12953                                             }
12954                                             clientAdj = adj;
12955                                         }
12956                                     }
12957                                 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12958                                     if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12959                                         // If this connection is keeping the service
12960                                         // created, then we want to try to better follow
12961                                         // its memory management semantics for activities.
12962                                         // That is, if it is sitting in the background
12963                                         // LRU list as a hidden process (with activities),
12964                                         // we don't want the service it is connected to
12965                                         // to go into the empty LRU and quickly get killed,
12966                                         // because I'll we'll do is just end up restarting
12967                                         // the service.
12968                                         app.hasClientActivities |= client.hasActivities;
12969                                     }
12970                                 }
12971                                 if (adj > clientAdj) {
12972                                     // If this process has recently shown UI, and
12973                                     // the process that is binding to it is less
12974                                     // important than being visible, then we don't
12975                                     // care about the binding as much as we care
12976                                     // about letting this process get into the LRU
12977                                     // list to be killed and restarted if needed for
12978                                     // memory.
12979                                     if (app.hasShownUi && app != mHomeProcess
12980                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12981                                         adjType = "bound-bg-ui-services";
12982                                     } else {
12983                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12984                                                 |Context.BIND_IMPORTANT)) != 0) {
12985                                             adj = clientAdj;
12986                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12987                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12988                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12989                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12990                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12991                                             adj = clientAdj;
12992                                         } else {
12993                                             app.pendingUiClean = true;
12994                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
12995                                                 adj = ProcessList.VISIBLE_APP_ADJ;
12996                                             }
12997                                         }
12998                                         if (!client.hidden) {
12999                                             app.hidden = false;
13000                                         }
13001                                         if (client.keeping) {
13002                                             app.keeping = true;
13003                                         }
13004                                         adjType = "service";
13005                                     }
13006                                 }
13007                                 if (adjType != null) {
13008                                     app.adjType = adjType;
13009                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13010                                             .REASON_SERVICE_IN_USE;
13011                                     app.adjSource = cr.binding.client;
13012                                     app.adjSourceOom = clientAdj;
13013                                     app.adjTarget = s.name;
13014                                 }
13015                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13016                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13017                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13018                                     }
13019                                 }
13020                             }
13021                             final ActivityRecord a = cr.activity;
13022                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13023                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
13024                                         (a.visible || a.state == ActivityState.RESUMED
13025                                          || a.state == ActivityState.PAUSING)) {
13026                                     adj = ProcessList.FOREGROUND_APP_ADJ;
13027                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13028                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13029                                     }
13030                                     app.hidden = false;
13031                                     app.adjType = "service";
13032                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13033                                             .REASON_SERVICE_IN_USE;
13034                                     app.adjSource = a;
13035                                     app.adjSourceOom = adj;
13036                                     app.adjTarget = s.name;
13037                                 }
13038                             }
13039                         }
13040                     }
13041                 }
13042             }
13043             
13044             // Finally, if this process has active services running in it, we
13045             // would like to avoid killing it unless it would prevent the current
13046             // application from running.  By default we put the process in
13047             // with the rest of the background processes; as we scan through
13048             // its services we may bump it up from there.
13049             if (adj > hiddenAdj) {
13050                 adj = hiddenAdj;
13051                 app.hidden = false;
13052                 app.adjType = "bg-services";
13053             }
13054         }
13055
13056         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13057                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13058             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13059             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13060                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13061                 ContentProviderRecord cpr = jt.next();
13062                 for (int i = cpr.connections.size()-1;
13063                         i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13064                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
13065                         i--) {
13066                     ContentProviderConnection conn = cpr.connections.get(i);
13067                     ProcessRecord client = conn.client;
13068                     if (client == app) {
13069                         // Being our own client is not interesting.
13070                         continue;
13071                     }
13072                     int myHiddenAdj = hiddenAdj;
13073                     if (myHiddenAdj > client.hiddenAdj) {
13074                         if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13075                             myHiddenAdj = client.hiddenAdj;
13076                         } else {
13077                             myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13078                         }
13079                     }
13080                     int myClientHiddenAdj = clientHiddenAdj;
13081                     if (myClientHiddenAdj > client.clientHiddenAdj) {
13082                         if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13083                             myClientHiddenAdj = client.clientHiddenAdj;
13084                         } else {
13085                             myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13086                         }
13087                     }
13088                     int myEmptyAdj = emptyAdj;
13089                     if (myEmptyAdj > client.emptyAdj) {
13090                         if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13091                             myEmptyAdj = client.emptyAdj;
13092                         } else {
13093                             myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13094                         }
13095                     }
13096                     int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13097                             myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13098                     if (adj > clientAdj) {
13099                         if (app.hasShownUi && app != mHomeProcess
13100                                 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13101                             app.adjType = "bg-ui-provider";
13102                         } else {
13103                             adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13104                                     ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13105                             app.adjType = "provider";
13106                         }
13107                         if (!client.hidden) {
13108                             app.hidden = false;
13109                         }
13110                         if (client.keeping) {
13111                             app.keeping = true;
13112                         }
13113                         app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13114                                 .REASON_PROVIDER_IN_USE;
13115                         app.adjSource = client;
13116                         app.adjSourceOom = clientAdj;
13117                         app.adjTarget = cpr.name;
13118                     }
13119                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13120                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13121                     }
13122                 }
13123                 // If the provider has external (non-framework) process
13124                 // dependencies, ensure that its adjustment is at least
13125                 // FOREGROUND_APP_ADJ.
13126                 if (cpr.hasExternalProcessHandles()) {
13127                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13128                         adj = ProcessList.FOREGROUND_APP_ADJ;
13129                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13130                         app.hidden = false;
13131                         app.keeping = true;
13132                         app.adjType = "provider";
13133                         app.adjTarget = cpr.name;
13134                     }
13135                 }
13136             }
13137         }
13138
13139         if (adj == ProcessList.SERVICE_ADJ) {
13140             if (doingAll) {
13141                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13142                 mNewNumServiceProcs++;
13143             }
13144             if (app.serviceb) {
13145                 adj = ProcessList.SERVICE_B_ADJ;
13146             }
13147         } else {
13148             app.serviceb = false;
13149         }
13150
13151         app.nonStoppingAdj = adj;
13152
13153         if (hasStoppingActivities) {
13154             // Only upgrade adjustment.
13155             if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13156                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13157                 app.adjType = "stopping";
13158             }
13159         }
13160
13161         app.curRawAdj = adj;
13162         
13163         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13164         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13165         if (adj > app.maxAdj) {
13166             adj = app.maxAdj;
13167             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13168                 schedGroup = Process.THREAD_GROUP_DEFAULT;
13169             }
13170         }
13171         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13172             app.keeping = true;
13173         }
13174
13175         if (app.hasAboveClient) {
13176             // If this process has bound to any services with BIND_ABOVE_CLIENT,
13177             // then we need to drop its adjustment to be lower than the service's
13178             // in order to honor the request.  We want to drop it by one adjustment
13179             // level...  but there is special meaning applied to various levels so
13180             // we will skip some of them.
13181             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13182                 // System process will not get dropped, ever
13183             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13184                 adj = ProcessList.VISIBLE_APP_ADJ;
13185             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13186                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13187             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13188                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13189             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13190                 adj++;
13191             }
13192         }
13193
13194         int importance = app.memImportance;
13195         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13196             app.curAdj = adj;
13197             app.curSchedGroup = schedGroup;
13198             if (!interesting) {
13199                 // For this reporting, if there is not something explicitly
13200                 // interesting in this process then we will push it to the
13201                 // background importance.
13202                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13203             } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13204                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13205             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13206                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13207             } else if (adj >= ProcessList.HOME_APP_ADJ) {
13208                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13209             } else if (adj >= ProcessList.SERVICE_ADJ) {
13210                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13211             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13212                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13213             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13214                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13215             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13216                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13217             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13218                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13219             } else {
13220                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13221             }
13222         }
13223
13224         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13225         if (foregroundActivities != app.foregroundActivities) {
13226             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13227         }
13228         if (changes != 0) {
13229             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13230             app.memImportance = importance;
13231             app.foregroundActivities = foregroundActivities;
13232             int i = mPendingProcessChanges.size()-1;
13233             ProcessChangeItem item = null;
13234             while (i >= 0) {
13235                 item = mPendingProcessChanges.get(i);
13236                 if (item.pid == app.pid) {
13237                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13238                     break;
13239                 }
13240                 i--;
13241             }
13242             if (i < 0) {
13243                 // No existing item in pending changes; need a new one.
13244                 final int NA = mAvailProcessChanges.size();
13245                 if (NA > 0) {
13246                     item = mAvailProcessChanges.remove(NA-1);
13247                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13248                 } else {
13249                     item = new ProcessChangeItem();
13250                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13251                 }
13252                 item.changes = 0;
13253                 item.pid = app.pid;
13254                 item.uid = app.info.uid;
13255                 if (mPendingProcessChanges.size() == 0) {
13256                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13257                             "*** Enqueueing dispatch processes changed!");
13258                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13259                 }
13260                 mPendingProcessChanges.add(item);
13261             }
13262             item.changes |= changes;
13263             item.importance = importance;
13264             item.foregroundActivities = foregroundActivities;
13265             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13266                     + Integer.toHexString(System.identityHashCode(item))
13267                     + " " + app.toShortString() + ": changes=" + item.changes
13268                     + " importance=" + item.importance
13269                     + " foreground=" + item.foregroundActivities
13270                     + " type=" + app.adjType + " source=" + app.adjSource
13271                     + " target=" + app.adjTarget);
13272         }
13273
13274         return app.curRawAdj;
13275     }
13276
13277     /**
13278      * Ask a given process to GC right now.
13279      */
13280     final void performAppGcLocked(ProcessRecord app) {
13281         try {
13282             app.lastRequestedGc = SystemClock.uptimeMillis();
13283             if (app.thread != null) {
13284                 if (app.reportLowMemory) {
13285                     app.reportLowMemory = false;
13286                     app.thread.scheduleLowMemory();
13287                 } else {
13288                     app.thread.processInBackground();
13289                 }
13290             }
13291         } catch (Exception e) {
13292             // whatever.
13293         }
13294     }
13295     
13296     /**
13297      * Returns true if things are idle enough to perform GCs.
13298      */
13299     private final boolean canGcNowLocked() {
13300         boolean processingBroadcasts = false;
13301         for (BroadcastQueue q : mBroadcastQueues) {
13302             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13303                 processingBroadcasts = true;
13304             }
13305         }
13306         return !processingBroadcasts
13307                 && (mSleeping || (mMainStack.mResumedActivity != null &&
13308                         mMainStack.mResumedActivity.idle));
13309     }
13310     
13311     /**
13312      * Perform GCs on all processes that are waiting for it, but only
13313      * if things are idle.
13314      */
13315     final void performAppGcsLocked() {
13316         final int N = mProcessesToGc.size();
13317         if (N <= 0) {
13318             return;
13319         }
13320         if (canGcNowLocked()) {
13321             while (mProcessesToGc.size() > 0) {
13322                 ProcessRecord proc = mProcessesToGc.remove(0);
13323                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13324                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13325                             <= SystemClock.uptimeMillis()) {
13326                         // To avoid spamming the system, we will GC processes one
13327                         // at a time, waiting a few seconds between each.
13328                         performAppGcLocked(proc);
13329                         scheduleAppGcsLocked();
13330                         return;
13331                     } else {
13332                         // It hasn't been long enough since we last GCed this
13333                         // process...  put it in the list to wait for its time.
13334                         addProcessToGcListLocked(proc);
13335                         break;
13336                     }
13337                 }
13338             }
13339             
13340             scheduleAppGcsLocked();
13341         }
13342     }
13343     
13344     /**
13345      * If all looks good, perform GCs on all processes waiting for them.
13346      */
13347     final void performAppGcsIfAppropriateLocked() {
13348         if (canGcNowLocked()) {
13349             performAppGcsLocked();
13350             return;
13351         }
13352         // Still not idle, wait some more.
13353         scheduleAppGcsLocked();
13354     }
13355
13356     /**
13357      * Schedule the execution of all pending app GCs.
13358      */
13359     final void scheduleAppGcsLocked() {
13360         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13361         
13362         if (mProcessesToGc.size() > 0) {
13363             // Schedule a GC for the time to the next process.
13364             ProcessRecord proc = mProcessesToGc.get(0);
13365             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13366             
13367             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13368             long now = SystemClock.uptimeMillis();
13369             if (when < (now+GC_TIMEOUT)) {
13370                 when = now + GC_TIMEOUT;
13371             }
13372             mHandler.sendMessageAtTime(msg, when);
13373         }
13374     }
13375     
13376     /**
13377      * Add a process to the array of processes waiting to be GCed.  Keeps the
13378      * list in sorted order by the last GC time.  The process can't already be
13379      * on the list.
13380      */
13381     final void addProcessToGcListLocked(ProcessRecord proc) {
13382         boolean added = false;
13383         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13384             if (mProcessesToGc.get(i).lastRequestedGc <
13385                     proc.lastRequestedGc) {
13386                 added = true;
13387                 mProcessesToGc.add(i+1, proc);
13388                 break;
13389             }
13390         }
13391         if (!added) {
13392             mProcessesToGc.add(0, proc);
13393         }
13394     }
13395     
13396     /**
13397      * Set up to ask a process to GC itself.  This will either do it
13398      * immediately, or put it on the list of processes to gc the next
13399      * time things are idle.
13400      */
13401     final void scheduleAppGcLocked(ProcessRecord app) {
13402         long now = SystemClock.uptimeMillis();
13403         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13404             return;
13405         }
13406         if (!mProcessesToGc.contains(app)) {
13407             addProcessToGcListLocked(app);
13408             scheduleAppGcsLocked();
13409         }
13410     }
13411
13412     final void checkExcessivePowerUsageLocked(boolean doKills) {
13413         updateCpuStatsNow();
13414
13415         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13416         boolean doWakeKills = doKills;
13417         boolean doCpuKills = doKills;
13418         if (mLastPowerCheckRealtime == 0) {
13419             doWakeKills = false;
13420         }
13421         if (mLastPowerCheckUptime == 0) {
13422             doCpuKills = false;
13423         }
13424         if (stats.isScreenOn()) {
13425             doWakeKills = false;
13426         }
13427         final long curRealtime = SystemClock.elapsedRealtime();
13428         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13429         final long curUptime = SystemClock.uptimeMillis();
13430         final long uptimeSince = curUptime - mLastPowerCheckUptime;
13431         mLastPowerCheckRealtime = curRealtime;
13432         mLastPowerCheckUptime = curUptime;
13433         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13434             doWakeKills = false;
13435         }
13436         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13437             doCpuKills = false;
13438         }
13439         int i = mLruProcesses.size();
13440         while (i > 0) {
13441             i--;
13442             ProcessRecord app = mLruProcesses.get(i);
13443             if (!app.keeping) {
13444                 long wtime;
13445                 synchronized (stats) {
13446                     wtime = stats.getProcessWakeTime(app.info.uid,
13447                             app.pid, curRealtime);
13448                 }
13449                 long wtimeUsed = wtime - app.lastWakeTime;
13450                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13451                 if (DEBUG_POWER) {
13452                     StringBuilder sb = new StringBuilder(128);
13453                     sb.append("Wake for ");
13454                     app.toShortString(sb);
13455                     sb.append(": over ");
13456                     TimeUtils.formatDuration(realtimeSince, sb);
13457                     sb.append(" used ");
13458                     TimeUtils.formatDuration(wtimeUsed, sb);
13459                     sb.append(" (");
13460                     sb.append((wtimeUsed*100)/realtimeSince);
13461                     sb.append("%)");
13462                     Slog.i(TAG, sb.toString());
13463                     sb.setLength(0);
13464                     sb.append("CPU for ");
13465                     app.toShortString(sb);
13466                     sb.append(": over ");
13467                     TimeUtils.formatDuration(uptimeSince, sb);
13468                     sb.append(" used ");
13469                     TimeUtils.formatDuration(cputimeUsed, sb);
13470                     sb.append(" (");
13471                     sb.append((cputimeUsed*100)/uptimeSince);
13472                     sb.append("%)");
13473                     Slog.i(TAG, sb.toString());
13474                 }
13475                 // If a process has held a wake lock for more
13476                 // than 50% of the time during this period,
13477                 // that sounds bad.  Kill!
13478                 if (doWakeKills && realtimeSince > 0
13479                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
13480                     synchronized (stats) {
13481                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13482                                 realtimeSince, wtimeUsed);
13483                     }
13484                     Slog.w(TAG, "Excessive wake lock in " + app.processName
13485                             + " (pid " + app.pid + "): held " + wtimeUsed
13486                             + " during " + realtimeSince);
13487                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13488                             app.processName, app.setAdj, "excessive wake lock");
13489                     Process.killProcessQuiet(app.pid);
13490                 } else if (doCpuKills && uptimeSince > 0
13491                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
13492                     synchronized (stats) {
13493                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13494                                 uptimeSince, cputimeUsed);
13495                     }
13496                     Slog.w(TAG, "Excessive CPU in " + app.processName
13497                             + " (pid " + app.pid + "): used " + cputimeUsed
13498                             + " during " + uptimeSince);
13499                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13500                             app.processName, app.setAdj, "excessive cpu");
13501                     Process.killProcessQuiet(app.pid);
13502                 } else {
13503                     app.lastWakeTime = wtime;
13504                     app.lastCpuTime = app.curCpuTime;
13505                 }
13506             }
13507         }
13508     }
13509
13510     private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13511             int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13512         app.hiddenAdj = hiddenAdj;
13513         app.clientHiddenAdj = clientHiddenAdj;
13514         app.emptyAdj = emptyAdj;
13515
13516         if (app.thread == null) {
13517             return false;
13518         }
13519
13520         final boolean wasKeeping = app.keeping;
13521
13522         boolean success = true;
13523
13524         computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13525
13526         if (app.curRawAdj != app.setRawAdj) {
13527             if (wasKeeping && !app.keeping) {
13528                 // This app is no longer something we want to keep.  Note
13529                 // its current wake lock time to later know to kill it if
13530                 // it is not behaving well.
13531                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13532                 synchronized (stats) {
13533                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13534                             app.pid, SystemClock.elapsedRealtime());
13535                 }
13536                 app.lastCpuTime = app.curCpuTime;
13537             }
13538
13539             app.setRawAdj = app.curRawAdj;
13540         }
13541
13542         if (app.curAdj != app.setAdj) {
13543             if (Process.setOomAdj(app.pid, app.curAdj)) {
13544                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13545                     TAG, "Set " + app.pid + " " + app.processName +
13546                     " adj " + app.curAdj + ": " + app.adjType);
13547                 app.setAdj = app.curAdj;
13548             } else {
13549                 success = false;
13550                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13551             }
13552         }
13553         if (app.setSchedGroup != app.curSchedGroup) {
13554             app.setSchedGroup = app.curSchedGroup;
13555             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13556                     "Setting process group of " + app.processName
13557                     + " to " + app.curSchedGroup);
13558             if (app.waitingToKill != null &&
13559                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13560                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13561                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13562                         app.processName, app.setAdj, app.waitingToKill);
13563                 app.killedBackground = true;
13564                 Process.killProcessQuiet(app.pid);
13565                 success = false;
13566             } else {
13567                 if (true) {
13568                     long oldId = Binder.clearCallingIdentity();
13569                     try {
13570                         Process.setProcessGroup(app.pid, app.curSchedGroup);
13571                     } catch (Exception e) {
13572                         Slog.w(TAG, "Failed setting process group of " + app.pid
13573                                 + " to " + app.curSchedGroup);
13574                         e.printStackTrace();
13575                     } finally {
13576                         Binder.restoreCallingIdentity(oldId);
13577                     }
13578                 } else {
13579                     if (app.thread != null) {
13580                         try {
13581                             app.thread.setSchedulingGroup(app.curSchedGroup);
13582                         } catch (RemoteException e) {
13583                         }
13584                     }
13585                 }
13586             }
13587         }
13588         return success;
13589     }
13590
13591     private final ActivityRecord resumedAppLocked() {
13592         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13593         if (resumedActivity == null || resumedActivity.app == null) {
13594             resumedActivity = mMainStack.mPausingActivity;
13595             if (resumedActivity == null || resumedActivity.app == null) {
13596                 resumedActivity = mMainStack.topRunningActivityLocked(null);
13597             }
13598         }
13599         return resumedActivity;
13600     }
13601
13602     final boolean updateOomAdjLocked(ProcessRecord app) {
13603         final ActivityRecord TOP_ACT = resumedAppLocked();
13604         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13605         int curAdj = app.curAdj;
13606         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13607             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13608
13609         mAdjSeq++;
13610
13611         boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13612                 app.emptyAdj, TOP_APP, false);
13613         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13614             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13615         if (nowHidden != wasHidden) {
13616             // Changed to/from hidden state, so apps after it in the LRU
13617             // list may also be changed.
13618             updateOomAdjLocked();
13619         }
13620         return success;
13621     }
13622
13623     final void updateOomAdjLocked() {
13624         final ActivityRecord TOP_ACT = resumedAppLocked();
13625         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13626         final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13627
13628         if (false) {
13629             RuntimeException e = new RuntimeException();
13630             e.fillInStackTrace();
13631             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13632         }
13633
13634         mAdjSeq++;
13635         mNewNumServiceProcs = 0;
13636
13637         final int emptyProcessLimit;
13638         final int hiddenProcessLimit;
13639         if (mProcessLimit <= 0) {
13640             emptyProcessLimit = hiddenProcessLimit = 0;
13641         } else if (mProcessLimit == 1) {
13642             emptyProcessLimit = 1;
13643             hiddenProcessLimit = 0;
13644         } else {
13645             emptyProcessLimit = (mProcessLimit*2)/3;
13646             hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13647         }
13648
13649         // Let's determine how many processes we have running vs.
13650         // how many slots we have for background processes; we may want
13651         // to put multiple processes in a slot of there are enough of
13652         // them.
13653         int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13654                 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13655         int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13656         if (numEmptyProcs > hiddenProcessLimit) {
13657             // If there are more empty processes than our limit on hidden
13658             // processes, then use the hidden process limit for the factor.
13659             // This ensures that the really old empty processes get pushed
13660             // down to the bottom, so if we are running low on memory we will
13661             // have a better chance at keeping around more hidden processes
13662             // instead of a gazillion empty processes.
13663             numEmptyProcs = hiddenProcessLimit;
13664         }
13665         int emptyFactor = numEmptyProcs/numSlots;
13666         if (emptyFactor < 1) emptyFactor = 1;
13667         int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13668         if (hiddenFactor < 1) hiddenFactor = 1;
13669         int stepHidden = 0;
13670         int stepEmpty = 0;
13671         int numHidden = 0;
13672         int numEmpty = 0;
13673         int numTrimming = 0;
13674
13675         mNumNonHiddenProcs = 0;
13676         mNumHiddenProcs = 0;
13677
13678         // First update the OOM adjustment for each of the
13679         // application processes based on their current state.
13680         int i = mLruProcesses.size();
13681         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13682         int nextHiddenAdj = curHiddenAdj+1;
13683         int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13684         int nextEmptyAdj = curEmptyAdj+2;
13685         int curClientHiddenAdj = curEmptyAdj;
13686         while (i > 0) {
13687             i--;
13688             ProcessRecord app = mLruProcesses.get(i);
13689             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13690             updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13691             if (!app.killedBackground) {
13692                 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13693                     // This process was assigned as a hidden process...  step the
13694                     // hidden level.
13695                     mNumHiddenProcs++;
13696                     if (curHiddenAdj != nextHiddenAdj) {
13697                         stepHidden++;
13698                         if (stepHidden >= hiddenFactor) {
13699                             stepHidden = 0;
13700                             curHiddenAdj = nextHiddenAdj;
13701                             nextHiddenAdj += 2;
13702                             if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13703                                 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13704                             }
13705                             if (curClientHiddenAdj <= curHiddenAdj) {
13706                                 curClientHiddenAdj = curHiddenAdj + 1;
13707                                 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13708                                     curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13709                                 }
13710                             }
13711                         }
13712                     }
13713                     numHidden++;
13714                     if (numHidden > hiddenProcessLimit) {
13715                         Slog.i(TAG, "No longer want " + app.processName
13716                                 + " (pid " + app.pid + "): hidden #" + numHidden);
13717                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13718                                 app.processName, app.setAdj, "too many background");
13719                         app.killedBackground = true;
13720                         Process.killProcessQuiet(app.pid);
13721                     }
13722                 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13723                     // This process has a client that has activities.  We will have
13724                     // given it the current hidden adj; here we will just leave it
13725                     // without stepping the hidden adj.
13726                     curClientHiddenAdj++;
13727                     if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13728                         curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13729                     }
13730                 } else {
13731                     if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13732                         // This process was assigned as an empty process...  step the
13733                         // empty level.
13734                         if (curEmptyAdj != nextEmptyAdj) {
13735                             stepEmpty++;
13736                             if (stepEmpty >= emptyFactor) {
13737                                 stepEmpty = 0;
13738                                 curEmptyAdj = nextEmptyAdj;
13739                                 nextEmptyAdj += 2;
13740                                 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13741                                     nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13742                                 }
13743                             }
13744                         }
13745                     } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13746                         mNumNonHiddenProcs++;
13747                     }
13748                     if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13749                             && !app.hasClientActivities) {
13750                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13751                                 && app.lastActivityTime < oldTime) {
13752                             Slog.i(TAG, "No longer want " + app.processName
13753                                     + " (pid " + app.pid + "): empty for "
13754                                     + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13755                                             / 1000) + "s");
13756                             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13757                                     app.processName, app.setAdj, "old background process");
13758                             app.killedBackground = true;
13759                             Process.killProcessQuiet(app.pid);
13760                         } else {
13761                             numEmpty++;
13762                             if (numEmpty > emptyProcessLimit) {
13763                                 Slog.i(TAG, "No longer want " + app.processName
13764                                         + " (pid " + app.pid + "): empty #" + numEmpty);
13765                                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13766                                         app.processName, app.setAdj, "too many background");
13767                                 app.killedBackground = true;
13768                                 Process.killProcessQuiet(app.pid);
13769                             }
13770                         }
13771                     }
13772                 }
13773                 if (app.isolated && app.services.size() <= 0) {
13774                     // If this is an isolated process, and there are no
13775                     // services running in it, then the process is no longer
13776                     // needed.  We agressively kill these because we can by
13777                     // definition not re-use the same process again, and it is
13778                     // good to avoid having whatever code was running in them
13779                     // left sitting around after no longer needed.
13780                     Slog.i(TAG, "Isolated process " + app.processName
13781                             + " (pid " + app.pid + ") no longer needed");
13782                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13783                             app.processName, app.setAdj, "isolated not needed");
13784                     app.killedBackground = true;
13785                     Process.killProcessQuiet(app.pid);
13786                 }
13787                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13788                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13789                         && !app.killedBackground) {
13790                     numTrimming++;
13791                 }
13792             }
13793         }
13794
13795         mNumServiceProcs = mNewNumServiceProcs;
13796
13797         // Now determine the memory trimming level of background processes.
13798         // Unfortunately we need to start at the back of the list to do this
13799         // properly.  We only do this if the number of background apps we
13800         // are managing to keep around is less than half the maximum we desire;
13801         // if we are keeping a good number around, we'll let them use whatever
13802         // memory they want.
13803         if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13804                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13805             final int numHiddenAndEmpty = numHidden + numEmpty;
13806             final int N = mLruProcesses.size();
13807             int factor = numTrimming/3;
13808             int minFactor = 2;
13809             if (mHomeProcess != null) minFactor++;
13810             if (mPreviousProcess != null) minFactor++;
13811             if (factor < minFactor) factor = minFactor;
13812             int step = 0;
13813             int fgTrimLevel;
13814             if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13815                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13816             } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13817                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13818             } else {
13819                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13820             }
13821             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13822             for (i=0; i<N; i++) {
13823                 ProcessRecord app = mLruProcesses.get(i);
13824                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13825                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13826                         && !app.killedBackground) {
13827                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
13828                         try {
13829                             app.thread.scheduleTrimMemory(curLevel);
13830                         } catch (RemoteException e) {
13831                         }
13832                         if (false) {
13833                             // For now we won't do this; our memory trimming seems
13834                             // to be good enough at this point that destroying
13835                             // activities causes more harm than good.
13836                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13837                                     && app != mHomeProcess && app != mPreviousProcess) {
13838                                 // Need to do this on its own message because the stack may not
13839                                 // be in a consistent state at this point.
13840                                 // For these apps we will also finish their activities
13841                                 // to help them free memory.
13842                                 mMainStack.scheduleDestroyActivities(app, false, "trim");
13843                             }
13844                         }
13845                     }
13846                     app.trimMemoryLevel = curLevel;
13847                     step++;
13848                     if (step >= factor) {
13849                         step = 0;
13850                         switch (curLevel) {
13851                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13852                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13853                                 break;
13854                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13855                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13856                                 break;
13857                         }
13858                     }
13859                 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13860                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13861                             && app.thread != null) {
13862                         try {
13863                             app.thread.scheduleTrimMemory(
13864                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13865                         } catch (RemoteException e) {
13866                         }
13867                     }
13868                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13869                 } else {
13870                     if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13871                             && app.pendingUiClean) {
13872                         // If this application is now in the background and it
13873                         // had done UI, then give it the special trim level to
13874                         // have it free UI resources.
13875                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13876                         if (app.trimMemoryLevel < level && app.thread != null) {
13877                             try {
13878                                 app.thread.scheduleTrimMemory(level);
13879                             } catch (RemoteException e) {
13880                             }
13881                         }
13882                         app.pendingUiClean = false;
13883                     }
13884                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13885                         try {
13886                             app.thread.scheduleTrimMemory(fgTrimLevel);
13887                         } catch (RemoteException e) {
13888                         }
13889                     }
13890                     app.trimMemoryLevel = fgTrimLevel;
13891                 }
13892             }
13893         } else {
13894             final int N = mLruProcesses.size();
13895             for (i=0; i<N; i++) {
13896                 ProcessRecord app = mLruProcesses.get(i);
13897                 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13898                         && app.pendingUiClean) {
13899                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13900                             && app.thread != null) {
13901                         try {
13902                             app.thread.scheduleTrimMemory(
13903                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13904                         } catch (RemoteException e) {
13905                         }
13906                     }
13907                     app.pendingUiClean = false;
13908                 }
13909                 app.trimMemoryLevel = 0;
13910             }
13911         }
13912
13913         if (mAlwaysFinishActivities) {
13914             // Need to do this on its own message because the stack may not
13915             // be in a consistent state at this point.
13916             mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13917         }
13918     }
13919
13920     final void trimApplications() {
13921         synchronized (this) {
13922             int i;
13923
13924             // First remove any unused application processes whose package
13925             // has been removed.
13926             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13927                 final ProcessRecord app = mRemovedProcesses.get(i);
13928                 if (app.activities.size() == 0
13929                         && app.curReceiver == null && app.services.size() == 0) {
13930                     Slog.i(
13931                         TAG, "Exiting empty application process "
13932                         + app.processName + " ("
13933                         + (app.thread != null ? app.thread.asBinder() : null)
13934                         + ")\n");
13935                     if (app.pid > 0 && app.pid != MY_PID) {
13936                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13937                                 app.processName, app.setAdj, "empty");
13938                         Process.killProcessQuiet(app.pid);
13939                     } else {
13940                         try {
13941                             app.thread.scheduleExit();
13942                         } catch (Exception e) {
13943                             // Ignore exceptions.
13944                         }
13945                     }
13946                     cleanUpApplicationRecordLocked(app, false, true, -1);
13947                     mRemovedProcesses.remove(i);
13948                     
13949                     if (app.persistent) {
13950                         if (app.persistent) {
13951                             addAppLocked(app.info, false);
13952                         }
13953                     }
13954                 }
13955             }
13956
13957             // Now update the oom adj for all processes.
13958             updateOomAdjLocked();
13959         }
13960     }
13961
13962     /** This method sends the specified signal to each of the persistent apps */
13963     public void signalPersistentProcesses(int sig) throws RemoteException {
13964         if (sig != Process.SIGNAL_USR1) {
13965             throw new SecurityException("Only SIGNAL_USR1 is allowed");
13966         }
13967
13968         synchronized (this) {
13969             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13970                     != PackageManager.PERMISSION_GRANTED) {
13971                 throw new SecurityException("Requires permission "
13972                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13973             }
13974
13975             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13976                 ProcessRecord r = mLruProcesses.get(i);
13977                 if (r.thread != null && r.persistent) {
13978                     Process.sendSignal(r.pid, sig);
13979                 }
13980             }
13981         }
13982     }
13983
13984     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13985         if (proc == null || proc == mProfileProc) {
13986             proc = mProfileProc;
13987             path = mProfileFile;
13988             profileType = mProfileType;
13989             clearProfilerLocked();
13990         }
13991         if (proc == null) {
13992             return;
13993         }
13994         try {
13995             proc.thread.profilerControl(false, path, null, profileType);
13996         } catch (RemoteException e) {
13997             throw new IllegalStateException("Process disappeared");
13998         }
13999     }
14000
14001     private void clearProfilerLocked() {
14002         if (mProfileFd != null) {
14003             try {
14004                 mProfileFd.close();
14005             } catch (IOException e) {
14006             }
14007         }
14008         mProfileApp = null;
14009         mProfileProc = null;
14010         mProfileFile = null;
14011         mProfileType = 0;
14012         mAutoStopProfiler = false;
14013     }
14014
14015     public boolean profileControl(String process, int userId, boolean start,
14016             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
14017
14018         try {
14019             synchronized (this) {
14020                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14021                 // its own permission.
14022                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14023                         != PackageManager.PERMISSION_GRANTED) {
14024                     throw new SecurityException("Requires permission "
14025                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14026                 }
14027
14028                 if (start && fd == null) {
14029                     throw new IllegalArgumentException("null fd");
14030                 }
14031
14032                 ProcessRecord proc = null;
14033                 if (process != null) {
14034                     proc = findProcessLocked(process, userId, "profileControl");
14035                 }
14036
14037                 if (start && (proc == null || proc.thread == null)) {
14038                     throw new IllegalArgumentException("Unknown process: " + process);
14039                 }
14040
14041                 if (start) {
14042                     stopProfilerLocked(null, null, 0);
14043                     setProfileApp(proc.info, proc.processName, path, fd, false);
14044                     mProfileProc = proc;
14045                     mProfileType = profileType;
14046                     try {
14047                         fd = fd.dup();
14048                     } catch (IOException e) {
14049                         fd = null;
14050                     }
14051                     proc.thread.profilerControl(start, path, fd, profileType);
14052                     fd = null;
14053                     mProfileFd = null;
14054                 } else {
14055                     stopProfilerLocked(proc, path, profileType);
14056                     if (fd != null) {
14057                         try {
14058                             fd.close();
14059                         } catch (IOException e) {
14060                         }
14061                     }
14062                 }
14063
14064                 return true;
14065             }
14066         } catch (RemoteException e) {
14067             throw new IllegalStateException("Process disappeared");
14068         } finally {
14069             if (fd != null) {
14070                 try {
14071                     fd.close();
14072                 } catch (IOException e) {
14073                 }
14074             }
14075         }
14076     }
14077
14078     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
14079         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14080                 userId, true, true, callName, null);
14081         ProcessRecord proc = null;
14082         try {
14083             int pid = Integer.parseInt(process);
14084             synchronized (mPidsSelfLocked) {
14085                 proc = mPidsSelfLocked.get(pid);
14086             }
14087         } catch (NumberFormatException e) {
14088         }
14089
14090         if (proc == null) {
14091             HashMap<String, SparseArray<ProcessRecord>> all
14092                     = mProcessNames.getMap();
14093             SparseArray<ProcessRecord> procs = all.get(process);
14094             if (procs != null && procs.size() > 0) {
14095                 proc = procs.valueAt(0);
14096                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14097                     for (int i=1; i<procs.size(); i++) {
14098                         ProcessRecord thisProc = procs.valueAt(i);
14099                         if (thisProc.userId == userId) {
14100                             proc = thisProc;
14101                             break;
14102                         }
14103                     }
14104                 }
14105             }
14106         }
14107
14108         return proc;
14109     }
14110
14111     public boolean dumpHeap(String process, int userId, boolean managed,
14112             String path, ParcelFileDescriptor fd) throws RemoteException {
14113
14114         try {
14115             synchronized (this) {
14116                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14117                 // its own permission (same as profileControl).
14118                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14119                         != PackageManager.PERMISSION_GRANTED) {
14120                     throw new SecurityException("Requires permission "
14121                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14122                 }
14123
14124                 if (fd == null) {
14125                     throw new IllegalArgumentException("null fd");
14126                 }
14127
14128                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14129                 if (proc == null || proc.thread == null) {
14130                     throw new IllegalArgumentException("Unknown process: " + process);
14131                 }
14132
14133                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14134                 if (!isDebuggable) {
14135                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14136                         throw new SecurityException("Process not debuggable: " + proc);
14137                     }
14138                 }
14139
14140                 proc.thread.dumpHeap(managed, path, fd);
14141                 fd = null;
14142                 return true;
14143             }
14144         } catch (RemoteException e) {
14145             throw new IllegalStateException("Process disappeared");
14146         } finally {
14147             if (fd != null) {
14148                 try {
14149                     fd.close();
14150                 } catch (IOException e) {
14151                 }
14152             }
14153         }
14154     }
14155
14156     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14157     public void monitor() {
14158         synchronized (this) { }
14159     }
14160
14161     void onCoreSettingsChange(Bundle settings) {
14162         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14163             ProcessRecord processRecord = mLruProcesses.get(i);
14164             try {
14165                 if (processRecord.thread != null) {
14166                     processRecord.thread.setCoreSettings(settings);
14167                 }
14168             } catch (RemoteException re) {
14169                 /* ignore */
14170             }
14171         }
14172     }
14173
14174     // Multi-user methods
14175
14176     @Override
14177     public boolean switchUser(final int userId) {
14178         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14179                 != PackageManager.PERMISSION_GRANTED) {
14180             String msg = "Permission Denial: switchUser() from pid="
14181                     + Binder.getCallingPid()
14182                     + ", uid=" + Binder.getCallingUid()
14183                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14184             Slog.w(TAG, msg);
14185             throw new SecurityException(msg);
14186         }
14187
14188         final long ident = Binder.clearCallingIdentity();
14189         try {
14190             synchronized (this) {
14191                 final int oldUserId = mCurrentUserId;
14192                 if (oldUserId == userId) {
14193                     return true;
14194                 }
14195
14196                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14197                 if (userInfo == null) {
14198                     Slog.w(TAG, "No user info for user #" + userId);
14199                     return false;
14200                 }
14201
14202                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14203                         R.anim.screen_user_enter);
14204
14205                 boolean needStart = false;
14206
14207                 // If the user we are switching to is not currently started, then
14208                 // we need to start it now.
14209                 if (mStartedUsers.get(userId) == null) {
14210                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14211                     updateStartedUserArrayLocked();
14212                     needStart = true;
14213                 }
14214
14215                 mCurrentUserId = userId;
14216                 mCurrentUserArray = new int[] { userId };
14217                 final Integer userIdInt = Integer.valueOf(userId);
14218                 mUserLru.remove(userIdInt);
14219                 mUserLru.add(userIdInt);
14220
14221                 mWindowManager.setCurrentUser(userId);
14222
14223                 // Once the internal notion of the active user has switched, we lock the device
14224                 // with the option to show the user switcher on the keyguard.
14225                 mWindowManager.lockNow(null);
14226
14227                 final UserStartedState uss = mStartedUsers.get(userId);
14228
14229                 // Make sure user is in the started state.  If it is currently
14230                 // stopping, we need to knock that off.
14231                 if (uss.mState == UserStartedState.STATE_STOPPING) {
14232                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14233                     // so we can just fairly silently bring the user back from
14234                     // the almost-dead.
14235                     uss.mState = UserStartedState.STATE_RUNNING;
14236                     updateStartedUserArrayLocked();
14237                     needStart = true;
14238                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14239                     // This means ACTION_SHUTDOWN has been sent, so we will
14240                     // need to treat this as a new boot of the user.
14241                     uss.mState = UserStartedState.STATE_BOOTING;
14242                     updateStartedUserArrayLocked();
14243                     needStart = true;
14244                 }
14245
14246                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14247                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14248                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14249                         oldUserId, userId, uss));
14250                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14251                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14252                 if (needStart) {
14253                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14254                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14255                             | Intent.FLAG_RECEIVER_FOREGROUND);
14256                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14257                     broadcastIntentLocked(null, null, intent,
14258                             null, null, 0, null, null, null,
14259                             false, false, MY_PID, Process.SYSTEM_UID, userId);
14260                 }
14261
14262                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14263                     if (userId != 0) {
14264                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14265                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14266                         broadcastIntentLocked(null, null, intent, null,
14267                                 new IIntentReceiver.Stub() {
14268                                     public void performReceive(Intent intent, int resultCode,
14269                                             String data, Bundle extras, boolean ordered,
14270                                             boolean sticky, int sendingUser) {
14271                                         userInitialized(uss, userId);
14272                                     }
14273                                 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14274                                 userId);
14275                         uss.initializing = true;
14276                     } else {
14277                         getUserManagerLocked().makeInitialized(userInfo.id);
14278                     }
14279                 }
14280
14281                 boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14282                 if (!haveActivities) {
14283                     startHomeActivityLocked(userId);
14284                 }
14285
14286                 EventLogTags.writeAmSwitchUser(userId);
14287                 getUserManagerLocked().userForeground(userId);
14288                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
14289                 if (needStart) {
14290                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14291                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14292                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14293                     broadcastIntentLocked(null, null, intent,
14294                             null, new IIntentReceiver.Stub() {
14295                                 @Override
14296                                 public void performReceive(Intent intent, int resultCode, String data,
14297                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14298                                         throws RemoteException {
14299                                 }
14300                             }, 0, null, null,
14301                             android.Manifest.permission.INTERACT_ACROSS_USERS,
14302                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14303                 }
14304             }
14305         } finally {
14306             Binder.restoreCallingIdentity(ident);
14307         }
14308
14309         return true;
14310     }
14311
14312     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14313         long ident = Binder.clearCallingIdentity();
14314         try {
14315             Intent intent;
14316             if (oldUserId >= 0) {
14317                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14318                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14319                         | Intent.FLAG_RECEIVER_FOREGROUND);
14320                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14321                 broadcastIntentLocked(null, null, intent,
14322                         null, null, 0, null, null, null,
14323                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14324             }
14325             if (newUserId >= 0) {
14326                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14327                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14328                         | Intent.FLAG_RECEIVER_FOREGROUND);
14329                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14330                 broadcastIntentLocked(null, null, intent,
14331                         null, null, 0, null, null, null,
14332                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14333                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
14334                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14335                         | Intent.FLAG_RECEIVER_FOREGROUND);
14336                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14337                 broadcastIntentLocked(null, null, intent,
14338                         null, null, 0, null, null,
14339                         android.Manifest.permission.MANAGE_USERS,
14340                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14341             }
14342         } finally {
14343             Binder.restoreCallingIdentity(ident);
14344         }
14345     }
14346
14347     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14348             final int newUserId) {
14349         final int N = mUserSwitchObservers.beginBroadcast();
14350         if (N > 0) {
14351             final IRemoteCallback callback = new IRemoteCallback.Stub() {
14352                 int mCount = 0;
14353                 @Override
14354                 public void sendResult(Bundle data) throws RemoteException {
14355                     synchronized (ActivityManagerService.this) {
14356                         if (mCurUserSwitchCallback == this) {
14357                             mCount++;
14358                             if (mCount == N) {
14359                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14360                             }
14361                         }
14362                     }
14363                 }
14364             };
14365             synchronized (this) {
14366                 uss.switching = true;
14367                 mCurUserSwitchCallback = callback;
14368             }
14369             for (int i=0; i<N; i++) {
14370                 try {
14371                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14372                             newUserId, callback);
14373                 } catch (RemoteException e) {
14374                 }
14375             }
14376         } else {
14377             synchronized (this) {
14378                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14379             }
14380         }
14381         mUserSwitchObservers.finishBroadcast();
14382     }
14383
14384     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14385         synchronized (this) {
14386             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14387             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14388         }
14389     }
14390
14391     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14392         mCurUserSwitchCallback = null;
14393         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14394         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14395                 oldUserId, newUserId, uss));
14396     }
14397
14398     void userInitialized(UserStartedState uss, int newUserId) {
14399         completeSwitchAndInitalize(uss, newUserId, true, false);
14400     }
14401
14402     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14403         completeSwitchAndInitalize(uss, newUserId, false, true);
14404     }
14405
14406     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
14407             boolean clearInitializing, boolean clearSwitching) {
14408         boolean unfrozen = false;
14409         synchronized (this) {
14410             if (clearInitializing) {
14411                 uss.initializing = false;
14412                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14413             }
14414             if (clearSwitching) {
14415                 uss.switching = false;
14416             }
14417             if (!uss.switching && !uss.initializing) {
14418                 mWindowManager.stopFreezingScreen();
14419                 unfrozen = true;
14420             }
14421         }
14422         if (unfrozen) {
14423             final int N = mUserSwitchObservers.beginBroadcast();
14424             for (int i=0; i<N; i++) {
14425                 try {
14426                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14427                 } catch (RemoteException e) {
14428                 }
14429             }
14430             mUserSwitchObservers.finishBroadcast();
14431         }
14432     }
14433
14434     void finishUserSwitch(UserStartedState uss) {
14435         synchronized (this) {
14436             if (uss.mState == UserStartedState.STATE_BOOTING
14437                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14438                 uss.mState = UserStartedState.STATE_RUNNING;
14439                 final int userId = uss.mHandle.getIdentifier();
14440                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14441                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14442                 broadcastIntentLocked(null, null, intent,
14443                         null, null, 0, null, null,
14444                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14445                         false, false, MY_PID, Process.SYSTEM_UID, userId);
14446             }
14447             int num = mUserLru.size();
14448             int i = 0;
14449             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14450                 Integer oldUserId = mUserLru.get(i);
14451                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
14452                 if (oldUss == null) {
14453                     // Shouldn't happen, but be sane if it does.
14454                     mUserLru.remove(i);
14455                     num--;
14456                     continue;
14457                 }
14458                 if (oldUss.mState == UserStartedState.STATE_STOPPING
14459                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14460                     // This user is already stopping, doesn't count.
14461                     num--;
14462                     i++;
14463                     continue;
14464                 }
14465                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14466                     // Owner and current can't be stopped, but count as running.
14467                     i++;
14468                     continue;
14469                 }
14470                 // This is a user to be stopped.
14471                 stopUserLocked(oldUserId, null);
14472                 num--;
14473                 i++;
14474             }
14475         }
14476     }
14477
14478     @Override
14479     public int stopUser(final int userId, final IStopUserCallback callback) {
14480         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14481                 != PackageManager.PERMISSION_GRANTED) {
14482             String msg = "Permission Denial: switchUser() from pid="
14483                     + Binder.getCallingPid()
14484                     + ", uid=" + Binder.getCallingUid()
14485                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14486             Slog.w(TAG, msg);
14487             throw new SecurityException(msg);
14488         }
14489         if (userId <= 0) {
14490             throw new IllegalArgumentException("Can't stop primary user " + userId);
14491         }
14492         synchronized (this) {
14493             return stopUserLocked(userId, callback);
14494         }
14495     }
14496
14497     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14498         if (mCurrentUserId == userId) {
14499             return ActivityManager.USER_OP_IS_CURRENT;
14500         }
14501
14502         final UserStartedState uss = mStartedUsers.get(userId);
14503         if (uss == null) {
14504             // User is not started, nothing to do...  but we do need to
14505             // callback if requested.
14506             if (callback != null) {
14507                 mHandler.post(new Runnable() {
14508                     @Override
14509                     public void run() {
14510                         try {
14511                             callback.userStopped(userId);
14512                         } catch (RemoteException e) {
14513                         }
14514                     }
14515                 });
14516             }
14517             return ActivityManager.USER_OP_SUCCESS;
14518         }
14519
14520         if (callback != null) {
14521             uss.mStopCallbacks.add(callback);
14522         }
14523
14524         if (uss.mState != UserStartedState.STATE_STOPPING
14525                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14526             uss.mState = UserStartedState.STATE_STOPPING;
14527             updateStartedUserArrayLocked();
14528
14529             long ident = Binder.clearCallingIdentity();
14530             try {
14531                 // We are going to broadcast ACTION_USER_STOPPING and then
14532                 // once that is done send a final ACTION_SHUTDOWN and then
14533                 // stop the user.
14534                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14535                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14536                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14537                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14538                 // This is the result receiver for the final shutdown broadcast.
14539                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14540                     @Override
14541                     public void performReceive(Intent intent, int resultCode, String data,
14542                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14543                         finishUserStop(uss);
14544                     }
14545                 };
14546                 // This is the result receiver for the initial stopping broadcast.
14547                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14548                     @Override
14549                     public void performReceive(Intent intent, int resultCode, String data,
14550                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14551                         // On to the next.
14552                         synchronized (ActivityManagerService.this) {
14553                             if (uss.mState != UserStartedState.STATE_STOPPING) {
14554                                 // Whoops, we are being started back up.  Abort, abort!
14555                                 return;
14556                             }
14557                             uss.mState = UserStartedState.STATE_SHUTDOWN;
14558                         }
14559                         broadcastIntentLocked(null, null, shutdownIntent,
14560                                 null, shutdownReceiver, 0, null, null, null,
14561                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
14562                     }
14563                 };
14564                 // Kick things off.
14565                 broadcastIntentLocked(null, null, stoppingIntent,
14566                         null, stoppingReceiver, 0, null, null,
14567                         android.Manifest.permission.INTERACT_ACROSS_USERS,
14568                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14569             } finally {
14570                 Binder.restoreCallingIdentity(ident);
14571             }
14572         }
14573
14574         return ActivityManager.USER_OP_SUCCESS;
14575     }
14576
14577     void finishUserStop(UserStartedState uss) {
14578         final int userId = uss.mHandle.getIdentifier();
14579         boolean stopped;
14580         ArrayList<IStopUserCallback> callbacks;
14581         synchronized (this) {
14582             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14583             if (mStartedUsers.get(userId) != uss) {
14584                 stopped = false;
14585             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14586                 stopped = false;
14587             } else {
14588                 stopped = true;
14589                 // User can no longer run.
14590                 mStartedUsers.remove(userId);
14591                 mUserLru.remove(Integer.valueOf(userId));
14592                 updateStartedUserArrayLocked();
14593
14594                 // Clean up all state and processes associated with the user.
14595                 // Kill all the processes for the user.
14596                 forceStopUserLocked(userId);
14597                 AttributeCache ac = AttributeCache.instance();
14598                 if (ac != null) {
14599                     ac.removeUser(userId);
14600                 }
14601             }
14602         }
14603
14604         for (int i=0; i<callbacks.size(); i++) {
14605             try {
14606                 if (stopped) callbacks.get(i).userStopped(userId);
14607                 else callbacks.get(i).userStopAborted(userId);
14608             } catch (RemoteException e) {
14609             }
14610         }
14611     }
14612
14613     @Override
14614     public UserInfo getCurrentUser() {
14615         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14616                 != PackageManager.PERMISSION_GRANTED) && (
14617                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14618                 != PackageManager.PERMISSION_GRANTED)) {
14619             String msg = "Permission Denial: getCurrentUser() from pid="
14620                     + Binder.getCallingPid()
14621                     + ", uid=" + Binder.getCallingUid()
14622                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14623             Slog.w(TAG, msg);
14624             throw new SecurityException(msg);
14625         }
14626         synchronized (this) {
14627             return getUserManagerLocked().getUserInfo(mCurrentUserId);
14628         }
14629     }
14630
14631     int getCurrentUserIdLocked() {
14632         return mCurrentUserId;
14633     }
14634
14635     @Override
14636     public boolean isUserRunning(int userId, boolean orStopped) {
14637         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14638                 != PackageManager.PERMISSION_GRANTED) {
14639             String msg = "Permission Denial: isUserRunning() from pid="
14640                     + Binder.getCallingPid()
14641                     + ", uid=" + Binder.getCallingUid()
14642                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14643             Slog.w(TAG, msg);
14644             throw new SecurityException(msg);
14645         }
14646         synchronized (this) {
14647             return isUserRunningLocked(userId, orStopped);
14648         }
14649     }
14650
14651     boolean isUserRunningLocked(int userId, boolean orStopped) {
14652         UserStartedState state = mStartedUsers.get(userId);
14653         if (state == null) {
14654             return false;
14655         }
14656         if (orStopped) {
14657             return true;
14658         }
14659         return state.mState != UserStartedState.STATE_STOPPING
14660                 && state.mState != UserStartedState.STATE_SHUTDOWN;
14661     }
14662
14663     @Override
14664     public int[] getRunningUserIds() {
14665         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14666                 != PackageManager.PERMISSION_GRANTED) {
14667             String msg = "Permission Denial: isUserRunning() from pid="
14668                     + Binder.getCallingPid()
14669                     + ", uid=" + Binder.getCallingUid()
14670                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14671             Slog.w(TAG, msg);
14672             throw new SecurityException(msg);
14673         }
14674         synchronized (this) {
14675             return mStartedUserArray;
14676         }
14677     }
14678
14679     private void updateStartedUserArrayLocked() {
14680         int num = 0;
14681         for (int i=0; i<mStartedUsers.size();  i++) {
14682             UserStartedState uss = mStartedUsers.valueAt(i);
14683             // This list does not include stopping users.
14684             if (uss.mState != UserStartedState.STATE_STOPPING
14685                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14686                 num++;
14687             }
14688         }
14689         mStartedUserArray = new int[num];
14690         num = 0;
14691         for (int i=0; i<mStartedUsers.size();  i++) {
14692             UserStartedState uss = mStartedUsers.valueAt(i);
14693             if (uss.mState != UserStartedState.STATE_STOPPING
14694                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14695                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
14696                 num++;
14697             }
14698         }
14699     }
14700
14701     @Override
14702     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14703         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14704                 != PackageManager.PERMISSION_GRANTED) {
14705             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14706                     + Binder.getCallingPid()
14707                     + ", uid=" + Binder.getCallingUid()
14708                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14709             Slog.w(TAG, msg);
14710             throw new SecurityException(msg);
14711         }
14712
14713         mUserSwitchObservers.register(observer);
14714     }
14715
14716     @Override
14717     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14718         mUserSwitchObservers.unregister(observer);
14719     }
14720
14721     private boolean userExists(int userId) {
14722         if (userId == 0) {
14723             return true;
14724         }
14725         UserManagerService ums = getUserManagerLocked();
14726         return ums != null ? (ums.getUserInfo(userId) != null) : false;
14727     }
14728
14729     int[] getUsersLocked() {
14730         UserManagerService ums = getUserManagerLocked();
14731         return ums != null ? ums.getUserIds() : new int[] { 0 };
14732     }
14733
14734     UserManagerService getUserManagerLocked() {
14735         if (mUserManager == null) {
14736             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14737             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14738         }
14739         return mUserManager;
14740     }
14741
14742     private void checkValidCaller(int uid, int userId) {
14743         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14744
14745         throw new SecurityException("Caller uid=" + uid
14746                 + " is not privileged to communicate with user=" + userId);
14747     }
14748
14749     private int applyUserId(int uid, int userId) {
14750         return UserHandle.getUid(userId, uid);
14751     }
14752
14753     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14754         if (info == null) return null;
14755         ApplicationInfo newInfo = new ApplicationInfo(info);
14756         newInfo.uid = applyUserId(info.uid, userId);
14757         newInfo.dataDir = USER_DATA_DIR + userId + "/"
14758                 + info.packageName;
14759         return newInfo;
14760     }
14761
14762     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14763         if (aInfo == null
14764                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14765             return aInfo;
14766         }
14767
14768         ActivityInfo info = new ActivityInfo(aInfo);
14769         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14770         return info;
14771     }
14772 }