blob: 568183b01d0fad0ce7b09387dd0d3695cb21a265 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070021import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import com.android.server.IntentResolver;
23import com.android.server.ProcessMap;
24import com.android.server.ProcessStats;
25import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070028import com.android.server.net.NetworkPolicyManagerService;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080029import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
Dianne Hackborndd71fc82009-12-16 19:24:32 -080031import dalvik.system.Zygote;
32
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.app.Activity;
34import android.app.ActivityManager;
35import android.app.ActivityManagerNative;
36import android.app.ActivityThread;
37import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070038import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020039import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070041import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.app.IActivityWatcher;
43import android.app.IApplicationThread;
44import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070045import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070046import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.app.IServiceConnection;
48import android.app.IThumbnailReceiver;
Dianne Hackbornf26fd992011-04-08 18:14:09 -070049import android.app.IThumbnailRetriever;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070051import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070052import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070054import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080055import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020056import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080057import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.ComponentName;
59import android.content.ContentResolver;
60import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020061import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.Intent;
63import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070064import android.content.IIntentReceiver;
65import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070066import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.content.pm.ActivityInfo;
68import android.content.pm.ApplicationInfo;
69import android.content.pm.ConfigurationInfo;
70import android.content.pm.IPackageDataObserver;
71import android.content.pm.IPackageManager;
72import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080073import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070075import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.content.pm.ProviderInfo;
77import android.content.pm.ResolveInfo;
78import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070079import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040080import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.content.res.Configuration;
82import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070083import android.net.Proxy;
84import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.net.Uri;
86import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080087import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080088import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070089import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080090import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080092import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.os.FileUtils;
94import android.os.Handler;
95import android.os.IBinder;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070096import android.os.IInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import android.os.IPermissionController;
98import android.os.Looper;
99import android.os.Message;
100import android.os.Parcel;
101import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700103import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.os.RemoteException;
105import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700106import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.os.SystemClock;
108import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800111import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800112import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.util.PrintWriterPrinter;
114import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700115import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116import android.view.Gravity;
117import android.view.LayoutInflater;
118import android.view.View;
119import android.view.WindowManager;
120import android.view.WindowManagerPolicy;
121
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700122import java.io.BufferedInputStream;
123import java.io.BufferedOutputStream;
124import java.io.DataInputStream;
125import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import java.io.File;
127import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700130import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200131import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800132import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133import java.io.PrintWriter;
134import java.lang.IllegalStateException;
135import java.lang.ref.WeakReference;
136import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700137import java.util.Collections;
138import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139import java.util.HashMap;
140import java.util.HashSet;
141import java.util.Iterator;
142import java.util.List;
143import java.util.Locale;
144import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700145import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700146import java.util.concurrent.atomic.AtomicBoolean;
147import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700149public final class ActivityManagerService extends ActivityManagerNative
150 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 static final String TAG = "ActivityManager";
152 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400153 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 static final boolean DEBUG_SWITCH = localLOGV || false;
155 static final boolean DEBUG_TASKS = localLOGV || false;
156 static final boolean DEBUG_PAUSE = localLOGV || false;
157 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
158 static final boolean DEBUG_TRANSITION = localLOGV || false;
159 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700160 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700162 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_VISBILITY = localLOGV || false;
164 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700165 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800166 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700168 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700169 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700170 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700171 static final boolean DEBUG_POWER = localLOGV || false;
172 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 static final boolean VALIDATE_TOKENS = false;
174 static final boolean SHOW_ACTIVITY_START_TIME = true;
175
176 // Control over CPU and battery monitoring.
177 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
178 static final boolean MONITOR_CPU_USAGE = true;
179 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
180 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
181 static final boolean MONITOR_THREAD_CPU_USAGE = false;
182
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700184 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 private static final String SYSTEM_SECURE = "ro.secure";
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800187 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
189 // This is the maximum number of application processes we would like
190 // to have running. Due to the asynchronous nature of things, we can
191 // temporarily go beyond this limit.
192 static final int MAX_PROCESSES = 2;
193
194 // Set to false to leave processes running indefinitely, relying on
195 // the kernel killing them as resources are required.
196 static final boolean ENFORCE_PROCESS_LIMIT = false;
197
198 // This is the maximum number of activities that we would like to have
199 // running at a given time.
200 static final int MAX_ACTIVITIES = 20;
201
202 // Maximum number of recent tasks that we can remember.
203 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700204
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700205 // Amount of time after a call to stopAppSwitches() during which we will
206 // prevent further untrusted switches from happening.
207 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208
209 // How long we wait for a launched process to attach to the activity manager
210 // before we decide it's never going to come up for real.
211 static final int PROC_START_TIMEOUT = 10*1000;
212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 // How long to wait after going idle before forcing apps to GC.
214 static final int GC_TIMEOUT = 5*1000;
215
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700216 // The minimum amount of time between successive GC requests for a process.
217 static final int GC_MIN_INTERVAL = 60*1000;
218
Dianne Hackborn287952c2010-09-22 22:34:31 -0700219 // The rate at which we check for apps using excessive power -- 15 mins.
220 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
221
222 // The minimum sample duration we will allow before deciding we have
223 // enough data on wake locks to start killing things.
224 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
225
226 // The minimum sample duration we will allow before deciding we have
227 // enough data on CPU usage to start killing things.
228 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 // How long we allow a receiver to run before giving up on it.
231 static final int BROADCAST_TIMEOUT = 10*1000;
232
233 // How long we wait for a service to finish executing.
234 static final int SERVICE_TIMEOUT = 20*1000;
235
236 // How long a service needs to be running until restarting its process
237 // is no longer considered to be a relaunch of the service.
238 static final int SERVICE_RESTART_DURATION = 5*1000;
239
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700240 // How long a service needs to be running until it will start back at
241 // SERVICE_RESTART_DURATION after being killed.
242 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
243
244 // Multiplying factor to increase restart duration time by, for each time
245 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
246 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
247
248 // The minimum amount of time between restarting services that we allow.
249 // That is, when multiple services are restarting, we won't allow each
250 // to restart less than this amount of time from the last one.
251 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 // Maximum amount of time for there to be no activity on a service before
254 // we consider it non-essential and allow its process to go on the
255 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700256 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257
258 // How long we wait until we timeout on key dispatching.
259 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
260
261 // The minimum time we allow between crashes, for us to consider this
262 // application to be bad and stop and its services and reject broadcasts.
263 static final int MIN_CRASH_INTERVAL = 60*1000;
264
265 // How long we wait until we timeout on key dispatching during instrumentation.
266 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
267
268 // OOM adjustments for processes in various states:
269
270 // This is a process without anything currently running in it. Definitely
271 // the first to go! Value set in system/rootdir/init.rc on startup.
272 // This value is initalized in the constructor, careful when refering to
273 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800274 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275
276 // This is a process only hosting activities that are not visible,
277 // so it can be killed without any disruption. Value set in
278 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800279 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 static int HIDDEN_APP_MIN_ADJ;
281
The Android Open Source Project4df24232009-03-05 14:34:35 -0800282 // This is a process holding the home application -- we want to try
283 // avoiding killing it, even if it would normally be in the background,
284 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800285 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800286
Christopher Tate6fa95972009-06-05 18:43:55 -0700287 // This is a process currently hosting a backup operation. Killing it
288 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800289 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 // This is a process holding a secondary server -- killing it will not
292 // have much of an impact as far as the user is concerned. Value set in
293 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800294 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700296 // This is a process with a heavy-weight application. It is in the
297 // background, but we want to try to avoid killing it. Value set in
298 // system/rootdir/init.rc on startup.
299 static final int HEAVY_WEIGHT_APP_ADJ;
300
301 // This is a process only hosting components that are perceptible to the
302 // user, and we really want to avoid killing them, but they are not
303 // immediately visible. An example is background music playback. Value set in
304 // system/rootdir/init.rc on startup.
305 static final int PERCEPTIBLE_APP_ADJ;
306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 // This is a process only hosting activities that are visible to the
308 // user, so we'd prefer they don't disappear. Value set in
309 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800310 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311
312 // This is the process running the current foreground app. We'd really
313 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800314 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315
316 // This is a process running a core server, such as telephony. Definitely
317 // don't want to kill it, but doing so is not completely fatal.
318 static final int CORE_SERVER_ADJ = -12;
319
320 // The system process runs at the default adjustment.
321 static final int SYSTEM_ADJ = -16;
322
323 // Memory pages are 4K.
324 static final int PAGE_SIZE = 4*1024;
325
326 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800327 static final int EMPTY_APP_MEM;
328 static final int HIDDEN_APP_MEM;
329 static final int HOME_APP_MEM;
330 static final int BACKUP_APP_MEM;
331 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700332 static final int HEAVY_WEIGHT_APP_MEM;
333 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800334 static final int VISIBLE_APP_MEM;
335 static final int FOREGROUND_APP_MEM;
336
337 // The minimum number of hidden apps we want to be able to keep around,
338 // without empty apps being able to push them out of memory.
339 static final int MIN_HIDDEN_APPS = 2;
340
Dianne Hackborn8633e682010-04-22 16:03:41 -0700341 // The maximum number of hidden processes we will keep around before
342 // killing them; this is just a control to not let us go too crazy with
343 // keeping around processes on devices with large amounts of RAM.
344 static final int MAX_HIDDEN_APPS = 15;
345
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800346 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700347 // been idle for less than 15 seconds.
348 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800349
350 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700351 // been idle for less than 120 seconds.
352 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800353
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700354 static int getIntProp(String name, boolean allowZero) {
355 String str = SystemProperties.get(name);
356 if (str == null) {
357 throw new IllegalArgumentException("Property not defined: " + name);
358 }
359 int val = Integer.valueOf(str);
360 if (val == 0 && !allowZero) {
361 throw new IllegalArgumentException("Property must not be zero: " + name);
362 }
363 return val;
364 }
365
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800366 static {
367 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700368 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
369 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
370 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
371 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
372 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
373 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
374 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
375 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
376 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
377 // These days we use the last empty slot for hidden apps as well.
378 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
379 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
380 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
381 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
382 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
383 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
384 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
385 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
386 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
387 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389
Dan Egnor42471dd2010-01-07 17:25:22 -0800390 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391
392 static final String[] EMPTY_STRING_ARRAY = new String[0];
393
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700394 public ActivityStack mMainStack;
395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700397 * Description of a request to start a new activity, which has been held
398 * due to app switches being disabled.
399 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700400 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700401 ActivityRecord r;
402 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700403 Uri[] grantedUriPermissions;
404 int grantedMode;
405 boolean onlyIfNeeded;
406 }
407
408 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
409 = new ArrayList<PendingActivityLaunch>();
410
411 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 * List of all active broadcasts that are to be executed immediately
413 * (without waiting for another broadcast to finish). Currently this only
414 * contains broadcasts to registered receivers, to avoid spinning up
415 * a bunch of processes to execute IntentReceiver components.
416 */
417 final ArrayList<BroadcastRecord> mParallelBroadcasts
418 = new ArrayList<BroadcastRecord>();
419
420 /**
421 * List of all active broadcasts that are to be executed one at a time.
422 * The object at the top of the list is the currently activity broadcasts;
423 * those after it are waiting for the top to finish..
424 */
425 final ArrayList<BroadcastRecord> mOrderedBroadcasts
426 = new ArrayList<BroadcastRecord>();
427
428 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800429 * Historical data of past broadcasts, for debugging.
430 */
431 static final int MAX_BROADCAST_HISTORY = 100;
432 final BroadcastRecord[] mBroadcastHistory
433 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
434
435 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 * Set when we current have a BROADCAST_INTENT_MSG in flight.
437 */
438 boolean mBroadcastsScheduled = false;
439
440 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 * Activity we have told the window manager to have key focus.
442 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700443 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700444 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 * List of intents that were used to start the most recent tasks.
446 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700447 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448
449 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 * All of the applications we currently have running organized by name.
451 * The keys are strings of the application package name (as
452 * returned by the package manager), and the keys are ApplicationRecord
453 * objects.
454 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700455 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456
457 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700458 * The currently running heavy-weight process, if any.
459 */
460 ProcessRecord mHeavyWeightProcess = null;
461
462 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 * The last time that various processes have crashed.
464 */
465 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
466
467 /**
468 * Set of applications that we consider to be bad, and will reject
469 * incoming broadcasts from (which the user has no control over).
470 * Processes are added to this set when they have crashed twice within
471 * a minimum amount of time; they are removed from it when they are
472 * later restarted (hopefully due to some user action). The value is the
473 * time it was added to the list.
474 */
475 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
476
477 /**
478 * All of the processes we currently have running organized by pid.
479 * The keys are the pid running the application.
480 *
481 * <p>NOTE: This object is protected by its own lock, NOT the global
482 * activity manager lock!
483 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700484 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485
486 /**
487 * All of the processes that have been forced to be foreground. The key
488 * is the pid of the caller who requested it (we hold a death
489 * link on it).
490 */
491 abstract class ForegroundToken implements IBinder.DeathRecipient {
492 int pid;
493 IBinder token;
494 }
495 final SparseArray<ForegroundToken> mForegroundProcesses
496 = new SparseArray<ForegroundToken>();
497
498 /**
499 * List of records for processes that someone had tried to start before the
500 * system was ready. We don't start them at that point, but ensure they
501 * are started by the time booting is complete.
502 */
503 final ArrayList<ProcessRecord> mProcessesOnHold
504 = new ArrayList<ProcessRecord>();
505
506 /**
507 * List of records for processes that we have started and are waiting
508 * for them to call back. This is really only needed when running in
509 * single processes mode, in which case we do not have a unique pid for
510 * each process.
511 */
512 final ArrayList<ProcessRecord> mStartingProcesses
513 = new ArrayList<ProcessRecord>();
514
515 /**
516 * List of persistent applications that are in the process
517 * of being started.
518 */
519 final ArrayList<ProcessRecord> mPersistentStartingProcesses
520 = new ArrayList<ProcessRecord>();
521
522 /**
523 * Processes that are being forcibly torn down.
524 */
525 final ArrayList<ProcessRecord> mRemovedProcesses
526 = new ArrayList<ProcessRecord>();
527
528 /**
529 * List of running applications, sorted by recent usage.
530 * The first entry in the list is the least recently used.
531 * It contains ApplicationRecord objects. This list does NOT include
532 * any persistent application records (since we never want to exit them).
533 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800534 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 = new ArrayList<ProcessRecord>();
536
537 /**
538 * List of processes that should gc as soon as things are idle.
539 */
540 final ArrayList<ProcessRecord> mProcessesToGc
541 = new ArrayList<ProcessRecord>();
542
543 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800544 * This is the process holding what we currently consider to be
545 * the "home" activity.
546 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700547 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800548
549 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400550 * Packages that the user has asked to have run in screen size
551 * compatibility mode instead of filling the screen.
552 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700553 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400554
555 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 * Set of PendingResultRecord objects that are currently active.
557 */
558 final HashSet mPendingResultRecords = new HashSet();
559
560 /**
561 * Set of IntentSenderRecord objects that are currently active.
562 */
563 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
564 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
565
566 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800567 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700568 * already logged DropBox entries for. Guarded by itself. If
569 * something (rogue user app) forces this over
570 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
571 */
572 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
573 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
574
575 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700576 * Strict Mode background batched logging state.
577 *
578 * The string buffer is guarded by itself, and its lock is also
579 * used to determine if another batched write is already
580 * in-flight.
581 */
582 private final StringBuilder mStrictModeBuffer = new StringBuilder();
583
584 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700585 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
586 */
587 private boolean mPendingBroadcastTimeoutMessage;
588
589 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 * Intent broadcast that we have tried to start, but are
591 * waiting for its application's process to be created. We only
592 * need one (instead of a list) because we always process broadcasts
593 * one at a time, so no others can be started while waiting for this
594 * one.
595 */
596 BroadcastRecord mPendingBroadcast = null;
597
598 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700599 * The receiver index that is pending, to restart the broadcast if needed.
600 */
601 int mPendingBroadcastRecvIndex;
602
603 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 * Keeps track of all IIntentReceivers that have been registered for
605 * broadcasts. Hash keys are the receiver IBinder, hash value is
606 * a ReceiverList.
607 */
608 final HashMap mRegisteredReceivers = new HashMap();
609
610 /**
611 * Resolver for broadcast intents to registered receivers.
612 * Holds BroadcastFilter (subclass of IntentFilter).
613 */
614 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
615 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
616 @Override
617 protected boolean allowFilterResult(
618 BroadcastFilter filter, List<BroadcastFilter> dest) {
619 IBinder target = filter.receiverList.receiver.asBinder();
620 for (int i=dest.size()-1; i>=0; i--) {
621 if (dest.get(i).receiverList.receiver.asBinder() == target) {
622 return false;
623 }
624 }
625 return true;
626 }
627 };
628
629 /**
630 * State of all active sticky broadcasts. Keys are the action of the
631 * sticky Intent, values are an ArrayList of all broadcasted intents with
632 * that action (which should usually be one).
633 */
634 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
635 new HashMap<String, ArrayList<Intent>>();
636
637 /**
638 * All currently running services.
639 */
640 final HashMap<ComponentName, ServiceRecord> mServices =
641 new HashMap<ComponentName, ServiceRecord>();
642
643 /**
644 * All currently running services indexed by the Intent used to start them.
645 */
646 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
647 new HashMap<Intent.FilterComparison, ServiceRecord>();
648
649 /**
650 * All currently bound service connections. Keys are the IBinder of
651 * the client's IServiceConnection.
652 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700653 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
654 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655
656 /**
657 * List of services that we have been asked to start,
658 * but haven't yet been able to. It is used to hold start requests
659 * while waiting for their corresponding application thread to get
660 * going.
661 */
662 final ArrayList<ServiceRecord> mPendingServices
663 = new ArrayList<ServiceRecord>();
664
665 /**
666 * List of services that are scheduled to restart following a crash.
667 */
668 final ArrayList<ServiceRecord> mRestartingServices
669 = new ArrayList<ServiceRecord>();
670
671 /**
672 * List of services that are in the process of being stopped.
673 */
674 final ArrayList<ServiceRecord> mStoppingServices
675 = new ArrayList<ServiceRecord>();
676
677 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700678 * Backup/restore process management
679 */
680 String mBackupAppName = null;
681 BackupRecord mBackupTarget = null;
682
683 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 * List of PendingThumbnailsRecord objects of clients who are still
685 * waiting to receive all of the thumbnails for a task.
686 */
687 final ArrayList mPendingThumbnails = new ArrayList();
688
689 /**
690 * List of HistoryRecord objects that have been finished and must
691 * still report back to a pending thumbnail receiver.
692 */
693 final ArrayList mCancelledThumbnails = new ArrayList();
694
695 /**
696 * All of the currently running global content providers. Keys are a
697 * string containing the provider name and values are a
698 * ContentProviderRecord object containing the data about it. Note
699 * that a single provider may be published under multiple names, so
700 * there may be multiple entries here for a single one in mProvidersByClass.
701 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700702 final HashMap<String, ContentProviderRecord> mProvidersByName
703 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
705 /**
706 * All of the currently running global content providers. Keys are a
707 * string containing the provider's implementation class and values are a
708 * ContentProviderRecord object containing the data about it.
709 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700710 final HashMap<String, ContentProviderRecord> mProvidersByClass
711 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712
713 /**
714 * List of content providers who have clients waiting for them. The
715 * application is currently being launched and the provider will be
716 * removed from this list once it is published.
717 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700718 final ArrayList<ContentProviderRecord> mLaunchingProviders
719 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720
721 /**
722 * Global set of specific Uri permissions that have been granted.
723 */
724 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
725 = new SparseArray<HashMap<Uri, UriPermission>>();
726
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800727 CoreSettingsObserver mCoreSettingsObserver;
728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 /**
730 * Thread-local storage used to carry caller permissions over through
731 * indirect content-provider access.
732 * @see #ActivityManagerService.openContentUri()
733 */
734 private class Identity {
735 public int pid;
736 public int uid;
737
738 Identity(int _pid, int _uid) {
739 pid = _pid;
740 uid = _uid;
741 }
742 }
743 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
744
745 /**
746 * All information we have collected about the runtime performance of
747 * any user id that can impact battery performance.
748 */
749 final BatteryStatsService mBatteryStatsService;
750
751 /**
752 * information about component usage
753 */
754 final UsageStatsService mUsageStatsService;
755
756 /**
757 * Current configuration information. HistoryRecord objects are given
758 * a reference to this object to indicate which configuration they are
759 * currently running in, so this object must be kept immutable.
760 */
761 Configuration mConfiguration = new Configuration();
762
763 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800764 * Current sequencing integer of the configuration, for skipping old
765 * configurations.
766 */
767 int mConfigurationSeq = 0;
768
769 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700770 * Hardware-reported OpenGLES version.
771 */
772 final int GL_ES_VERSION;
773
774 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 * List of initialization arguments to pass to all processes when binding applications to them.
776 * For example, references to the commonly used services.
777 */
778 HashMap<String, IBinder> mAppBindArgs;
779
780 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700781 * Temporary to avoid allocations. Protected by main lock.
782 */
783 final StringBuilder mStringBuilder = new StringBuilder(256);
784
785 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 * Used to control how we initialize the service.
787 */
788 boolean mStartRunning = false;
789 ComponentName mTopComponent;
790 String mTopAction;
791 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700792 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 boolean mSystemReady = false;
794 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700795 boolean mWaitingUpdate = false;
796 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700797 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700798 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799
800 Context mContext;
801
802 int mFactoryTest;
803
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700804 boolean mCheckedForSetup;
805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700807 * The time at which we will allow normal application switches again,
808 * after a call to {@link #stopAppSwitches()}.
809 */
810 long mAppSwitchesAllowedTime;
811
812 /**
813 * This is set to true after the first switch after mAppSwitchesAllowedTime
814 * is set; any switches after that will clear the time.
815 */
816 boolean mDidAppSwitch;
817
818 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700819 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700820 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700821 long mLastPowerCheckRealtime;
822
823 /**
824 * Last time (in uptime) at which we checked for power usage.
825 */
826 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700827
828 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 * Set while we are wanting to sleep, to prevent any
830 * activities from being started/resumed.
831 */
832 boolean mSleeping = false;
833
834 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700835 * Set if we are shutting down the system, similar to sleeping.
836 */
837 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838
839 /**
840 * Task identifier that activities are currently being started
841 * in. Incremented each time a new task is created.
842 * todo: Replace this with a TokenSpace class that generates non-repeating
843 * integers that won't wrap.
844 */
845 int mCurTask = 1;
846
847 /**
848 * Current sequence id for oom_adj computation traversal.
849 */
850 int mAdjSeq = 0;
851
852 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700853 * Current sequence id for process LRU updating.
854 */
855 int mLruSeq = 0;
856
857 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
859 * is set, indicating the user wants processes started in such a way
860 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
861 * running in each process (thus no pre-initialized process, etc).
862 */
863 boolean mSimpleProcessManagement = false;
864
865 /**
866 * System monitoring: number of processes that died since the last
867 * N procs were started.
868 */
869 int[] mProcDeaths = new int[20];
870
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700871 /**
872 * This is set if we had to do a delayed dexopt of an app before launching
873 * it, to increasing the ANR timeouts in that case.
874 */
875 boolean mDidDexOpt;
876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 String mDebugApp = null;
878 boolean mWaitForDebugger = false;
879 boolean mDebugTransient = false;
880 String mOrigDebugApp = null;
881 boolean mOrigWaitForDebugger = false;
882 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700883 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700885 final RemoteCallbackList<IActivityWatcher> mWatchers
886 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700887
888 final RemoteCallbackList<IProcessObserver> mProcessObservers
889 = new RemoteCallbackList<IProcessObserver>();
890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 /**
892 * Callback of last caller to {@link #requestPss}.
893 */
894 Runnable mRequestPssCallback;
895
896 /**
897 * Remaining processes for which we are waiting results from the last
898 * call to {@link #requestPss}.
899 */
900 final ArrayList<ProcessRecord> mRequestPssList
901 = new ArrayList<ProcessRecord>();
902
903 /**
904 * Runtime statistics collection thread. This object's lock is used to
905 * protect all related state.
906 */
907 final Thread mProcessStatsThread;
908
909 /**
910 * Used to collect process stats when showing not responding dialog.
911 * Protected by mProcessStatsThread.
912 */
913 final ProcessStats mProcessStats = new ProcessStats(
914 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700915 final AtomicLong mLastCpuTime = new AtomicLong(0);
916 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 long mLastWriteTime = 0;
919
920 /**
921 * Set to true after the system has finished booting.
922 */
923 boolean mBooted = false;
924
925 int mProcessLimit = 0;
926
927 WindowManagerService mWindowManager;
928
929 static ActivityManagerService mSelf;
930 static ActivityThread mSystemThread;
931
932 private final class AppDeathRecipient implements IBinder.DeathRecipient {
933 final ProcessRecord mApp;
934 final int mPid;
935 final IApplicationThread mAppThread;
936
937 AppDeathRecipient(ProcessRecord app, int pid,
938 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800939 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 TAG, "New death recipient " + this
941 + " for thread " + thread.asBinder());
942 mApp = app;
943 mPid = pid;
944 mAppThread = thread;
945 }
946
947 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800948 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 TAG, "Death received in " + this
950 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 synchronized(ActivityManagerService.this) {
952 appDiedLocked(mApp, mPid, mAppThread);
953 }
954 }
955 }
956
957 static final int SHOW_ERROR_MSG = 1;
958 static final int SHOW_NOT_RESPONDING_MSG = 2;
959 static final int SHOW_FACTORY_ERROR_MSG = 3;
960 static final int UPDATE_CONFIGURATION_MSG = 4;
961 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
962 static final int WAIT_FOR_DEBUGGER_MSG = 6;
963 static final int BROADCAST_INTENT_MSG = 7;
964 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 static final int SERVICE_TIMEOUT_MSG = 12;
966 static final int UPDATE_TIME_ZONE = 13;
967 static final int SHOW_UID_ERROR_MSG = 14;
968 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700970 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700971 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800972 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700973 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
974 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700975 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700976 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700977 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700978 static final int UPDATE_HTTP_PROXY = 29;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700979 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 30;
980 static final int DISPATCH_PROCESS_DIED = 31;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981
982 AlertDialog mUidAlert;
983
984 final Handler mHandler = new Handler() {
985 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800986 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 //}
988
989 public void handleMessage(Message msg) {
990 switch (msg.what) {
991 case SHOW_ERROR_MSG: {
992 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 synchronized (ActivityManagerService.this) {
994 ProcessRecord proc = (ProcessRecord)data.get("app");
995 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800996 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 return;
998 }
999 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -07001000 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -08001001 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 d.show();
1003 proc.crashDialog = d;
1004 } else {
1005 // The device is asleep, so just pretend that the user
1006 // saw a crash dialog and hit "force quit".
1007 res.set(0);
1008 }
1009 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001010
1011 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 } break;
1013 case SHOW_NOT_RESPONDING_MSG: {
1014 synchronized (ActivityManagerService.this) {
1015 HashMap data = (HashMap) msg.obj;
1016 ProcessRecord proc = (ProcessRecord)data.get("app");
1017 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001018 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 return;
1020 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001021
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001022 Intent intent = new Intent("android.intent.action.ANR");
1023 if (!mProcessesReady) {
1024 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1025 }
1026 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001027 null, null, 0, null, null, null,
1028 false, false, MY_PID, Process.SYSTEM_UID);
1029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001031 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001032 d.show();
1033 proc.anrDialog = d;
1034 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001035
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001036 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001038 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1039 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1040 synchronized (ActivityManagerService.this) {
1041 ProcessRecord proc = (ProcessRecord) data.get("app");
1042 if (proc == null) {
1043 Slog.e(TAG, "App not found when showing strict mode dialog.");
1044 break;
1045 }
1046 if (proc.crashDialog != null) {
1047 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1048 return;
1049 }
1050 AppErrorResult res = (AppErrorResult) data.get("result");
1051 if (!mSleeping && !mShuttingDown) {
1052 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1053 d.show();
1054 proc.crashDialog = d;
1055 } else {
1056 // The device is asleep, so just pretend that the user
1057 // saw a crash dialog and hit "force quit".
1058 res.set(0);
1059 }
1060 }
1061 ensureBootCompleted();
1062 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 case SHOW_FACTORY_ERROR_MSG: {
1064 Dialog d = new FactoryErrorDialog(
1065 mContext, msg.getData().getCharSequence("msg"));
1066 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001067 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001068 } break;
1069 case UPDATE_CONFIGURATION_MSG: {
1070 final ContentResolver resolver = mContext.getContentResolver();
1071 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1072 } break;
1073 case GC_BACKGROUND_PROCESSES_MSG: {
1074 synchronized (ActivityManagerService.this) {
1075 performAppGcsIfAppropriateLocked();
1076 }
1077 } break;
1078 case WAIT_FOR_DEBUGGER_MSG: {
1079 synchronized (ActivityManagerService.this) {
1080 ProcessRecord app = (ProcessRecord)msg.obj;
1081 if (msg.arg1 != 0) {
1082 if (!app.waitedForDebugger) {
1083 Dialog d = new AppWaitingForDebuggerDialog(
1084 ActivityManagerService.this,
1085 mContext, app);
1086 app.waitDialog = d;
1087 app.waitedForDebugger = true;
1088 d.show();
1089 }
1090 } else {
1091 if (app.waitDialog != null) {
1092 app.waitDialog.dismiss();
1093 app.waitDialog = null;
1094 }
1095 }
1096 }
1097 } break;
1098 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001099 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 TAG, "Received BROADCAST_INTENT_MSG");
1101 processNextBroadcast(true);
1102 } break;
1103 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001104 synchronized (ActivityManagerService.this) {
1105 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001109 if (mDidDexOpt) {
1110 mDidDexOpt = false;
1111 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1112 nmsg.obj = msg.obj;
1113 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1114 return;
1115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 serviceTimeout((ProcessRecord)msg.obj);
1117 } break;
1118 case UPDATE_TIME_ZONE: {
1119 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001120 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1121 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 if (r.thread != null) {
1123 try {
1124 r.thread.updateTimeZone();
1125 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001126 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 }
1128 }
1129 }
1130 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001131 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001132 case CLEAR_DNS_CACHE: {
1133 synchronized (ActivityManagerService.this) {
1134 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1135 ProcessRecord r = mLruProcesses.get(i);
1136 if (r.thread != null) {
1137 try {
1138 r.thread.clearDnsCache();
1139 } catch (RemoteException ex) {
1140 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1141 }
1142 }
1143 }
1144 }
1145 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001146 case UPDATE_HTTP_PROXY: {
1147 ProxyProperties proxy = (ProxyProperties)msg.obj;
1148 String host = "";
1149 String port = "";
1150 String exclList = "";
1151 if (proxy != null) {
1152 host = proxy.getHost();
1153 port = Integer.toString(proxy.getPort());
1154 exclList = proxy.getExclusionList();
1155 }
1156 synchronized (ActivityManagerService.this) {
1157 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1158 ProcessRecord r = mLruProcesses.get(i);
1159 if (r.thread != null) {
1160 try {
1161 r.thread.setHttpProxy(host, port, exclList);
1162 } catch (RemoteException ex) {
1163 Slog.w(TAG, "Failed to update http proxy for: " +
1164 r.info.processName);
1165 }
1166 }
1167 }
1168 }
1169 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 case SHOW_UID_ERROR_MSG: {
1171 // XXX This is a temporary dialog, no need to localize.
1172 AlertDialog d = new BaseErrorDialog(mContext);
1173 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1174 d.setCancelable(false);
1175 d.setTitle("System UIDs Inconsistent");
1176 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001177 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1179 mUidAlert = d;
1180 d.show();
1181 } break;
1182 case IM_FEELING_LUCKY_MSG: {
1183 if (mUidAlert != null) {
1184 mUidAlert.dismiss();
1185 mUidAlert = null;
1186 }
1187 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001189 if (mDidDexOpt) {
1190 mDidDexOpt = false;
1191 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1192 nmsg.obj = msg.obj;
1193 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1194 return;
1195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 ProcessRecord app = (ProcessRecord)msg.obj;
1197 synchronized (ActivityManagerService.this) {
1198 processStartTimedOutLocked(app);
1199 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001200 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001201 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1202 synchronized (ActivityManagerService.this) {
1203 doPendingActivityLaunchesLocked(true);
1204 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001205 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001206 case KILL_APPLICATION_MSG: {
1207 synchronized (ActivityManagerService.this) {
1208 int uid = msg.arg1;
1209 boolean restart = (msg.arg2 == 1);
1210 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001211 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001212 }
1213 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001214 case FINALIZE_PENDING_INTENT_MSG: {
1215 ((PendingIntentRecord)msg.obj).completeFinalize();
1216 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001217 case POST_HEAVY_NOTIFICATION_MSG: {
1218 INotificationManager inm = NotificationManager.getService();
1219 if (inm == null) {
1220 return;
1221 }
1222
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001223 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001224 ProcessRecord process = root.app;
1225 if (process == null) {
1226 return;
1227 }
1228
1229 try {
1230 Context context = mContext.createPackageContext(process.info.packageName, 0);
1231 String text = mContext.getString(R.string.heavy_weight_notification,
1232 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1233 Notification notification = new Notification();
1234 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1235 notification.when = 0;
1236 notification.flags = Notification.FLAG_ONGOING_EVENT;
1237 notification.tickerText = text;
1238 notification.defaults = 0; // please be quiet
1239 notification.sound = null;
1240 notification.vibrate = null;
1241 notification.setLatestEventInfo(context, text,
1242 mContext.getText(R.string.heavy_weight_notification_detail),
1243 PendingIntent.getActivity(mContext, 0, root.intent,
1244 PendingIntent.FLAG_CANCEL_CURRENT));
1245
1246 try {
1247 int[] outId = new int[1];
1248 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1249 notification, outId);
1250 } catch (RuntimeException e) {
1251 Slog.w(ActivityManagerService.TAG,
1252 "Error showing notification for heavy-weight app", e);
1253 } catch (RemoteException e) {
1254 }
1255 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001256 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001257 }
1258 } break;
1259 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1260 INotificationManager inm = NotificationManager.getService();
1261 if (inm == null) {
1262 return;
1263 }
1264 try {
1265 inm.cancelNotification("android",
1266 R.string.heavy_weight_notification);
1267 } catch (RuntimeException e) {
1268 Slog.w(ActivityManagerService.TAG,
1269 "Error canceling notification for service", e);
1270 } catch (RemoteException e) {
1271 }
1272 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001273 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1274 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001275 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001276 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001277 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1278 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001279 }
1280 } break;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001281 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001282 final ProcessRecord app = (ProcessRecord) msg.obj;
Jeff Sharkeya4620792011-05-20 15:29:23 -07001283 final boolean foregroundActivities = msg.arg1 != 0;
1284 dispatchForegroundActivitiesChanged(
1285 app.pid, app.info.uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001286 break;
1287 }
1288 case DISPATCH_PROCESS_DIED: {
1289 final ProcessRecord app = (ProcessRecord) msg.obj;
Jeff Sharkeya4620792011-05-20 15:29:23 -07001290 dispatchProcessDied(app.pid, app.info.uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001291 break;
1292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 }
1294 }
1295 };
1296
1297 public static void setSystemProcess() {
1298 try {
1299 ActivityManagerService m = mSelf;
1300
1301 ServiceManager.addService("activity", m);
1302 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001303 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 if (MONITOR_CPU_USAGE) {
1305 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 ServiceManager.addService("permission", new PermissionController(m));
1308
1309 ApplicationInfo info =
1310 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001311 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001312 mSystemThread.installSystemApplicationInfo(info);
1313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 synchronized (mSelf) {
1315 ProcessRecord app = mSelf.newProcessRecordLocked(
1316 mSystemThread.getApplicationThread(), info,
1317 info.processName);
1318 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001319 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 app.maxAdj = SYSTEM_ADJ;
1321 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1322 synchronized (mSelf.mPidsSelfLocked) {
1323 mSelf.mPidsSelfLocked.put(app.pid, app);
1324 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001325 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 }
1327 } catch (PackageManager.NameNotFoundException e) {
1328 throw new RuntimeException(
1329 "Unable to find android system package", e);
1330 }
1331 }
1332
1333 public void setWindowManager(WindowManagerService wm) {
1334 mWindowManager = wm;
1335 }
1336
1337 public static final Context main(int factoryTest) {
1338 AThread thr = new AThread();
1339 thr.start();
1340
1341 synchronized (thr) {
1342 while (thr.mService == null) {
1343 try {
1344 thr.wait();
1345 } catch (InterruptedException e) {
1346 }
1347 }
1348 }
1349
1350 ActivityManagerService m = thr.mService;
1351 mSelf = m;
1352 ActivityThread at = ActivityThread.systemMain();
1353 mSystemThread = at;
1354 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001355 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 m.mContext = context;
1357 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001358 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359
1360 m.mBatteryStatsService.publish(context);
1361 m.mUsageStatsService.publish(context);
1362
1363 synchronized (thr) {
1364 thr.mReady = true;
1365 thr.notifyAll();
1366 }
1367
1368 m.startRunning(null, null, null, null);
1369
1370 return context;
1371 }
1372
1373 public static ActivityManagerService self() {
1374 return mSelf;
1375 }
1376
1377 static class AThread extends Thread {
1378 ActivityManagerService mService;
1379 boolean mReady = false;
1380
1381 public AThread() {
1382 super("ActivityManager");
1383 }
1384
1385 public void run() {
1386 Looper.prepare();
1387
1388 android.os.Process.setThreadPriority(
1389 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001390 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391
1392 ActivityManagerService m = new ActivityManagerService();
1393
1394 synchronized (this) {
1395 mService = m;
1396 notifyAll();
1397 }
1398
1399 synchronized (this) {
1400 while (!mReady) {
1401 try {
1402 wait();
1403 } catch (InterruptedException e) {
1404 }
1405 }
1406 }
1407
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001408 // For debug builds, log event loop stalls to dropbox for analysis.
1409 if (StrictMode.conditionallyEnableDebugLogging()) {
1410 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1411 }
1412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 Looper.loop();
1414 }
1415 }
1416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 static class MemBinder extends Binder {
1418 ActivityManagerService mActivityManagerService;
1419 MemBinder(ActivityManagerService activityManagerService) {
1420 mActivityManagerService = activityManagerService;
1421 }
1422
1423 @Override
1424 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001425 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 }
1427 }
1428
Chet Haase9c1e23b2011-03-24 10:51:31 -07001429 static class GraphicsBinder extends Binder {
1430 ActivityManagerService mActivityManagerService;
1431 GraphicsBinder(ActivityManagerService activityManagerService) {
1432 mActivityManagerService = activityManagerService;
1433 }
1434
1435 @Override
1436 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001437 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001438 }
1439 }
1440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 static class CpuBinder extends Binder {
1442 ActivityManagerService mActivityManagerService;
1443 CpuBinder(ActivityManagerService activityManagerService) {
1444 mActivityManagerService = activityManagerService;
1445 }
1446
1447 @Override
1448 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1449 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001450 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1451 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1452 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 }
1454 }
1455 }
1456
1457 private ActivityManagerService() {
1458 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1459 if (v != null && Integer.getInteger(v) != 0) {
1460 mSimpleProcessManagement = true;
1461 }
1462 v = System.getenv("ANDROID_DEBUG_APP");
1463 if (v != null) {
1464 mSimpleProcessManagement = true;
1465 }
1466
Joe Onorato8a9b2202010-02-26 18:56:32 -08001467 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 File dataDir = Environment.getDataDirectory();
1470 File systemDir = new File(dataDir, "system");
1471 systemDir.mkdirs();
1472 mBatteryStatsService = new BatteryStatsService(new File(
1473 systemDir, "batterystats.bin").toString());
1474 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001475 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001476 mOnBattery = DEBUG_POWER ? true
1477 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001478 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001480 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001481 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482
Jack Palevichb90d28c2009-07-22 15:35:24 -07001483 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1484 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1485
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001486 mConfiguration.setToDefaults();
1487 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 mProcessStats.init();
1489
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001490 mCompatModePackages = new CompatModePackages(this, systemDir);
1491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 // Add ourself to the Watchdog monitors.
1493 Watchdog.getInstance().addMonitor(this);
1494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 mProcessStatsThread = new Thread("ProcessStats") {
1496 public void run() {
1497 while (true) {
1498 try {
1499 try {
1500 synchronized(this) {
1501 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001502 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001504 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 // + ", write delay=" + nextWriteDelay);
1506 if (nextWriteDelay < nextCpuDelay) {
1507 nextCpuDelay = nextWriteDelay;
1508 }
1509 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001510 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 this.wait(nextCpuDelay);
1512 }
1513 }
1514 } catch (InterruptedException e) {
1515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 updateCpuStatsNow();
1517 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001518 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 }
1520 }
1521 }
1522 };
1523 mProcessStatsThread.start();
1524 }
1525
1526 @Override
1527 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1528 throws RemoteException {
1529 try {
1530 return super.onTransact(code, data, reply, flags);
1531 } catch (RuntimeException e) {
1532 // The activity manager only throws security exceptions, so let's
1533 // log all others.
1534 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001535 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 }
1537 throw e;
1538 }
1539 }
1540
1541 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001542 final long now = SystemClock.uptimeMillis();
1543 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1544 return;
1545 }
1546 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1547 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 mProcessStatsThread.notify();
1549 }
1550 }
1551 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 void updateCpuStatsNow() {
1554 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001555 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 final long now = SystemClock.uptimeMillis();
1557 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001560 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1561 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 haveNewCpuStats = true;
1563 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001564 //Slog.i(TAG, mProcessStats.printCurrentState());
1565 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 // + mProcessStats.getTotalCpuPercent() + "%");
1567
Joe Onorato8a9b2202010-02-26 18:56:32 -08001568 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 if ("true".equals(SystemProperties.get("events.cpu"))) {
1570 int user = mProcessStats.getLastUserTime();
1571 int system = mProcessStats.getLastSystemTime();
1572 int iowait = mProcessStats.getLastIoWaitTime();
1573 int irq = mProcessStats.getLastIrqTime();
1574 int softIrq = mProcessStats.getLastSoftIrqTime();
1575 int idle = mProcessStats.getLastIdleTime();
1576
1577 int total = user + system + iowait + irq + softIrq + idle;
1578 if (total == 0) total = 1;
1579
Doug Zongker2bec3d42009-12-04 12:52:44 -08001580 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 ((user+system+iowait+irq+softIrq) * 100) / total,
1582 (user * 100) / total,
1583 (system * 100) / total,
1584 (iowait * 100) / total,
1585 (irq * 100) / total,
1586 (softIrq * 100) / total);
1587 }
1588 }
1589
Amith Yamasanie43530a2009-08-21 13:11:37 -07001590 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001591 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001592 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 synchronized(mPidsSelfLocked) {
1594 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001595 if (mOnBattery) {
1596 int perc = bstats.startAddingCpuLocked();
1597 int totalUTime = 0;
1598 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001599 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001601 ProcessStats.Stats st = mProcessStats.getStats(i);
1602 if (!st.working) {
1603 continue;
1604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001606 int otherUTime = (st.rel_utime*perc)/100;
1607 int otherSTime = (st.rel_stime*perc)/100;
1608 totalUTime += otherUTime;
1609 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 if (pr != null) {
1611 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001612 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1613 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001614 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001615 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001616 } else {
1617 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001618 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001619 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001620 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1621 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001622 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001624 }
1625 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001626 bstats.finishAddingCpuLocked(perc, totalUTime,
1627 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 }
1629 }
1630 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1633 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001634 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 }
1636 }
1637 }
1638 }
1639
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001640 @Override
1641 public void batteryNeedsCpuUpdate() {
1642 updateCpuStatsNow();
1643 }
1644
1645 @Override
1646 public void batteryPowerChanged(boolean onBattery) {
1647 // When plugging in, update the CPU stats first before changing
1648 // the plug state.
1649 updateCpuStatsNow();
1650 synchronized (this) {
1651 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001652 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001653 }
1654 }
1655 }
1656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 /**
1658 * Initialize the application bind args. These are passed to each
1659 * process when the bindApplication() IPC is sent to the process. They're
1660 * lazily setup to make sure the services are running when they're asked for.
1661 */
1662 private HashMap<String, IBinder> getCommonServicesLocked() {
1663 if (mAppBindArgs == null) {
1664 mAppBindArgs = new HashMap<String, IBinder>();
1665
1666 // Setup the application init args
1667 mAppBindArgs.put("package", ServiceManager.getService("package"));
1668 mAppBindArgs.put("window", ServiceManager.getService("window"));
1669 mAppBindArgs.put(Context.ALARM_SERVICE,
1670 ServiceManager.getService(Context.ALARM_SERVICE));
1671 }
1672 return mAppBindArgs;
1673 }
1674
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001675 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 if (mFocusedActivity != r) {
1677 mFocusedActivity = r;
1678 mWindowManager.setFocusedApp(r, true);
1679 }
1680 }
1681
Dianne Hackborn906497c2010-05-10 15:57:38 -07001682 private final void updateLruProcessInternalLocked(ProcessRecord app,
1683 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001684 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001685 int lrui = mLruProcesses.indexOf(app);
1686 if (lrui >= 0) mLruProcesses.remove(lrui);
1687
1688 int i = mLruProcesses.size()-1;
1689 int skipTop = 0;
1690
Dianne Hackborn906497c2010-05-10 15:57:38 -07001691 app.lruSeq = mLruSeq;
1692
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001693 // compute the new weight for this process.
1694 if (updateActivityTime) {
1695 app.lastActivityTime = SystemClock.uptimeMillis();
1696 }
1697 if (app.activities.size() > 0) {
1698 // If this process has activities, we more strongly want to keep
1699 // it around.
1700 app.lruWeight = app.lastActivityTime;
1701 } else if (app.pubProviders.size() > 0) {
1702 // If this process contains content providers, we want to keep
1703 // it a little more strongly.
1704 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1705 // Also don't let it kick out the first few "real" hidden processes.
1706 skipTop = MIN_HIDDEN_APPS;
1707 } else {
1708 // If this process doesn't have activities, we less strongly
1709 // want to keep it around, and generally want to avoid getting
1710 // in front of any very recently used activities.
1711 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1712 // Also don't let it kick out the first few "real" hidden processes.
1713 skipTop = MIN_HIDDEN_APPS;
1714 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001715
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001716 while (i >= 0) {
1717 ProcessRecord p = mLruProcesses.get(i);
1718 // If this app shouldn't be in front of the first N background
1719 // apps, then skip over that many that are currently hidden.
1720 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1721 skipTop--;
1722 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001723 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001724 mLruProcesses.add(i+1, app);
1725 break;
1726 }
1727 i--;
1728 }
1729 if (i < 0) {
1730 mLruProcesses.add(0, app);
1731 }
1732
Dianne Hackborn906497c2010-05-10 15:57:38 -07001733 // If the app is currently using a content provider or service,
1734 // bump those processes as well.
1735 if (app.connections.size() > 0) {
1736 for (ConnectionRecord cr : app.connections) {
1737 if (cr.binding != null && cr.binding.service != null
1738 && cr.binding.service.app != null
1739 && cr.binding.service.app.lruSeq != mLruSeq) {
1740 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1741 updateActivityTime, i+1);
1742 }
1743 }
1744 }
1745 if (app.conProviders.size() > 0) {
1746 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1747 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1748 updateLruProcessInternalLocked(cpr.app, oomAdj,
1749 updateActivityTime, i+1);
1750 }
1751 }
1752 }
1753
Joe Onorato8a9b2202010-02-26 18:56:32 -08001754 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 if (oomAdj) {
1756 updateOomAdjLocked();
1757 }
1758 }
1759
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001760 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001761 boolean oomAdj, boolean updateActivityTime) {
1762 mLruSeq++;
1763 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1764 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001765
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001766 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 String processName, int uid) {
1768 if (uid == Process.SYSTEM_UID) {
1769 // The system gets to run in any process. If there are multiple
1770 // processes with the same uid, just pick the first (this
1771 // should never happen).
1772 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1773 processName);
1774 return procs != null ? procs.valueAt(0) : null;
1775 }
1776 ProcessRecord proc = mProcessNames.get(processName, uid);
1777 return proc;
1778 }
1779
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001780 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001781 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001782 try {
1783 if (pm.performDexOpt(packageName)) {
1784 mDidDexOpt = true;
1785 }
1786 } catch (RemoteException e) {
1787 }
1788 }
1789
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001790 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 int transit = mWindowManager.getPendingAppTransition();
1792 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1793 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1794 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1795 }
1796
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001797 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001799 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1801 // We don't have to do anything more if:
1802 // (1) There is an existing application record; and
1803 // (2) The caller doesn't think it is dead, OR there is no thread
1804 // object attached to it so we know it couldn't have crashed; and
1805 // (3) There is a pid assigned to it, so it is either starting or
1806 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001807 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 + " app=" + app + " knownToBeDead=" + knownToBeDead
1809 + " thread=" + (app != null ? app.thread : null)
1810 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001811 if (app != null && app.pid > 0) {
1812 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001813 // We already have the app running, or are waiting for it to
1814 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001815 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001816 return app;
1817 } else {
1818 // An application record is attached to a previous process,
1819 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001820 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001821 handleAppDiedLocked(app, true);
1822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 String hostingNameStr = hostingName != null
1826 ? hostingName.flattenToShortString() : null;
1827
1828 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1829 // If we are in the background, then check to see if this process
1830 // is bad. If so, we will just silently fail.
1831 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001832 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1833 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001834 return null;
1835 }
1836 } else {
1837 // When the user is explicitly starting a process, then clear its
1838 // crash count so that we won't make it bad until they see at
1839 // least one crash dialog again, and make the process good again
1840 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001841 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1842 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 mProcessCrashTimes.remove(info.processName, info.uid);
1844 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001845 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 info.processName);
1847 mBadProcesses.remove(info.processName, info.uid);
1848 if (app != null) {
1849 app.bad = false;
1850 }
1851 }
1852 }
1853
1854 if (app == null) {
1855 app = newProcessRecordLocked(null, info, processName);
1856 mProcessNames.put(processName, info.uid, app);
1857 } else {
1858 // If this is a new package in the process, add the package to the list
1859 app.addPackage(info.packageName);
1860 }
1861
1862 // If the system is not ready yet, then hold off on starting this
1863 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001864 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001865 && !isAllowedWhileBooting(info)
1866 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 if (!mProcessesOnHold.contains(app)) {
1868 mProcessesOnHold.add(app);
1869 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001870 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 return app;
1872 }
1873
1874 startProcessLocked(app, hostingType, hostingNameStr);
1875 return (app.pid != 0) ? app : null;
1876 }
1877
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001878 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1879 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1880 }
1881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 private final void startProcessLocked(ProcessRecord app,
1883 String hostingType, String hostingNameStr) {
1884 if (app.pid > 0 && app.pid != MY_PID) {
1885 synchronized (mPidsSelfLocked) {
1886 mPidsSelfLocked.remove(app.pid);
1887 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1888 }
1889 app.pid = 0;
1890 }
1891
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001892 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1893 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001894 mProcessesOnHold.remove(app);
1895
1896 updateCpuStats();
1897
1898 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1899 mProcDeaths[0] = 0;
1900
1901 try {
1902 int uid = app.info.uid;
1903 int[] gids = null;
1904 try {
1905 gids = mContext.getPackageManager().getPackageGids(
1906 app.info.packageName);
1907 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001908 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 }
1910 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1911 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1912 && mTopComponent != null
1913 && app.processName.equals(mTopComponent.getPackageName())) {
1914 uid = 0;
1915 }
1916 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1917 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1918 uid = 0;
1919 }
1920 }
1921 int debugFlags = 0;
1922 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1923 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1924 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001925 // Run the app in safe mode if its manifest requests so or the
1926 // system is booted in safe mode.
1927 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1928 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001929 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001931 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1932 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1933 }
1934 if ("1".equals(SystemProperties.get("debug.assert"))) {
1935 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1936 }
1937 int pid = Process.start("android.app.ActivityThread",
1938 mSimpleProcessManagement ? app.processName : null, uid, uid,
1939 gids, debugFlags, null);
1940 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1941 synchronized (bs) {
1942 if (bs.isOnBattery()) {
1943 app.batteryStats.incStartsLocked();
1944 }
1945 }
1946
Doug Zongker2bec3d42009-12-04 12:52:44 -08001947 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 app.processName, hostingType,
1949 hostingNameStr != null ? hostingNameStr : "");
1950
1951 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001952 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 }
1954
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001955 StringBuilder buf = mStringBuilder;
1956 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 buf.append("Start proc ");
1958 buf.append(app.processName);
1959 buf.append(" for ");
1960 buf.append(hostingType);
1961 if (hostingNameStr != null) {
1962 buf.append(" ");
1963 buf.append(hostingNameStr);
1964 }
1965 buf.append(": pid=");
1966 buf.append(pid);
1967 buf.append(" uid=");
1968 buf.append(uid);
1969 buf.append(" gids={");
1970 if (gids != null) {
1971 for (int gi=0; gi<gids.length; gi++) {
1972 if (gi != 0) buf.append(", ");
1973 buf.append(gids[gi]);
1974
1975 }
1976 }
1977 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001978 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 if (pid == 0 || pid == MY_PID) {
1980 // Processes are being emulated with threads.
1981 app.pid = MY_PID;
1982 app.removed = false;
1983 mStartingProcesses.add(app);
1984 } else if (pid > 0) {
1985 app.pid = pid;
1986 app.removed = false;
1987 synchronized (mPidsSelfLocked) {
1988 this.mPidsSelfLocked.put(pid, app);
1989 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1990 msg.obj = app;
1991 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1992 }
1993 } else {
1994 app.pid = 0;
1995 RuntimeException e = new RuntimeException(
1996 "Failure starting process " + app.processName
1997 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001998 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 }
2000 } catch (RuntimeException e) {
2001 // XXX do better error recovery.
2002 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002003 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 }
2005 }
2006
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002007 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002008 if (resumed) {
2009 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2010 } else {
2011 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2012 }
2013 }
2014
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002015 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002016 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2017 && mTopAction == null) {
2018 // We are running in factory test mode, but unable to find
2019 // the factory test app, so just sit around displaying the
2020 // error message and don't try to start anything.
2021 return false;
2022 }
2023 Intent intent = new Intent(
2024 mTopAction,
2025 mTopData != null ? Uri.parse(mTopData) : null);
2026 intent.setComponent(mTopComponent);
2027 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2028 intent.addCategory(Intent.CATEGORY_HOME);
2029 }
2030 ActivityInfo aInfo =
2031 intent.resolveActivityInfo(mContext.getPackageManager(),
2032 STOCK_PM_FLAGS);
2033 if (aInfo != null) {
2034 intent.setComponent(new ComponentName(
2035 aInfo.applicationInfo.packageName, aInfo.name));
2036 // Don't do this if the home app is currently being
2037 // instrumented.
2038 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2039 aInfo.applicationInfo.uid);
2040 if (app == null || app.instrumentationClass == null) {
2041 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002042 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002043 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002044 }
2045 }
2046
2047
2048 return true;
2049 }
2050
2051 /**
2052 * Starts the "new version setup screen" if appropriate.
2053 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002054 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002055 // Only do this once per boot.
2056 if (mCheckedForSetup) {
2057 return;
2058 }
2059
2060 // We will show this screen if the current one is a different
2061 // version than the last one shown, and we are not running in
2062 // low-level factory test mode.
2063 final ContentResolver resolver = mContext.getContentResolver();
2064 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2065 Settings.Secure.getInt(resolver,
2066 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2067 mCheckedForSetup = true;
2068
2069 // See if we should be showing the platform update setup UI.
2070 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2071 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2072 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2073
2074 // We don't allow third party apps to replace this.
2075 ResolveInfo ri = null;
2076 for (int i=0; ris != null && i<ris.size(); i++) {
2077 if ((ris.get(i).activityInfo.applicationInfo.flags
2078 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2079 ri = ris.get(i);
2080 break;
2081 }
2082 }
2083
2084 if (ri != null) {
2085 String vers = ri.activityInfo.metaData != null
2086 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2087 : null;
2088 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2089 vers = ri.activityInfo.applicationInfo.metaData.getString(
2090 Intent.METADATA_SETUP_VERSION);
2091 }
2092 String lastVers = Settings.Secure.getString(
2093 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2094 if (vers != null && !vers.equals(lastVers)) {
2095 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2096 intent.setComponent(new ComponentName(
2097 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002098 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002099 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002100 }
2101 }
2102 }
2103 }
2104
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002105 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002106 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002107 }
2108
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002109 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002110 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002111 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2112 }
2113 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002114
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002115 public void setFrontActivityScreenCompatMode(int mode) {
2116 synchronized (this) {
2117 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2118 }
2119 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002120
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002121 public int getPackageScreenCompatMode(String packageName) {
2122 synchronized (this) {
2123 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2124 }
2125 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002126
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002127 public void setPackageScreenCompatMode(String packageName, int mode) {
2128 synchronized (this) {
2129 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002130 }
2131 }
2132
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002133 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002134 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002135
2136 final int identHash = System.identityHashCode(r);
2137 updateUsageStats(r, true);
2138
2139 int i = mWatchers.beginBroadcast();
2140 while (i > 0) {
2141 i--;
2142 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2143 if (w != null) {
2144 try {
2145 w.activityResuming(identHash);
2146 } catch (RemoteException e) {
2147 }
2148 }
2149 }
2150 mWatchers.finishBroadcast();
2151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152
Jeff Sharkeya4620792011-05-20 15:29:23 -07002153 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2154 int i = mProcessObservers.beginBroadcast();
2155 while (i > 0) {
2156 i--;
2157 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2158 if (observer != null) {
2159 try {
2160 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2161 } catch (RemoteException e) {
2162 }
2163 }
2164 }
2165 mProcessObservers.finishBroadcast();
2166 }
2167
2168 private void dispatchProcessDied(int pid, int uid) {
2169 int i = mProcessObservers.beginBroadcast();
2170 while (i > 0) {
2171 i--;
2172 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2173 if (observer != null) {
2174 try {
2175 observer.onProcessDied(pid, uid);
2176 } catch (RemoteException e) {
2177 }
2178 }
2179 }
2180 mProcessObservers.finishBroadcast();
2181 }
2182
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002183 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002184 final int N = mPendingActivityLaunches.size();
2185 if (N <= 0) {
2186 return;
2187 }
2188 for (int i=0; i<N; i++) {
2189 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002190 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002191 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2192 doResume && i == (N-1));
2193 }
2194 mPendingActivityLaunches.clear();
2195 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002196
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002197 public final int startActivity(IApplicationThread caller,
2198 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2199 int grantedMode, IBinder resultTo,
2200 String resultWho, int requestCode, boolean onlyIfNeeded,
2201 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002202 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002203 grantedUriPermissions, grantedMode, resultTo, resultWho,
2204 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002205 }
2206
2207 public final WaitResult startActivityAndWait(IApplicationThread caller,
2208 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2209 int grantedMode, IBinder resultTo,
2210 String resultWho, int requestCode, boolean onlyIfNeeded,
2211 boolean debug) {
2212 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002213 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002214 grantedUriPermissions, grantedMode, resultTo, resultWho,
2215 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002216 return res;
2217 }
2218
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002219 public final int startActivityWithConfig(IApplicationThread caller,
2220 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2221 int grantedMode, IBinder resultTo,
2222 String resultWho, int requestCode, boolean onlyIfNeeded,
2223 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002224 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002225 grantedUriPermissions, grantedMode, resultTo, resultWho,
2226 requestCode, onlyIfNeeded, debug, null, config);
2227 }
2228
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002229 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002230 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002231 IBinder resultTo, String resultWho, int requestCode,
2232 int flagsMask, int flagsValues) {
2233 // Refuse possible leaked file descriptors
2234 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2235 throw new IllegalArgumentException("File descriptors passed in Intent");
2236 }
2237
2238 IIntentSender sender = intent.getTarget();
2239 if (!(sender instanceof PendingIntentRecord)) {
2240 throw new IllegalArgumentException("Bad PendingIntent object");
2241 }
2242
2243 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002244
2245 synchronized (this) {
2246 // If this is coming from the currently resumed activity, it is
2247 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002248 if (mMainStack.mResumedActivity != null
2249 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002250 Binder.getCallingUid()) {
2251 mAppSwitchesAllowedTime = 0;
2252 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002253 }
2254
2255 return pir.sendInner(0, fillInIntent, resolvedType,
2256 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2257 }
2258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 public boolean startNextMatchingActivity(IBinder callingActivity,
2260 Intent intent) {
2261 // Refuse possible leaked file descriptors
2262 if (intent != null && intent.hasFileDescriptors() == true) {
2263 throw new IllegalArgumentException("File descriptors passed in Intent");
2264 }
2265
2266 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002267 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 if (index < 0) {
2269 return false;
2270 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002271 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 if (r.app == null || r.app.thread == null) {
2273 // The caller is not running... d'oh!
2274 return false;
2275 }
2276 intent = new Intent(intent);
2277 // The caller is not allowed to change the data.
2278 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2279 // And we are resetting to find the next component...
2280 intent.setComponent(null);
2281
2282 ActivityInfo aInfo = null;
2283 try {
2284 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002285 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002287 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288
2289 // Look for the original activity in the list...
2290 final int N = resolves != null ? resolves.size() : 0;
2291 for (int i=0; i<N; i++) {
2292 ResolveInfo rInfo = resolves.get(i);
2293 if (rInfo.activityInfo.packageName.equals(r.packageName)
2294 && rInfo.activityInfo.name.equals(r.info.name)) {
2295 // We found the current one... the next matching is
2296 // after it.
2297 i++;
2298 if (i<N) {
2299 aInfo = resolves.get(i).activityInfo;
2300 }
2301 break;
2302 }
2303 }
2304 } catch (RemoteException e) {
2305 }
2306
2307 if (aInfo == null) {
2308 // Nobody who is next!
2309 return false;
2310 }
2311
2312 intent.setComponent(new ComponentName(
2313 aInfo.applicationInfo.packageName, aInfo.name));
2314 intent.setFlags(intent.getFlags()&~(
2315 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2316 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2317 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2318 Intent.FLAG_ACTIVITY_NEW_TASK));
2319
2320 // Okay now we need to start the new activity, replacing the
2321 // currently running activity. This is a little tricky because
2322 // we want to start the new one as if the current one is finished,
2323 // but not finish the current one first so that there is no flicker.
2324 // And thus...
2325 final boolean wasFinishing = r.finishing;
2326 r.finishing = true;
2327
2328 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002329 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 final String resultWho = r.resultWho;
2331 final int requestCode = r.requestCode;
2332 r.resultTo = null;
2333 if (resultTo != null) {
2334 resultTo.removeResultsLocked(r, resultWho, requestCode);
2335 }
2336
2337 final long origId = Binder.clearCallingIdentity();
2338 // XXX we are not dealing with propagating grantedUriPermissions...
2339 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002340 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002341 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002342 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 Binder.restoreCallingIdentity(origId);
2344
2345 r.finishing = wasFinishing;
2346 if (res != START_SUCCESS) {
2347 return false;
2348 }
2349 return true;
2350 }
2351 }
2352
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002353 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 Intent intent, String resolvedType, IBinder resultTo,
2355 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002356
2357 // This is so super not safe, that only the system (or okay root)
2358 // can do it.
2359 final int callingUid = Binder.getCallingUid();
2360 if (callingUid != 0 && callingUid != Process.myUid()) {
2361 throw new SecurityException(
2362 "startActivityInPackage only available to the system");
2363 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002365 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2366 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2367 }
2368
2369 public final int startActivities(IApplicationThread caller,
2370 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2371 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2372 }
2373
2374 public final int startActivitiesInPackage(int uid,
2375 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2376
2377 // This is so super not safe, that only the system (or okay root)
2378 // can do it.
2379 final int callingUid = Binder.getCallingUid();
2380 if (callingUid != 0 && callingUid != Process.myUid()) {
2381 throw new SecurityException(
2382 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 }
2384
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002385 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 }
2387
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002388 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002390 // Quick case: check if the top-most recent task is the same.
2391 if (N > 0 && mRecentTasks.get(0) == task) {
2392 return;
2393 }
2394 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 for (int i=0; i<N; i++) {
2396 TaskRecord tr = mRecentTasks.get(i);
2397 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2398 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2399 mRecentTasks.remove(i);
2400 i--;
2401 N--;
2402 if (task.intent == null) {
2403 // If the new recent task we are adding is not fully
2404 // specified, then replace it with the existing recent task.
2405 task = tr;
2406 }
2407 }
2408 }
2409 if (N >= MAX_RECENT_TASKS) {
2410 mRecentTasks.remove(N-1);
2411 }
2412 mRecentTasks.add(0, task);
2413 }
2414
2415 public void setRequestedOrientation(IBinder token,
2416 int requestedOrientation) {
2417 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002418 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 if (index < 0) {
2420 return;
2421 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002422 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 final long origId = Binder.clearCallingIdentity();
2424 mWindowManager.setAppOrientation(r, requestedOrientation);
2425 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002426 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002427 r.mayFreezeScreenLocked(r.app) ? r : null);
2428 if (config != null) {
2429 r.frozenBeforeDestroy = true;
2430 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002431 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002432 }
2433 }
2434 Binder.restoreCallingIdentity(origId);
2435 }
2436 }
2437
2438 public int getRequestedOrientation(IBinder token) {
2439 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002440 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 if (index < 0) {
2442 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2443 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002444 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002445 return mWindowManager.getAppOrientation(r);
2446 }
2447 }
2448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 /**
2450 * This is the internal entry point for handling Activity.finish().
2451 *
2452 * @param token The Binder token referencing the Activity we want to finish.
2453 * @param resultCode Result code, if any, from this Activity.
2454 * @param resultData Result data (Intent), if any, from this Activity.
2455 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002456 * @return Returns true if the activity successfully finished, or false if it is still running.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 */
2458 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2459 // Refuse possible leaked file descriptors
2460 if (resultData != null && resultData.hasFileDescriptors() == true) {
2461 throw new IllegalArgumentException("File descriptors passed in Intent");
2462 }
2463
2464 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002465 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002466 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002467 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 if (next != null) {
2469 // ask watcher if this is allowed
2470 boolean resumeOK = true;
2471 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002472 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002474 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 }
2476
2477 if (!resumeOK) {
2478 return false;
2479 }
2480 }
2481 }
2482 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002483 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 resultData, "app-request");
2485 Binder.restoreCallingIdentity(origId);
2486 return res;
2487 }
2488 }
2489
Dianne Hackborn860755f2010-06-03 18:47:52 -07002490 public final void finishHeavyWeightApp() {
2491 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2492 != PackageManager.PERMISSION_GRANTED) {
2493 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2494 + Binder.getCallingPid()
2495 + ", uid=" + Binder.getCallingUid()
2496 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2497 Slog.w(TAG, msg);
2498 throw new SecurityException(msg);
2499 }
2500
2501 synchronized(this) {
2502 if (mHeavyWeightProcess == null) {
2503 return;
2504 }
2505
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002506 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002507 mHeavyWeightProcess.activities);
2508 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002509 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002510 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002511 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002512 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002513 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002514 null, "finish-heavy");
2515 }
2516 }
2517 }
2518
2519 mHeavyWeightProcess = null;
2520 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2521 }
2522 }
2523
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002524 public void crashApplication(int uid, int initialPid, String packageName,
2525 String message) {
2526 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2527 != PackageManager.PERMISSION_GRANTED) {
2528 String msg = "Permission Denial: crashApplication() from pid="
2529 + Binder.getCallingPid()
2530 + ", uid=" + Binder.getCallingUid()
2531 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2532 Slog.w(TAG, msg);
2533 throw new SecurityException(msg);
2534 }
2535
2536 synchronized(this) {
2537 ProcessRecord proc = null;
2538
2539 // Figure out which process to kill. We don't trust that initialPid
2540 // still has any relation to current pids, so must scan through the
2541 // list.
2542 synchronized (mPidsSelfLocked) {
2543 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2544 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2545 if (p.info.uid != uid) {
2546 continue;
2547 }
2548 if (p.pid == initialPid) {
2549 proc = p;
2550 break;
2551 }
2552 for (String str : p.pkgList) {
2553 if (str.equals(packageName)) {
2554 proc = p;
2555 }
2556 }
2557 }
2558 }
2559
2560 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002561 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002562 + " initialPid=" + initialPid
2563 + " packageName=" + packageName);
2564 return;
2565 }
2566
2567 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002568 if (proc.pid == Process.myPid()) {
2569 Log.w(TAG, "crashApplication: trying to crash self!");
2570 return;
2571 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002572 long ident = Binder.clearCallingIdentity();
2573 try {
2574 proc.thread.scheduleCrash(message);
2575 } catch (RemoteException e) {
2576 }
2577 Binder.restoreCallingIdentity(ident);
2578 }
2579 }
2580 }
2581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002582 public final void finishSubActivity(IBinder token, String resultWho,
2583 int requestCode) {
2584 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002585 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002586 if (index < 0) {
2587 return;
2588 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002589 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590
2591 final long origId = Binder.clearCallingIdentity();
2592
2593 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2595 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596 if (r.resultTo == self && r.requestCode == requestCode) {
2597 if ((r.resultWho == null && resultWho == null) ||
2598 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002599 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600 Activity.RESULT_CANCELED, null, "request-sub");
2601 }
2602 }
2603 }
2604
2605 Binder.restoreCallingIdentity(origId);
2606 }
2607 }
2608
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002609 public boolean willActivityBeVisible(IBinder token) {
2610 synchronized(this) {
2611 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002612 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2613 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002614 if (r == token) {
2615 return true;
2616 }
2617 if (r.fullscreen && !r.finishing) {
2618 return false;
2619 }
2620 }
2621 return true;
2622 }
2623 }
2624
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002625 public void overridePendingTransition(IBinder token, String packageName,
2626 int enterAnim, int exitAnim) {
2627 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002628 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002629 if (index < 0) {
2630 return;
2631 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002632 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002633
2634 final long origId = Binder.clearCallingIdentity();
2635
2636 if (self.state == ActivityState.RESUMED
2637 || self.state == ActivityState.PAUSING) {
2638 mWindowManager.overridePendingAppTransition(packageName,
2639 enterAnim, exitAnim);
2640 }
2641
2642 Binder.restoreCallingIdentity(origId);
2643 }
2644 }
2645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002646 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 * Main function for removing an existing process from the activity manager
2648 * as a result of that process going away. Clears out all connections
2649 * to the process.
2650 */
2651 private final void handleAppDiedLocked(ProcessRecord app,
2652 boolean restarting) {
2653 cleanUpApplicationRecordLocked(app, restarting, -1);
2654 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002655 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 }
2657
2658 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002659 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2660 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2661 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002663 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2664 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 }
2666
2667 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002668 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002669
2670 boolean atTop = true;
2671 boolean hasVisibleActivities = false;
2672
2673 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002674 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002675 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 TAG, "Removing app " + app + " from history with " + i + " entries");
2677 while (i > 0) {
2678 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002679 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002680 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002681 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2682 if (r.app == app) {
2683 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002684 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 TAG, "Removing this entry! frozen=" + r.haveState
2686 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002687 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002688 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002689 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 mWindowManager.removeAppToken(r);
2691 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002692 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002693 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002694 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695
2696 } else {
2697 // We have the current state for this activity, so
2698 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002699 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002700 TAG, "Keeping entry, setting app to null");
2701 if (r.visible) {
2702 hasVisibleActivities = true;
2703 }
2704 r.app = null;
2705 r.nowVisible = false;
2706 if (!r.haveState) {
2707 r.icicle = null;
2708 }
2709 }
2710
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002711 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 r.state = ActivityState.STOPPED;
2713 }
2714 atTop = false;
2715 }
2716
2717 app.activities.clear();
2718
2719 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002720 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 + " running instrumentation " + app.instrumentationClass);
2722 Bundle info = new Bundle();
2723 info.putString("shortMsg", "Process crashed.");
2724 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2725 }
2726
2727 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002728 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002729 // If there was nothing to resume, and we are not already
2730 // restarting this process, but there is a visible activity that
2731 // is hosted by the process... then make sure all visible
2732 // activities are running, taking care of restarting this
2733 // process.
2734 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002735 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 }
2737 }
2738 }
2739 }
2740
2741 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2742 IBinder threadBinder = thread.asBinder();
2743
2744 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002745 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2746 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2748 return i;
2749 }
2750 }
2751 return -1;
2752 }
2753
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002754 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 IApplicationThread thread) {
2756 if (thread == null) {
2757 return null;
2758 }
2759
2760 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002761 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 }
2763
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002764 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 IApplicationThread thread) {
2766
2767 mProcDeaths[0]++;
2768
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002769 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2770 synchronized (stats) {
2771 stats.noteProcessDiedLocked(app.info.uid, pid);
2772 }
2773
Magnus Edlund7bb25812010-02-24 15:45:06 +01002774 // Clean up already done if the process has been re-started.
2775 if (app.pid == pid && app.thread != null &&
2776 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002777 if (!app.killedBackground) {
2778 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2779 + ") has died.");
2780 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002781 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002782 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 TAG, "Dying app: " + app + ", pid: " + pid
2784 + ", thread: " + thread.asBinder());
2785 boolean doLowMem = app.instrumentationClass == null;
2786 handleAppDiedLocked(app, false);
2787
2788 if (doLowMem) {
2789 // If there are no longer any background processes running,
2790 // and the app that died was not running instrumentation,
2791 // then tell everyone we are now low on memory.
2792 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002793 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2794 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2796 haveBg = true;
2797 break;
2798 }
2799 }
2800
2801 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002802 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002803 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002804 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002805 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2806 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002807 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002808 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2809 // The low memory report is overriding any current
2810 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002811 // heavy/important/visible/foreground processes first.
2812 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002813 rec.lastRequestedGc = 0;
2814 } else {
2815 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002817 rec.reportLowMemory = true;
2818 rec.lastLowMemory = now;
2819 mProcessesToGc.remove(rec);
2820 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 }
2822 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002823 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002824 }
2825 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002826 } else if (app.pid != pid) {
2827 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002828 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002829 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002830 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002831 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002832 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833 + thread.asBinder());
2834 }
2835 }
2836
Dan Egnor42471dd2010-01-07 17:25:22 -08002837 /**
2838 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002839 * @param clearTraces causes the dump file to be erased prior to the new
2840 * traces being written, if true; when false, the new traces will be
2841 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002842 * @param firstPids of dalvik VM processes to dump stack traces for first
2843 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002844 * @return file containing stack traces, or null if no dump file is configured
2845 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002846 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2847 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002848 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2849 if (tracesPath == null || tracesPath.length() == 0) {
2850 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002852
2853 File tracesFile = new File(tracesPath);
2854 try {
2855 File tracesDir = tracesFile.getParentFile();
2856 if (!tracesDir.exists()) tracesFile.mkdirs();
2857 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2858
Christopher Tate6ee412d2010-05-28 12:01:56 -07002859 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002860 tracesFile.createNewFile();
2861 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2862 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002863 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002864 return null;
2865 }
2866
2867 // Use a FileObserver to detect when traces finish writing.
2868 // The order of traces is considered important to maintain for legibility.
2869 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2870 public synchronized void onEvent(int event, String path) { notify(); }
2871 };
2872
2873 try {
2874 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002875
2876 // First collect all of the stacks of the most important pids.
2877 try {
2878 int num = firstPids.size();
2879 for (int i = 0; i < num; i++) {
2880 synchronized (observer) {
2881 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2882 observer.wait(200); // Wait for write-close, give up after 200msec
2883 }
2884 }
2885 } catch (InterruptedException e) {
2886 Log.wtf(TAG, e);
2887 }
2888
2889 // Next measure CPU usage.
2890 if (processStats != null) {
2891 processStats.init();
2892 System.gc();
2893 processStats.update();
2894 try {
2895 synchronized (processStats) {
2896 processStats.wait(500); // measure over 1/2 second.
2897 }
2898 } catch (InterruptedException e) {
2899 }
2900 processStats.update();
2901
2902 // We'll take the stack crawls of just the top apps using CPU.
2903 final int N = processStats.countWorkingStats();
2904 int numProcs = 0;
2905 for (int i=0; i<N && numProcs<5; i++) {
2906 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2907 if (lastPids.indexOfKey(stats.pid) >= 0) {
2908 numProcs++;
2909 try {
2910 synchronized (observer) {
2911 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2912 observer.wait(200); // Wait for write-close, give up after 200msec
2913 }
2914 } catch (InterruptedException e) {
2915 Log.wtf(TAG, e);
2916 }
2917
2918 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002919 }
2920 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002921
2922 return tracesFile;
2923
Dan Egnor42471dd2010-01-07 17:25:22 -08002924 } finally {
2925 observer.stopWatching();
2926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 }
2928
Jeff Brown4d94a762010-09-23 11:33:28 -07002929 private final class AppNotResponding implements Runnable {
2930 private final ProcessRecord mApp;
2931 private final String mAnnotation;
2932
2933 public AppNotResponding(ProcessRecord app, String annotation) {
2934 mApp = app;
2935 mAnnotation = annotation;
2936 }
2937
2938 @Override
2939 public void run() {
2940 appNotResponding(mApp, null, null, mAnnotation);
2941 }
2942 }
2943
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002944 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2945 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002946 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2947 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2948
Dianne Hackborn287952c2010-09-22 22:34:31 -07002949 if (mController != null) {
2950 try {
2951 // 0 == continue, -1 = kill process immediately
2952 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2953 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2954 } catch (RemoteException e) {
2955 mController = null;
2956 }
2957 }
2958
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002959 long anrTime = SystemClock.uptimeMillis();
2960 if (MONITOR_CPU_USAGE) {
2961 updateCpuStatsNow();
2962 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002963
2964 synchronized (this) {
2965 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2966 if (mShuttingDown) {
2967 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2968 return;
2969 } else if (app.notResponding) {
2970 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2971 return;
2972 } else if (app.crashing) {
2973 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2974 return;
2975 }
2976
2977 // In case we come through here for the same app before completing
2978 // this one, mark as anring now so we will bail out.
2979 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002980
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002981 // Log the ANR to the event log.
2982 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2983 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002984
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002985 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002986 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002987
2988 int parentPid = app.pid;
2989 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002990 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002991
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002992 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002993
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002994 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2995 ProcessRecord r = mLruProcesses.get(i);
2996 if (r != null && r.thread != null) {
2997 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002998 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2999 if (r.persistent) {
3000 firstPids.add(pid);
3001 } else {
3002 lastPids.put(pid, Boolean.TRUE);
3003 }
3004 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 }
3007 }
3008
Dan Egnor42471dd2010-01-07 17:25:22 -08003009 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003010 StringBuilder info = mStringBuilder;
3011 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003012 info.append("ANR in ").append(app.processName);
3013 if (activity != null && activity.shortComponentName != null) {
3014 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003015 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003016 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003018 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003019 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003020 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003021 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003023
Dianne Hackborn287952c2010-09-22 22:34:31 -07003024 final ProcessStats processStats = new ProcessStats(true);
3025
3026 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3027
Dan Egnor42471dd2010-01-07 17:25:22 -08003028 String cpuInfo = null;
3029 if (MONITOR_CPU_USAGE) {
3030 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003031 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003032 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003033 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003034 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003035 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 }
3037
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003038 info.append(processStats.printCurrentState(anrTime));
3039
Joe Onorato8a9b2202010-02-26 18:56:32 -08003040 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003041 if (tracesFile == null) {
3042 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3043 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3044 }
3045
3046 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3047
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003048 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003050 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3051 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003052 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003053 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3054 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 }
3056 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003057 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003058 }
3059 }
3060
Dan Egnor42471dd2010-01-07 17:25:22 -08003061 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3062 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3063 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003064
3065 synchronized (this) {
3066 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003067 Slog.w(TAG, "Killing " + app + ": background ANR");
3068 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3069 app.processName, app.setAdj, "background ANR");
3070 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003071 return;
3072 }
3073
3074 // Set the app's notResponding state, and look up the errorReportReceiver
3075 makeAppNotRespondingLocked(app,
3076 activity != null ? activity.shortComponentName : null,
3077 annotation != null ? "ANR " + annotation : "ANR",
3078 info.toString());
3079
3080 // Bring up the infamous App Not Responding dialog
3081 Message msg = Message.obtain();
3082 HashMap map = new HashMap();
3083 msg.what = SHOW_NOT_RESPONDING_MSG;
3084 msg.obj = map;
3085 map.put("app", app);
3086 if (activity != null) {
3087 map.put("activity", activity);
3088 }
3089
3090 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003091 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003092 }
3093
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003094 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3095 if (!mLaunchWarningShown) {
3096 mLaunchWarningShown = true;
3097 mHandler.post(new Runnable() {
3098 @Override
3099 public void run() {
3100 synchronized (ActivityManagerService.this) {
3101 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3102 d.show();
3103 mHandler.postDelayed(new Runnable() {
3104 @Override
3105 public void run() {
3106 synchronized (ActivityManagerService.this) {
3107 d.dismiss();
3108 mLaunchWarningShown = false;
3109 }
3110 }
3111 }, 4000);
3112 }
3113 }
3114 });
3115 }
3116 }
3117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 public boolean clearApplicationUserData(final String packageName,
3119 final IPackageDataObserver observer) {
3120 int uid = Binder.getCallingUid();
3121 int pid = Binder.getCallingPid();
3122 long callingId = Binder.clearCallingIdentity();
3123 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003124 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003125 int pkgUid = -1;
3126 synchronized(this) {
3127 try {
3128 pkgUid = pm.getPackageUid(packageName);
3129 } catch (RemoteException e) {
3130 }
3131 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003132 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003133 return false;
3134 }
3135 if (uid == pkgUid || checkComponentPermission(
3136 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003137 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003138 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003139 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003140 } else {
3141 throw new SecurityException(pid+" does not have permission:"+
3142 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3143 "for process:"+packageName);
3144 }
3145 }
3146
3147 try {
3148 //clear application user data
3149 pm.clearApplicationUserData(packageName, observer);
3150 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3151 Uri.fromParts("package", packageName, null));
3152 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003153 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3154 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003155 } catch (RemoteException e) {
3156 }
3157 } finally {
3158 Binder.restoreCallingIdentity(callingId);
3159 }
3160 return true;
3161 }
3162
Dianne Hackborn03abb812010-01-04 18:43:19 -08003163 public void killBackgroundProcesses(final String packageName) {
3164 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3165 != PackageManager.PERMISSION_GRANTED &&
3166 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3167 != PackageManager.PERMISSION_GRANTED) {
3168 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003169 + Binder.getCallingPid()
3170 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003171 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003172 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 throw new SecurityException(msg);
3174 }
3175
3176 long callingId = Binder.clearCallingIdentity();
3177 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003178 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 int pkgUid = -1;
3180 synchronized(this) {
3181 try {
3182 pkgUid = pm.getPackageUid(packageName);
3183 } catch (RemoteException e) {
3184 }
3185 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003186 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003187 return;
3188 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003189 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003190 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003191 }
3192 } finally {
3193 Binder.restoreCallingIdentity(callingId);
3194 }
3195 }
3196
3197 public void forceStopPackage(final String packageName) {
3198 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3199 != PackageManager.PERMISSION_GRANTED) {
3200 String msg = "Permission Denial: forceStopPackage() from pid="
3201 + Binder.getCallingPid()
3202 + ", uid=" + Binder.getCallingUid()
3203 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003204 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003205 throw new SecurityException(msg);
3206 }
3207
3208 long callingId = Binder.clearCallingIdentity();
3209 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003210 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003211 int pkgUid = -1;
3212 synchronized(this) {
3213 try {
3214 pkgUid = pm.getPackageUid(packageName);
3215 } catch (RemoteException e) {
3216 }
3217 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003218 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003219 return;
3220 }
3221 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003222 try {
3223 pm.setPackageStoppedState(packageName, true);
3224 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003225 } catch (IllegalArgumentException e) {
3226 Slog.w(TAG, "Failed trying to unstop package "
3227 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229 }
3230 } finally {
3231 Binder.restoreCallingIdentity(callingId);
3232 }
3233 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003234
3235 /*
3236 * The pkg name and uid have to be specified.
3237 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3238 */
3239 public void killApplicationWithUid(String pkg, int uid) {
3240 if (pkg == null) {
3241 return;
3242 }
3243 // Make sure the uid is valid.
3244 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003245 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003246 return;
3247 }
3248 int callerUid = Binder.getCallingUid();
3249 // Only the system server can kill an application
3250 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003251 // Post an aysnc message to kill the application
3252 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3253 msg.arg1 = uid;
3254 msg.arg2 = 0;
3255 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003256 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003257 } else {
3258 throw new SecurityException(callerUid + " cannot kill pkg: " +
3259 pkg);
3260 }
3261 }
3262
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003263 public void closeSystemDialogs(String reason) {
3264 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003265 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003266 if (reason != null) {
3267 intent.putExtra("reason", reason);
3268 }
3269
3270 final int uid = Binder.getCallingUid();
3271 final long origId = Binder.clearCallingIdentity();
3272 synchronized (this) {
3273 int i = mWatchers.beginBroadcast();
3274 while (i > 0) {
3275 i--;
3276 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3277 if (w != null) {
3278 try {
3279 w.closingSystemDialogs(reason);
3280 } catch (RemoteException e) {
3281 }
3282 }
3283 }
3284 mWatchers.finishBroadcast();
3285
Dianne Hackbornffa42482009-09-23 22:20:11 -07003286 mWindowManager.closeSystemDialogs(reason);
3287
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003288 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3289 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003290 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003291 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003292 Activity.RESULT_CANCELED, null, "close-sys");
3293 }
3294 }
3295
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003296 broadcastIntentLocked(null, null, intent, null,
3297 null, 0, null, null, null, false, false, -1, uid);
3298 }
3299 Binder.restoreCallingIdentity(origId);
3300 }
3301
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003302 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003303 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003304 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3305 for (int i=pids.length-1; i>=0; i--) {
3306 infos[i] = new Debug.MemoryInfo();
3307 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003308 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003309 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003310 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003311
3312 public void killApplicationProcess(String processName, int uid) {
3313 if (processName == null) {
3314 return;
3315 }
3316
3317 int callerUid = Binder.getCallingUid();
3318 // Only the system server can kill an application
3319 if (callerUid == Process.SYSTEM_UID) {
3320 synchronized (this) {
3321 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003322 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003323 try {
3324 app.thread.scheduleSuicide();
3325 } catch (RemoteException e) {
3326 // If the other end already died, then our work here is done.
3327 }
3328 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003329 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003330 + processName + " / " + uid);
3331 }
3332 }
3333 } else {
3334 throw new SecurityException(callerUid + " cannot kill app process: " +
3335 processName);
3336 }
3337 }
3338
Dianne Hackborn03abb812010-01-04 18:43:19 -08003339 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003340 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003341 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3342 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003343 if (!mProcessesReady) {
3344 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 intent.putExtra(Intent.EXTRA_UID, uid);
3347 broadcastIntentLocked(null, null, intent,
3348 null, null, 0, null, null, null,
3349 false, false, MY_PID, Process.SYSTEM_UID);
3350 }
3351
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003352 private final boolean killPackageProcessesLocked(String packageName, int uid,
3353 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003354 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003355
Dianne Hackborn03abb812010-01-04 18:43:19 -08003356 // Remove all processes this package may have touched: all with the
3357 // same UID (except for the system or root user), and all whose name
3358 // matches the package name.
3359 final String procNamePrefix = packageName + ":";
3360 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3361 final int NA = apps.size();
3362 for (int ia=0; ia<NA; ia++) {
3363 ProcessRecord app = apps.valueAt(ia);
3364 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003365 if (doit) {
3366 procs.add(app);
3367 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003368 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3369 || app.processName.equals(packageName)
3370 || app.processName.startsWith(procNamePrefix)) {
3371 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003372 if (!doit) {
3373 return true;
3374 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003375 app.removed = true;
3376 procs.add(app);
3377 }
3378 }
3379 }
3380 }
3381
3382 int N = procs.size();
3383 for (int i=0; i<N; i++) {
3384 removeProcessLocked(procs.get(i), callerWillRestart);
3385 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003386 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003387 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003388
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003389 private final boolean forceStopPackageLocked(String name, int uid,
3390 boolean callerWillRestart, boolean purgeCache, boolean doit) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003391 int i;
3392 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 if (uid < 0) {
3395 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003396 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 } catch (RemoteException e) {
3398 }
3399 }
3400
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003401 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003402 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003403
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003404 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3405 while (badApps.hasNext()) {
3406 SparseArray<Long> ba = badApps.next();
3407 if (ba.get(uid) != null) {
3408 badApps.remove();
3409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 }
3411 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003412
3413 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3414 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003416 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3417 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003419 if (!doit) {
3420 return true;
3421 }
3422 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003423 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003424 if (r.app != null) {
3425 r.app.removed = true;
3426 }
3427 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003428 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003429 }
3430 }
3431
3432 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3433 for (ServiceRecord service : mServices.values()) {
3434 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003435 if (!doit) {
3436 return true;
3437 }
3438 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003439 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003440 if (service.app != null) {
3441 service.app.removed = true;
3442 }
3443 service.app = null;
3444 services.add(service);
3445 }
3446 }
3447
3448 N = services.size();
3449 for (i=0; i<N; i++) {
3450 bringDownServiceLocked(services.get(i), true);
3451 }
3452
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003453 if (doit) {
3454 if (purgeCache) {
3455 AttributeCache ac = AttributeCache.instance();
3456 if (ac != null) {
3457 ac.removePackage(name);
3458 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003459 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003460 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003461 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003462
3463 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 }
3465
3466 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3467 final String name = app.processName;
3468 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003469 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 TAG, "Force removing process " + app + " (" + name
3471 + "/" + uid + ")");
3472
3473 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003474 if (mHeavyWeightProcess == app) {
3475 mHeavyWeightProcess = null;
3476 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3477 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003478 boolean needRestart = false;
3479 if (app.pid > 0 && app.pid != MY_PID) {
3480 int pid = app.pid;
3481 synchronized (mPidsSelfLocked) {
3482 mPidsSelfLocked.remove(pid);
3483 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3484 }
3485 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003486 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 Process.killProcess(pid);
3488
3489 if (app.persistent) {
3490 if (!callerWillRestart) {
3491 addAppLocked(app.info);
3492 } else {
3493 needRestart = true;
3494 }
3495 }
3496 } else {
3497 mRemovedProcesses.add(app);
3498 }
3499
3500 return needRestart;
3501 }
3502
3503 private final void processStartTimedOutLocked(ProcessRecord app) {
3504 final int pid = app.pid;
3505 boolean gone = false;
3506 synchronized (mPidsSelfLocked) {
3507 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3508 if (knownApp != null && knownApp.thread == null) {
3509 mPidsSelfLocked.remove(pid);
3510 gone = true;
3511 }
3512 }
3513
3514 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003515 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003516 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003517 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003519 if (mHeavyWeightProcess == app) {
3520 mHeavyWeightProcess = null;
3521 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3522 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003523 // Take care of any launching providers waiting for this process.
3524 checkAppInLaunchingProvidersLocked(app, true);
3525 // Take care of any services that are waiting for the process.
3526 for (int i=0; i<mPendingServices.size(); i++) {
3527 ServiceRecord sr = mPendingServices.get(i);
3528 if (app.info.uid == sr.appInfo.uid
3529 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003530 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003531 mPendingServices.remove(i);
3532 i--;
3533 bringDownServiceLocked(sr, true);
3534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003536 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3537 app.processName, app.setAdj, "start timeout");
3538 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003539 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003540 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003541 try {
3542 IBackupManager bm = IBackupManager.Stub.asInterface(
3543 ServiceManager.getService(Context.BACKUP_SERVICE));
3544 bm.agentDisconnected(app.info.packageName);
3545 } catch (RemoteException e) {
3546 // Can't happen; the backup manager is local
3547 }
3548 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003549 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003550 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003551 mPendingBroadcast.state = BroadcastRecord.IDLE;
3552 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003553 mPendingBroadcast = null;
3554 scheduleBroadcastsLocked();
3555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003557 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 }
3559 }
3560
3561 private final boolean attachApplicationLocked(IApplicationThread thread,
3562 int pid) {
3563
3564 // Find the application record that is being attached... either via
3565 // the pid if we are running in multiple processes, or just pull the
3566 // next app record if we are emulating process with anonymous threads.
3567 ProcessRecord app;
3568 if (pid != MY_PID && pid >= 0) {
3569 synchronized (mPidsSelfLocked) {
3570 app = mPidsSelfLocked.get(pid);
3571 }
3572 } else if (mStartingProcesses.size() > 0) {
3573 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003574 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575 } else {
3576 app = null;
3577 }
3578
3579 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003580 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003582 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003583 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003584 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 } else {
3586 try {
3587 thread.scheduleExit();
3588 } catch (Exception e) {
3589 // Ignore exceptions.
3590 }
3591 }
3592 return false;
3593 }
3594
3595 // If this application record is still attached to a previous
3596 // process, clean it up now.
3597 if (app.thread != null) {
3598 handleAppDiedLocked(app, true);
3599 }
3600
3601 // Tell the process all about itself.
3602
Joe Onorato8a9b2202010-02-26 18:56:32 -08003603 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003604 TAG, "Binding process pid " + pid + " to record " + app);
3605
3606 String processName = app.processName;
3607 try {
3608 thread.asBinder().linkToDeath(new AppDeathRecipient(
3609 app, pid, thread), 0);
3610 } catch (RemoteException e) {
3611 app.resetPackageList();
3612 startProcessLocked(app, "link fail", processName);
3613 return false;
3614 }
3615
Doug Zongker2bec3d42009-12-04 12:52:44 -08003616 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617
3618 app.thread = thread;
3619 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003620 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3621 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 app.forcingToForeground = null;
3623 app.foregroundServices = false;
3624 app.debugging = false;
3625
3626 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3627
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003628 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003629 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003630
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003631 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003632 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003633 }
3634
Joe Onorato8a9b2202010-02-26 18:56:32 -08003635 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003636 TAG, "New app record " + app
3637 + " thread=" + thread.asBinder() + " pid=" + pid);
3638 try {
3639 int testMode = IApplicationThread.DEBUG_OFF;
3640 if (mDebugApp != null && mDebugApp.equals(processName)) {
3641 testMode = mWaitForDebugger
3642 ? IApplicationThread.DEBUG_WAIT
3643 : IApplicationThread.DEBUG_ON;
3644 app.debugging = true;
3645 if (mDebugTransient) {
3646 mDebugApp = mOrigDebugApp;
3647 mWaitForDebugger = mOrigWaitForDebugger;
3648 }
3649 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003650
Christopher Tate181fafa2009-05-14 11:12:14 -07003651 // If the app is being launched for restore or full backup, set it up specially
3652 boolean isRestrictedBackupMode = false;
3653 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3654 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3655 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3656 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003657
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003658 ensurePackageDexOpt(app.instrumentationInfo != null
3659 ? app.instrumentationInfo.packageName
3660 : app.info.packageName);
3661 if (app.instrumentationClass != null) {
3662 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003663 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003664 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003665 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003666 ApplicationInfo appInfo = app.instrumentationInfo != null
3667 ? app.instrumentationInfo : app.info;
3668 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 app.instrumentationClass, app.instrumentationProfileFile,
3670 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003671 isRestrictedBackupMode || !normalMode,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003672 mConfiguration, compatibilityInfoForPackageLocked(appInfo),
3673 getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003674 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003675 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003676 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 } catch (Exception e) {
3678 // todo: Yikes! What should we do? For now we will try to
3679 // start another process, but that could easily get us in
3680 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003681 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682
3683 app.resetPackageList();
3684 startProcessLocked(app, "bind fail", processName);
3685 return false;
3686 }
3687
3688 // Remove this record from the list of starting applications.
3689 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003690 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3691 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 mProcessesOnHold.remove(app);
3693
3694 boolean badApp = false;
3695 boolean didSomething = false;
3696
3697 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003698 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003699 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003700 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3701 && processName.equals(hr.processName)) {
3702 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003703 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 didSomething = true;
3705 }
3706 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003707 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 + hr.intent.getComponent().flattenToShortString(), e);
3709 badApp = true;
3710 }
3711 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003712 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 }
3714 }
3715
3716 // Find any services that should be running in this process...
3717 if (!badApp && mPendingServices.size() > 0) {
3718 ServiceRecord sr = null;
3719 try {
3720 for (int i=0; i<mPendingServices.size(); i++) {
3721 sr = mPendingServices.get(i);
3722 if (app.info.uid != sr.appInfo.uid
3723 || !processName.equals(sr.processName)) {
3724 continue;
3725 }
3726
3727 mPendingServices.remove(i);
3728 i--;
3729 realStartServiceLocked(sr, app);
3730 didSomething = true;
3731 }
3732 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003733 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003734 + sr.shortName, e);
3735 badApp = true;
3736 }
3737 }
3738
3739 // Check if the next broadcast receiver is in this process...
3740 BroadcastRecord br = mPendingBroadcast;
3741 if (!badApp && br != null && br.curApp == app) {
3742 try {
3743 mPendingBroadcast = null;
3744 processCurBroadcastLocked(br, app);
3745 didSomething = true;
3746 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003747 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748 + br.curComponent.flattenToShortString(), e);
3749 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003750 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003751 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3752 br.resultExtras, br.resultAbort, true);
3753 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003754 // We need to reset the state if we fails to start the receiver.
3755 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003756 }
3757 }
3758
Christopher Tate181fafa2009-05-14 11:12:14 -07003759 // Check whether the next backup agent is in this process...
3760 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003761 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003762 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003763 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003764 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3765 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3766 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003767 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003768 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003769 e.printStackTrace();
3770 }
3771 }
3772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 if (badApp) {
3774 // todo: Also need to kill application to deal with all
3775 // kinds of exceptions.
3776 handleAppDiedLocked(app, false);
3777 return false;
3778 }
3779
3780 if (!didSomething) {
3781 updateOomAdjLocked();
3782 }
3783
3784 return true;
3785 }
3786
3787 public final void attachApplication(IApplicationThread thread) {
3788 synchronized (this) {
3789 int callingPid = Binder.getCallingPid();
3790 final long origId = Binder.clearCallingIdentity();
3791 attachApplicationLocked(thread, callingPid);
3792 Binder.restoreCallingIdentity(origId);
3793 }
3794 }
3795
Dianne Hackborne88846e2009-09-30 21:34:25 -07003796 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003798 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 Binder.restoreCallingIdentity(origId);
3800 }
3801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003803 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003804 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 mWindowManager.enableScreenAfterBoot();
3806 }
3807
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003808 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003809 IntentFilter pkgFilter = new IntentFilter();
3810 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3811 pkgFilter.addDataScheme("package");
3812 mContext.registerReceiver(new BroadcastReceiver() {
3813 @Override
3814 public void onReceive(Context context, Intent intent) {
3815 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3816 if (pkgs != null) {
3817 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003818 synchronized (ActivityManagerService.this) {
3819 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3820 setResultCode(Activity.RESULT_OK);
3821 return;
3822 }
3823 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003824 }
3825 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003826 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003827 }, pkgFilter);
3828
3829 synchronized (this) {
3830 // Ensure that any processes we had put on hold are now started
3831 // up.
3832 final int NP = mProcessesOnHold.size();
3833 if (NP > 0) {
3834 ArrayList<ProcessRecord> procs =
3835 new ArrayList<ProcessRecord>(mProcessesOnHold);
3836 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003837 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3838 + procs.get(ip));
3839 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003840 }
3841 }
3842
3843 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003844 // Start looking for apps that are abusing wake locks.
3845 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003846 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003847 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003848 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003849 broadcastIntentLocked(null, null,
3850 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3851 null, null, 0, null, null,
3852 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3853 false, false, MY_PID, Process.SYSTEM_UID);
3854 }
3855 }
3856 }
3857
3858 final void ensureBootCompleted() {
3859 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003860 boolean enableScreen;
3861 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003862 booting = mBooting;
3863 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003864 enableScreen = !mBooted;
3865 mBooted = true;
3866 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003867
3868 if (booting) {
3869 finishBooting();
3870 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003871
3872 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003873 enableScreenAfterBoot();
3874 }
3875 }
3876
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003877 public final void activityPaused(IBinder token) {
3878 final long origId = Binder.clearCallingIdentity();
3879 mMainStack.activityPaused(token, false);
3880 Binder.restoreCallingIdentity(origId);
3881 }
3882
3883 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3884 CharSequence description) {
3885 if (localLOGV) Slog.v(
3886 TAG, "Activity stopped: token=" + token);
3887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 // Refuse possible leaked file descriptors
3889 if (icicle != null && icicle.hasFileDescriptors()) {
3890 throw new IllegalArgumentException("File descriptors passed in Bundle");
3891 }
3892
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003893 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894
3895 final long origId = Binder.clearCallingIdentity();
3896
3897 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003898 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003900 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003901 r.icicle = icicle;
3902 r.haveState = true;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003903 r.updateThumbnail(thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 r.stopped = true;
3905 r.state = ActivityState.STOPPED;
3906 if (!r.finishing) {
3907 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003908 r.stack.destroyActivityLocked(r, true);
3909 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 }
3911 }
3912 }
3913 }
3914
3915 if (r != null) {
3916 sendPendingThumbnail(r, null, null, null, false);
3917 }
3918
3919 trimApplications();
3920
3921 Binder.restoreCallingIdentity(origId);
3922 }
3923
3924 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003925 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003926 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 }
3928
3929 public String getCallingPackage(IBinder token) {
3930 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003931 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003932 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 }
3934 }
3935
3936 public ComponentName getCallingActivity(IBinder token) {
3937 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003938 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 return r != null ? r.intent.getComponent() : null;
3940 }
3941 }
3942
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003943 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003944 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003946 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 if (r != null) {
3948 return r.resultTo;
3949 }
3950 }
3951 return null;
3952 }
3953
3954 public ComponentName getActivityClassForToken(IBinder token) {
3955 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003956 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003958 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 return r.intent.getComponent();
3960 }
3961 return null;
3962 }
3963 }
3964
3965 public String getPackageForToken(IBinder token) {
3966 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003967 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003969 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 return r.packageName;
3971 }
3972 return null;
3973 }
3974 }
3975
3976 public IIntentSender getIntentSender(int type,
3977 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003978 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003979 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003980 if (intents != null) {
3981 if (intents.length < 1) {
3982 throw new IllegalArgumentException("Intents array length must be >= 1");
3983 }
3984 for (int i=0; i<intents.length; i++) {
3985 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003986 if (intent != null) {
3987 if (intent.hasFileDescriptors()) {
3988 throw new IllegalArgumentException("File descriptors passed in Intent");
3989 }
3990 if (type == INTENT_SENDER_BROADCAST &&
3991 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3992 throw new IllegalArgumentException(
3993 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3994 }
3995 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003996 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003997 }
3998 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003999 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004000 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004001 }
4002 }
4003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 synchronized(this) {
4005 int callingUid = Binder.getCallingUid();
4006 try {
4007 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
4008 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004009 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004010 .getPackageUid(packageName);
4011 if (uid != Binder.getCallingUid()) {
4012 String msg = "Permission Denial: getIntentSender() from pid="
4013 + Binder.getCallingPid()
4014 + ", uid=" + Binder.getCallingUid()
4015 + ", (need uid=" + uid + ")"
4016 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004017 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 throw new SecurityException(msg);
4019 }
4020 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004021
4022 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004023 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 } catch (RemoteException e) {
4026 throw new SecurityException(e);
4027 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004028 }
4029 }
4030
4031 IIntentSender getIntentSenderLocked(int type,
4032 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004033 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004034 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004035 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004036 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004037 if (index < 0) {
4038 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004040 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004041 if (activity.finishing) {
4042 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004043 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004044 }
4045
4046 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4047 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4048 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4049 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4050 |PendingIntent.FLAG_UPDATE_CURRENT);
4051
4052 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4053 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004054 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004055 WeakReference<PendingIntentRecord> ref;
4056 ref = mIntentSenderRecords.get(key);
4057 PendingIntentRecord rec = ref != null ? ref.get() : null;
4058 if (rec != null) {
4059 if (!cancelCurrent) {
4060 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004061 if (rec.key.requestIntent != null) {
4062 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4063 }
4064 if (intents != null) {
4065 intents[intents.length-1] = rec.key.requestIntent;
4066 rec.key.allIntents = intents;
4067 rec.key.allResolvedTypes = resolvedTypes;
4068 } else {
4069 rec.key.allIntents = null;
4070 rec.key.allResolvedTypes = null;
4071 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004072 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 return rec;
4074 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004075 rec.canceled = true;
4076 mIntentSenderRecords.remove(key);
4077 }
4078 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 return rec;
4080 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004081 rec = new PendingIntentRecord(this, key, callingUid);
4082 mIntentSenderRecords.put(key, rec.ref);
4083 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4084 if (activity.pendingResults == null) {
4085 activity.pendingResults
4086 = new HashSet<WeakReference<PendingIntentRecord>>();
4087 }
4088 activity.pendingResults.add(rec.ref);
4089 }
4090 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 }
4092
4093 public void cancelIntentSender(IIntentSender sender) {
4094 if (!(sender instanceof PendingIntentRecord)) {
4095 return;
4096 }
4097 synchronized(this) {
4098 PendingIntentRecord rec = (PendingIntentRecord)sender;
4099 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004100 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004101 .getPackageUid(rec.key.packageName);
4102 if (uid != Binder.getCallingUid()) {
4103 String msg = "Permission Denial: cancelIntentSender() from pid="
4104 + Binder.getCallingPid()
4105 + ", uid=" + Binder.getCallingUid()
4106 + " is not allowed to cancel packges "
4107 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004108 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004109 throw new SecurityException(msg);
4110 }
4111 } catch (RemoteException e) {
4112 throw new SecurityException(e);
4113 }
4114 cancelIntentSenderLocked(rec, true);
4115 }
4116 }
4117
4118 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4119 rec.canceled = true;
4120 mIntentSenderRecords.remove(rec.key);
4121 if (cleanActivity && rec.key.activity != null) {
4122 rec.key.activity.pendingResults.remove(rec.ref);
4123 }
4124 }
4125
4126 public String getPackageForIntentSender(IIntentSender pendingResult) {
4127 if (!(pendingResult instanceof PendingIntentRecord)) {
4128 return null;
4129 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004130 try {
4131 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4132 return res.key.packageName;
4133 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004134 }
4135 return null;
4136 }
4137
4138 public void setProcessLimit(int max) {
4139 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4140 "setProcessLimit()");
4141 mProcessLimit = max;
4142 }
4143
4144 public int getProcessLimit() {
4145 return mProcessLimit;
4146 }
4147
4148 void foregroundTokenDied(ForegroundToken token) {
4149 synchronized (ActivityManagerService.this) {
4150 synchronized (mPidsSelfLocked) {
4151 ForegroundToken cur
4152 = mForegroundProcesses.get(token.pid);
4153 if (cur != token) {
4154 return;
4155 }
4156 mForegroundProcesses.remove(token.pid);
4157 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4158 if (pr == null) {
4159 return;
4160 }
4161 pr.forcingToForeground = null;
4162 pr.foregroundServices = false;
4163 }
4164 updateOomAdjLocked();
4165 }
4166 }
4167
4168 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4169 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4170 "setProcessForeground()");
4171 synchronized(this) {
4172 boolean changed = false;
4173
4174 synchronized (mPidsSelfLocked) {
4175 ProcessRecord pr = mPidsSelfLocked.get(pid);
4176 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004177 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004178 return;
4179 }
4180 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4181 if (oldToken != null) {
4182 oldToken.token.unlinkToDeath(oldToken, 0);
4183 mForegroundProcesses.remove(pid);
4184 pr.forcingToForeground = null;
4185 changed = true;
4186 }
4187 if (isForeground && token != null) {
4188 ForegroundToken newToken = new ForegroundToken() {
4189 public void binderDied() {
4190 foregroundTokenDied(this);
4191 }
4192 };
4193 newToken.pid = pid;
4194 newToken.token = token;
4195 try {
4196 token.linkToDeath(newToken, 0);
4197 mForegroundProcesses.put(pid, newToken);
4198 pr.forcingToForeground = token;
4199 changed = true;
4200 } catch (RemoteException e) {
4201 // If the process died while doing this, we will later
4202 // do the cleanup with the process death link.
4203 }
4204 }
4205 }
4206
4207 if (changed) {
4208 updateOomAdjLocked();
4209 }
4210 }
4211 }
4212
4213 // =========================================================
4214 // PERMISSIONS
4215 // =========================================================
4216
4217 static class PermissionController extends IPermissionController.Stub {
4218 ActivityManagerService mActivityManagerService;
4219 PermissionController(ActivityManagerService activityManagerService) {
4220 mActivityManagerService = activityManagerService;
4221 }
4222
4223 public boolean checkPermission(String permission, int pid, int uid) {
4224 return mActivityManagerService.checkPermission(permission, pid,
4225 uid) == PackageManager.PERMISSION_GRANTED;
4226 }
4227 }
4228
4229 /**
4230 * This can be called with or without the global lock held.
4231 */
4232 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004233 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 // We might be performing an operation on behalf of an indirect binder
4235 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4236 // client identity accordingly before proceeding.
4237 Identity tlsIdentity = sCallerIdentity.get();
4238 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004239 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4241 uid = tlsIdentity.uid;
4242 pid = tlsIdentity.pid;
4243 }
4244
4245 // Root, system server and our own process get to do everything.
4246 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4247 !Process.supportsProcesses()) {
4248 return PackageManager.PERMISSION_GRANTED;
4249 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004250 // If there is a uid that owns whatever is being accessed, it has
4251 // blanket access to it regardless of the permissions it requires.
4252 if (owningUid >= 0 && uid == owningUid) {
4253 return PackageManager.PERMISSION_GRANTED;
4254 }
4255 // If the target is not exported, then nobody else can get to it.
4256 if (!exported) {
4257 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 return PackageManager.PERMISSION_DENIED;
4259 }
4260 if (permission == null) {
4261 return PackageManager.PERMISSION_GRANTED;
4262 }
4263 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004264 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004265 .checkUidPermission(permission, uid);
4266 } catch (RemoteException e) {
4267 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004268 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 }
4270 return PackageManager.PERMISSION_DENIED;
4271 }
4272
4273 /**
4274 * As the only public entry point for permissions checking, this method
4275 * can enforce the semantic that requesting a check on a null global
4276 * permission is automatically denied. (Internally a null permission
4277 * string is used when calling {@link #checkComponentPermission} in cases
4278 * when only uid-based security is needed.)
4279 *
4280 * This can be called with or without the global lock held.
4281 */
4282 public int checkPermission(String permission, int pid, int uid) {
4283 if (permission == null) {
4284 return PackageManager.PERMISSION_DENIED;
4285 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004286 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004287 }
4288
4289 /**
4290 * Binder IPC calls go through the public entry point.
4291 * This can be called with or without the global lock held.
4292 */
4293 int checkCallingPermission(String permission) {
4294 return checkPermission(permission,
4295 Binder.getCallingPid(),
4296 Binder.getCallingUid());
4297 }
4298
4299 /**
4300 * This can be called with or without the global lock held.
4301 */
4302 void enforceCallingPermission(String permission, String func) {
4303 if (checkCallingPermission(permission)
4304 == PackageManager.PERMISSION_GRANTED) {
4305 return;
4306 }
4307
4308 String msg = "Permission Denial: " + func + " from pid="
4309 + Binder.getCallingPid()
4310 + ", uid=" + Binder.getCallingUid()
4311 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004312 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 throw new SecurityException(msg);
4314 }
4315
4316 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004317 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4318 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4319 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4320 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4321 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004322 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004323 // Is the component private from the target uid?
4324 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4325
4326 // Acceptable if the there is no read permission needed from the
4327 // target or the target is holding the read permission.
4328 if (!readPerm) {
4329 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004330 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004331 == PackageManager.PERMISSION_GRANTED)) {
4332 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004333 }
4334 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004335
4336 // Acceptable if the there is no write permission needed from the
4337 // target or the target is holding the read permission.
4338 if (!writePerm) {
4339 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004340 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004341 == PackageManager.PERMISSION_GRANTED)) {
4342 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343 }
4344 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004345
4346 // Acceptable if there is a path permission matching the URI that
4347 // the target holds the permission on.
4348 PathPermission[] pps = pi.pathPermissions;
4349 if (pps != null && (!readPerm || !writePerm)) {
4350 final String path = uri.getPath();
4351 int i = pps.length;
4352 while (i > 0 && (!readPerm || !writePerm)) {
4353 i--;
4354 PathPermission pp = pps[i];
4355 if (!readPerm) {
4356 final String pprperm = pp.getReadPermission();
4357 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4358 + pprperm + " for " + pp.getPath()
4359 + ": match=" + pp.match(path)
4360 + " check=" + pm.checkUidPermission(pprperm, uid));
4361 if (pprperm != null && pp.match(path) &&
4362 (pm.checkUidPermission(pprperm, uid)
4363 == PackageManager.PERMISSION_GRANTED)) {
4364 readPerm = true;
4365 }
4366 }
4367 if (!writePerm) {
4368 final String ppwperm = pp.getWritePermission();
4369 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4370 + ppwperm + " for " + pp.getPath()
4371 + ": match=" + pp.match(path)
4372 + " check=" + pm.checkUidPermission(ppwperm, uid));
4373 if (ppwperm != null && pp.match(path) &&
4374 (pm.checkUidPermission(ppwperm, uid)
4375 == PackageManager.PERMISSION_GRANTED)) {
4376 writePerm = true;
4377 }
4378 }
4379 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 } catch (RemoteException e) {
4382 return false;
4383 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004384
4385 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004386 }
4387
4388 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4389 int modeFlags) {
4390 // Root gets to do everything.
4391 if (uid == 0 || !Process.supportsProcesses()) {
4392 return true;
4393 }
4394 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4395 if (perms == null) return false;
4396 UriPermission perm = perms.get(uri);
4397 if (perm == null) return false;
4398 return (modeFlags&perm.modeFlags) == modeFlags;
4399 }
4400
4401 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4402 // Another redirected-binder-call permissions check as in
4403 // {@link checkComponentPermission}.
4404 Identity tlsIdentity = sCallerIdentity.get();
4405 if (tlsIdentity != null) {
4406 uid = tlsIdentity.uid;
4407 pid = tlsIdentity.pid;
4408 }
4409
4410 // Our own process gets to do everything.
4411 if (pid == MY_PID) {
4412 return PackageManager.PERMISSION_GRANTED;
4413 }
4414 synchronized(this) {
4415 return checkUriPermissionLocked(uri, uid, modeFlags)
4416 ? PackageManager.PERMISSION_GRANTED
4417 : PackageManager.PERMISSION_DENIED;
4418 }
4419 }
4420
Dianne Hackborn39792d22010-08-19 18:01:52 -07004421 /**
4422 * Check if the targetPkg can be granted permission to access uri by
4423 * the callingUid using the given modeFlags. Throws a security exception
4424 * if callingUid is not allowed to do this. Returns the uid of the target
4425 * if the URI permission grant should be performed; returns -1 if it is not
4426 * needed (for example targetPkg already has permission to access the URI).
4427 */
4428 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4429 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4431 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4432 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004433 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 }
4435
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004436 if (targetPkg != null) {
4437 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4438 "Checking grant " + targetPkg + " permission to " + uri);
4439 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004440
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004441 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442
4443 // If this is not a content: uri, we can't do anything with it.
4444 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004445 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004446 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004447 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448 }
4449
4450 String name = uri.getAuthority();
4451 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004452 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 if (cpr != null) {
4454 pi = cpr.info;
4455 } else {
4456 try {
4457 pi = pm.resolveContentProvider(name,
4458 PackageManager.GET_URI_PERMISSION_PATTERNS);
4459 } catch (RemoteException ex) {
4460 }
4461 }
4462 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004463 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004464 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 }
4466
4467 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004468 if (targetPkg != null) {
4469 try {
4470 targetUid = pm.getPackageUid(targetPkg);
4471 if (targetUid < 0) {
4472 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4473 "Can't grant URI permission no uid for: " + targetPkg);
4474 return -1;
4475 }
4476 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004477 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004479 } else {
4480 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 }
4482
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004483 if (targetUid >= 0) {
4484 // First... does the target actually need this permission?
4485 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4486 // No need to grant the target this permission.
4487 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4488 "Target " + targetPkg + " already has full permission to " + uri);
4489 return -1;
4490 }
4491 } else {
4492 // First... there is no target package, so can anyone access it?
4493 boolean allowed = pi.exported;
4494 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4495 if (pi.readPermission != null) {
4496 allowed = false;
4497 }
4498 }
4499 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4500 if (pi.writePermission != null) {
4501 allowed = false;
4502 }
4503 }
4504 if (allowed) {
4505 return -1;
4506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 }
4508
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004509 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 if (!pi.grantUriPermissions) {
4511 throw new SecurityException("Provider " + pi.packageName
4512 + "/" + pi.name
4513 + " does not allow granting of Uri permissions (uri "
4514 + uri + ")");
4515 }
4516 if (pi.uriPermissionPatterns != null) {
4517 final int N = pi.uriPermissionPatterns.length;
4518 boolean allowed = false;
4519 for (int i=0; i<N; i++) {
4520 if (pi.uriPermissionPatterns[i] != null
4521 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4522 allowed = true;
4523 break;
4524 }
4525 }
4526 if (!allowed) {
4527 throw new SecurityException("Provider " + pi.packageName
4528 + "/" + pi.name
4529 + " does not allow granting of permission to path of Uri "
4530 + uri);
4531 }
4532 }
4533
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004534 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004536 if (callingUid != Process.myUid()) {
4537 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4538 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4539 throw new SecurityException("Uid " + callingUid
4540 + " does not have permission to uri " + uri);
4541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004542 }
4543 }
4544
Dianne Hackborn39792d22010-08-19 18:01:52 -07004545 return targetUid;
4546 }
4547
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004548 public int checkGrantUriPermission(int callingUid, String targetPkg,
4549 Uri uri, int modeFlags) {
4550 synchronized(this) {
4551 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4552 }
4553 }
4554
Dianne Hackborn39792d22010-08-19 18:01:52 -07004555 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4556 Uri uri, int modeFlags, UriPermissionOwner owner) {
4557 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4558 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4559 if (modeFlags == 0) {
4560 return;
4561 }
4562
4563 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 // to the uri, and the target doesn't. Let's now give this to
4565 // the target.
4566
Joe Onorato8a9b2202010-02-26 18:56:32 -08004567 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004568 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004570 HashMap<Uri, UriPermission> targetUris
4571 = mGrantedUriPermissions.get(targetUid);
4572 if (targetUris == null) {
4573 targetUris = new HashMap<Uri, UriPermission>();
4574 mGrantedUriPermissions.put(targetUid, targetUris);
4575 }
4576
4577 UriPermission perm = targetUris.get(uri);
4578 if (perm == null) {
4579 perm = new UriPermission(targetUid, uri);
4580 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004583 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004584 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004585 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004586 } else {
4587 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4588 perm.readOwners.add(owner);
4589 owner.addReadPermission(perm);
4590 }
4591 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4592 perm.writeOwners.add(owner);
4593 owner.addWritePermission(perm);
4594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 }
4596 }
4597
Dianne Hackborn39792d22010-08-19 18:01:52 -07004598 void grantUriPermissionLocked(int callingUid,
4599 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004600 if (targetPkg == null) {
4601 throw new NullPointerException("targetPkg");
4602 }
4603
Dianne Hackborn39792d22010-08-19 18:01:52 -07004604 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4605 if (targetUid < 0) {
4606 return;
4607 }
4608
4609 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4610 }
4611
4612 /**
4613 * Like checkGrantUriPermissionLocked, but takes an Intent.
4614 */
4615 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4616 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004617 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004618 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004619 + " from " + intent + "; flags=0x"
4620 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4621
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004622 if (targetPkg == null) {
4623 throw new NullPointerException("targetPkg");
4624 }
4625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004627 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628 }
4629 Uri data = intent.getData();
4630 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004631 return -1;
4632 }
4633 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4634 intent.getFlags());
4635 }
4636
4637 /**
4638 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4639 */
4640 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4641 String targetPkg, Intent intent, UriPermissionOwner owner) {
4642 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4643 intent.getFlags(), owner);
4644 }
4645
4646 void grantUriPermissionFromIntentLocked(int callingUid,
4647 String targetPkg, Intent intent, UriPermissionOwner owner) {
4648 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4649 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 return;
4651 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004652
4653 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 }
4655
4656 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4657 Uri uri, int modeFlags) {
4658 synchronized(this) {
4659 final ProcessRecord r = getRecordForAppLocked(caller);
4660 if (r == null) {
4661 throw new SecurityException("Unable to find app for caller "
4662 + caller
4663 + " when granting permission to uri " + uri);
4664 }
4665 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004666 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 }
4668 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004669 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 }
4671
4672 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4673 null);
4674 }
4675 }
4676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004677 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4679 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4680 HashMap<Uri, UriPermission> perms
4681 = mGrantedUriPermissions.get(perm.uid);
4682 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004683 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004684 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004685 perms.remove(perm.uri);
4686 if (perms.size() == 0) {
4687 mGrantedUriPermissions.remove(perm.uid);
4688 }
4689 }
4690 }
4691 }
4692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004693 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4694 int modeFlags) {
4695 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4696 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4697 if (modeFlags == 0) {
4698 return;
4699 }
4700
Joe Onorato8a9b2202010-02-26 18:56:32 -08004701 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004702 "Revoking all granted permissions to " + uri);
4703
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004704 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705
4706 final String authority = uri.getAuthority();
4707 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004708 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 if (cpr != null) {
4710 pi = cpr.info;
4711 } else {
4712 try {
4713 pi = pm.resolveContentProvider(authority,
4714 PackageManager.GET_URI_PERMISSION_PATTERNS);
4715 } catch (RemoteException ex) {
4716 }
4717 }
4718 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004719 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004720 return;
4721 }
4722
4723 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004724 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004725 // Right now, if you are not the original owner of the permission,
4726 // you are not allowed to revoke it.
4727 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4728 throw new SecurityException("Uid " + callingUid
4729 + " does not have permission to uri " + uri);
4730 //}
4731 }
4732
4733 // Go through all of the permissions and remove any that match.
4734 final List<String> SEGMENTS = uri.getPathSegments();
4735 if (SEGMENTS != null) {
4736 final int NS = SEGMENTS.size();
4737 int N = mGrantedUriPermissions.size();
4738 for (int i=0; i<N; i++) {
4739 HashMap<Uri, UriPermission> perms
4740 = mGrantedUriPermissions.valueAt(i);
4741 Iterator<UriPermission> it = perms.values().iterator();
4742 toploop:
4743 while (it.hasNext()) {
4744 UriPermission perm = it.next();
4745 Uri targetUri = perm.uri;
4746 if (!authority.equals(targetUri.getAuthority())) {
4747 continue;
4748 }
4749 List<String> targetSegments = targetUri.getPathSegments();
4750 if (targetSegments == null) {
4751 continue;
4752 }
4753 if (targetSegments.size() < NS) {
4754 continue;
4755 }
4756 for (int j=0; j<NS; j++) {
4757 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4758 continue toploop;
4759 }
4760 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004761 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004762 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 perm.clearModes(modeFlags);
4764 if (perm.modeFlags == 0) {
4765 it.remove();
4766 }
4767 }
4768 if (perms.size() == 0) {
4769 mGrantedUriPermissions.remove(
4770 mGrantedUriPermissions.keyAt(i));
4771 N--;
4772 i--;
4773 }
4774 }
4775 }
4776 }
4777
4778 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4779 int modeFlags) {
4780 synchronized(this) {
4781 final ProcessRecord r = getRecordForAppLocked(caller);
4782 if (r == null) {
4783 throw new SecurityException("Unable to find app for caller "
4784 + caller
4785 + " when revoking permission to uri " + uri);
4786 }
4787 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004788 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 return;
4790 }
4791
4792 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4793 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4794 if (modeFlags == 0) {
4795 return;
4796 }
4797
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004798 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799
4800 final String authority = uri.getAuthority();
4801 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004802 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004803 if (cpr != null) {
4804 pi = cpr.info;
4805 } else {
4806 try {
4807 pi = pm.resolveContentProvider(authority,
4808 PackageManager.GET_URI_PERMISSION_PATTERNS);
4809 } catch (RemoteException ex) {
4810 }
4811 }
4812 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004813 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 return;
4815 }
4816
4817 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4818 }
4819 }
4820
Dianne Hackborn7e269642010-08-25 19:50:20 -07004821 @Override
4822 public IBinder newUriPermissionOwner(String name) {
4823 synchronized(this) {
4824 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4825 return owner.getExternalTokenLocked();
4826 }
4827 }
4828
4829 @Override
4830 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4831 Uri uri, int modeFlags) {
4832 synchronized(this) {
4833 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4834 if (owner == null) {
4835 throw new IllegalArgumentException("Unknown owner: " + token);
4836 }
4837 if (fromUid != Binder.getCallingUid()) {
4838 if (Binder.getCallingUid() != Process.myUid()) {
4839 // Only system code can grant URI permissions on behalf
4840 // of other users.
4841 throw new SecurityException("nice try");
4842 }
4843 }
4844 if (targetPkg == null) {
4845 throw new IllegalArgumentException("null target");
4846 }
4847 if (uri == null) {
4848 throw new IllegalArgumentException("null uri");
4849 }
4850
4851 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4852 }
4853 }
4854
4855 @Override
4856 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4857 synchronized(this) {
4858 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4859 if (owner == null) {
4860 throw new IllegalArgumentException("Unknown owner: " + token);
4861 }
4862
4863 if (uri == null) {
4864 owner.removeUriPermissionsLocked(mode);
4865 } else {
4866 owner.removeUriPermissionLocked(uri, mode);
4867 }
4868 }
4869 }
4870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004871 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4872 synchronized (this) {
4873 ProcessRecord app =
4874 who != null ? getRecordForAppLocked(who) : null;
4875 if (app == null) return;
4876
4877 Message msg = Message.obtain();
4878 msg.what = WAIT_FOR_DEBUGGER_MSG;
4879 msg.obj = app;
4880 msg.arg1 = waiting ? 1 : 0;
4881 mHandler.sendMessage(msg);
4882 }
4883 }
4884
4885 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4886 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004887 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004889 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004890 }
4891
4892 // =========================================================
4893 // TASK MANAGEMENT
4894 // =========================================================
4895
4896 public List getTasks(int maxNum, int flags,
4897 IThumbnailReceiver receiver) {
4898 ArrayList list = new ArrayList();
4899
4900 PendingThumbnailsRecord pending = null;
4901 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004902 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004903
4904 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004905 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004906 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4907 + ", receiver=" + receiver);
4908
4909 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4910 != PackageManager.PERMISSION_GRANTED) {
4911 if (receiver != null) {
4912 // If the caller wants to wait for pending thumbnails,
4913 // it ain't gonna get them.
4914 try {
4915 receiver.finished();
4916 } catch (RemoteException ex) {
4917 }
4918 }
4919 String msg = "Permission Denial: getTasks() from pid="
4920 + Binder.getCallingPid()
4921 + ", uid=" + Binder.getCallingUid()
4922 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004923 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004924 throw new SecurityException(msg);
4925 }
4926
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004927 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004928 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004929 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004930 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004931 TaskRecord curTask = null;
4932 int numActivities = 0;
4933 int numRunning = 0;
4934 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004935 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004936 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004937 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938
4939 // Initialize state for next task if needed.
4940 if (top == null ||
4941 (top.state == ActivityState.INITIALIZING
4942 && top.task == r.task)) {
4943 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004944 curTask = r.task;
4945 numActivities = numRunning = 0;
4946 }
4947
4948 // Add 'r' into the current task.
4949 numActivities++;
4950 if (r.app != null && r.app.thread != null) {
4951 numRunning++;
4952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953
Joe Onorato8a9b2202010-02-26 18:56:32 -08004954 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004955 TAG, r.intent.getComponent().flattenToShortString()
4956 + ": task=" + r.task);
4957
4958 // If the next one is a different task, generate a new
4959 // TaskInfo entry for what we have.
4960 if (next == null || next.task != curTask) {
4961 ActivityManager.RunningTaskInfo ci
4962 = new ActivityManager.RunningTaskInfo();
4963 ci.id = curTask.taskId;
4964 ci.baseActivity = r.intent.getComponent();
4965 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004966 if (top.thumbHolder != null) {
4967 ci.description = top.thumbHolder.lastDescription;
4968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 ci.numActivities = numActivities;
4970 ci.numRunning = numRunning;
4971 //System.out.println(
4972 // "#" + maxNum + ": " + " descr=" + ci.description);
4973 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004974 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004975 TAG, "State=" + top.state + "Idle=" + top.idle
4976 + " app=" + top.app
4977 + " thr=" + (top.app != null ? top.app.thread : null));
4978 if (top.state == ActivityState.RESUMED
4979 || top.state == ActivityState.PAUSING) {
4980 if (top.idle && top.app != null
4981 && top.app.thread != null) {
4982 topRecord = top;
4983 topThumbnail = top.app.thread;
4984 } else {
4985 top.thumbnailNeeded = true;
4986 }
4987 }
4988 if (pending == null) {
4989 pending = new PendingThumbnailsRecord(receiver);
4990 }
4991 pending.pendingRecords.add(top);
4992 }
4993 list.add(ci);
4994 maxNum--;
4995 top = null;
4996 }
4997 }
4998
4999 if (pending != null) {
5000 mPendingThumbnails.add(pending);
5001 }
5002 }
5003
Joe Onorato8a9b2202010-02-26 18:56:32 -08005004 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005
5006 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005007 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 try {
5009 topThumbnail.requestThumbnail(topRecord);
5010 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005011 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005012 sendPendingThumbnail(null, topRecord, null, null, true);
5013 }
5014 }
5015
5016 if (pending == null && receiver != null) {
5017 // In this case all thumbnails were available and the client
5018 // is being asked to be told when the remaining ones come in...
5019 // which is unusually, since the top-most currently running
5020 // activity should never have a canned thumbnail! Oh well.
5021 try {
5022 receiver.finished();
5023 } catch (RemoteException ex) {
5024 }
5025 }
5026
5027 return list;
5028 }
5029
5030 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5031 int flags) {
5032 synchronized (this) {
5033 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5034 "getRecentTasks()");
5035
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005036 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005038 final int N = mRecentTasks.size();
5039 ArrayList<ActivityManager.RecentTaskInfo> res
5040 = new ArrayList<ActivityManager.RecentTaskInfo>(
5041 maxNum < N ? maxNum : N);
5042 for (int i=0; i<N && maxNum > 0; i++) {
5043 TaskRecord tr = mRecentTasks.get(i);
5044 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5045 || (tr.intent == null)
5046 || ((tr.intent.getFlags()
5047 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5048 ActivityManager.RecentTaskInfo rti
5049 = new ActivityManager.RecentTaskInfo();
5050 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005051 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 rti.baseIntent = new Intent(
5053 tr.intent != null ? tr.intent : tr.affinityIntent);
5054 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005055 rti.description = tr.lastDescription;
5056
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005057 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5058 // Check whether this activity is currently available.
5059 try {
5060 if (rti.origActivity != null) {
5061 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5062 continue;
5063 }
5064 } else if (rti.baseIntent != null) {
5065 if (pm.queryIntentActivities(rti.baseIntent,
5066 null, 0) == null) {
5067 continue;
5068 }
5069 }
5070 } catch (RemoteException e) {
5071 // Will never happen.
5072 }
5073 }
5074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005075 res.add(rti);
5076 maxNum--;
5077 }
5078 }
5079 return res;
5080 }
5081 }
5082
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005083 private TaskRecord taskForIdLocked(int id) {
5084 final int N = mRecentTasks.size();
5085 for (int i=0; i<N; i++) {
5086 TaskRecord tr = mRecentTasks.get(i);
5087 if (tr.taskId == id) {
5088 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005089 }
5090 }
5091 return null;
5092 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005093
5094 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5095 synchronized (this) {
5096 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5097 "getTaskThumbnails()");
5098 TaskRecord tr = taskForIdLocked(id);
5099 if (tr != null) {
5100 return mMainStack.getTaskThumbnailsLocked(tr);
5101 }
5102 }
5103 return null;
5104 }
5105
5106 public boolean removeSubTask(int taskId, int subTaskIndex) {
5107 synchronized (this) {
5108 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5109 "removeSubTask()");
5110 long ident = Binder.clearCallingIdentity();
5111 try {
5112 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5113 } finally {
5114 Binder.restoreCallingIdentity(ident);
5115 }
5116 }
5117 }
5118
5119 private void removeTaskProcessesLocked(ActivityRecord root) {
5120 TaskRecord tr = root.task;
5121 Intent baseIntent = new Intent(
5122 tr.intent != null ? tr.intent : tr.affinityIntent);
5123 ComponentName component = baseIntent.getComponent();
5124 if (component == null) {
5125 Slog.w(TAG, "Now component for base intent of task: " + tr);
5126 return;
5127 }
5128
5129 // Find any running services associated with this app.
5130 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5131 for (ServiceRecord sr : mServices.values()) {
5132 if (sr.packageName.equals(component.getPackageName())) {
5133 services.add(sr);
5134 }
5135 }
5136
5137 // Take care of any running services associated with the app.
5138 for (int i=0; i<services.size(); i++) {
5139 ServiceRecord sr = services.get(i);
5140 if (sr.startRequested) {
5141 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5142 stopServiceLocked(sr);
5143 } else {
5144 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5145 sr.makeNextStartId(), baseIntent, -1));
5146 if (sr.app != null && sr.app.thread != null) {
5147 sendServiceArgsLocked(sr, false);
5148 }
5149 }
5150 }
5151 }
5152
5153 // Find any running processes associated with this app.
5154 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5155 SparseArray<ProcessRecord> appProcs
5156 = mProcessNames.getMap().get(component.getPackageName());
5157 if (appProcs != null) {
5158 for (int i=0; i<appProcs.size(); i++) {
5159 procs.add(appProcs.valueAt(i));
5160 }
5161 }
5162
5163 // Kill the running processes.
5164 for (int i=0; i<procs.size(); i++) {
5165 ProcessRecord pr = procs.get(i);
5166 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5167 Slog.i(TAG, "Killing " + pr + ": remove task");
5168 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5169 pr.processName, pr.setAdj, "remove task");
5170 Process.killProcessQuiet(pr.pid);
5171 } else {
5172 pr.waitingToKill = "remove task";
5173 }
5174 }
5175 }
5176
5177 public boolean removeTask(int taskId, int flags) {
5178 synchronized (this) {
5179 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5180 "removeTask()");
5181 long ident = Binder.clearCallingIdentity();
5182 try {
5183 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5184 if (r != null) {
5185 mRecentTasks.remove(r.task);
5186
5187 if ((flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0) {
5188 removeTaskProcessesLocked(r);
5189 }
5190
5191 return true;
5192 }
5193 } finally {
5194 Binder.restoreCallingIdentity(ident);
5195 }
5196 }
5197 return false;
5198 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5201 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005202 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005203 TaskRecord jt = startTask;
5204
5205 // First look backwards
5206 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005207 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005208 if (r.task != jt) {
5209 jt = r.task;
5210 if (affinity.equals(jt.affinity)) {
5211 return j;
5212 }
5213 }
5214 }
5215
5216 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005217 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 jt = startTask;
5219 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005220 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005221 if (r.task != jt) {
5222 if (affinity.equals(jt.affinity)) {
5223 return j;
5224 }
5225 jt = r.task;
5226 }
5227 }
5228
5229 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005230 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005231 return N-1;
5232 }
5233
5234 return -1;
5235 }
5236
5237 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005238 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005239 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005240 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005241 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5242 "moveTaskToFront()");
5243
5244 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005245 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5246 Binder.getCallingUid(), "Task to front")) {
5247 return;
5248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 final long origId = Binder.clearCallingIdentity();
5250 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005251 TaskRecord tr = taskForIdLocked(task);
5252 if (tr != null) {
5253 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5254 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005255 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005256 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5257 // Caller wants the home activity moved with it. To accomplish this,
5258 // we'll just move the home task to the top first.
5259 mMainStack.moveHomeToFrontLocked();
5260 }
5261 mMainStack.moveTaskToFrontLocked(tr, null);
5262 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005264 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5265 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005267 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5268 mMainStack.mUserLeaving = true;
5269 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005270 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5271 // Caller wants the home activity moved with it. To accomplish this,
5272 // we'll just move the home task to the top first.
5273 mMainStack.moveHomeToFrontLocked();
5274 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005275 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 return;
5277 }
5278 }
5279 } finally {
5280 Binder.restoreCallingIdentity(origId);
5281 }
5282 }
5283 }
5284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 public void moveTaskToBack(int task) {
5286 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5287 "moveTaskToBack()");
5288
5289 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005290 if (mMainStack.mResumedActivity != null
5291 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005292 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5293 Binder.getCallingUid(), "Task to back")) {
5294 return;
5295 }
5296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005298 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005299 Binder.restoreCallingIdentity(origId);
5300 }
5301 }
5302
5303 /**
5304 * Moves an activity, and all of the other activities within the same task, to the bottom
5305 * of the history stack. The activity's order within the task is unchanged.
5306 *
5307 * @param token A reference to the activity we wish to move
5308 * @param nonRoot If false then this only works if the activity is the root
5309 * of a task; if true it will work for any activity in a task.
5310 * @return Returns true if the move completed, false if not.
5311 */
5312 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5313 synchronized(this) {
5314 final long origId = Binder.clearCallingIdentity();
5315 int taskId = getTaskForActivityLocked(token, !nonRoot);
5316 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005317 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 }
5319 Binder.restoreCallingIdentity(origId);
5320 }
5321 return false;
5322 }
5323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005324 public void moveTaskBackwards(int task) {
5325 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5326 "moveTaskBackwards()");
5327
5328 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005329 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5330 Binder.getCallingUid(), "Task backwards")) {
5331 return;
5332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 final long origId = Binder.clearCallingIdentity();
5334 moveTaskBackwardsLocked(task);
5335 Binder.restoreCallingIdentity(origId);
5336 }
5337 }
5338
5339 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005340 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341 }
5342
5343 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5344 synchronized(this) {
5345 return getTaskForActivityLocked(token, onlyRoot);
5346 }
5347 }
5348
5349 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005350 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 TaskRecord lastTask = null;
5352 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005353 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005354 if (r == token) {
5355 if (!onlyRoot || lastTask != r.task) {
5356 return r.task.taskId;
5357 }
5358 return -1;
5359 }
5360 lastTask = r.task;
5361 }
5362
5363 return -1;
5364 }
5365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005366 public void finishOtherInstances(IBinder token, ComponentName className) {
5367 synchronized(this) {
5368 final long origId = Binder.clearCallingIdentity();
5369
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005370 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 TaskRecord lastTask = null;
5372 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005373 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 if (r.realActivity.equals(className)
5375 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005376 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005377 null, "others")) {
5378 i--;
5379 N--;
5380 }
5381 }
5382 lastTask = r.task;
5383 }
5384
5385 Binder.restoreCallingIdentity(origId);
5386 }
5387 }
5388
5389 // =========================================================
5390 // THUMBNAILS
5391 // =========================================================
5392
5393 public void reportThumbnail(IBinder token,
5394 Bitmap thumbnail, CharSequence description) {
5395 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5396 final long origId = Binder.clearCallingIdentity();
5397 sendPendingThumbnail(null, token, thumbnail, description, true);
5398 Binder.restoreCallingIdentity(origId);
5399 }
5400
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005401 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005402 Bitmap thumbnail, CharSequence description, boolean always) {
5403 TaskRecord task = null;
5404 ArrayList receivers = null;
5405
5406 //System.out.println("Send pending thumbnail: " + r);
5407
5408 synchronized(this) {
5409 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005410 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005411 if (index < 0) {
5412 return;
5413 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005414 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005416 if (thumbnail == null && r.thumbHolder != null) {
5417 thumbnail = r.thumbHolder.lastThumbnail;
5418 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 }
5420 if (thumbnail == null && !always) {
5421 // If there is no thumbnail, and this entry is not actually
5422 // going away, then abort for now and pick up the next
5423 // thumbnail we get.
5424 return;
5425 }
5426 task = r.task;
5427
5428 int N = mPendingThumbnails.size();
5429 int i=0;
5430 while (i<N) {
5431 PendingThumbnailsRecord pr =
5432 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5433 //System.out.println("Looking in " + pr.pendingRecords);
5434 if (pr.pendingRecords.remove(r)) {
5435 if (receivers == null) {
5436 receivers = new ArrayList();
5437 }
5438 receivers.add(pr);
5439 if (pr.pendingRecords.size() == 0) {
5440 pr.finished = true;
5441 mPendingThumbnails.remove(i);
5442 N--;
5443 continue;
5444 }
5445 }
5446 i++;
5447 }
5448 }
5449
5450 if (receivers != null) {
5451 final int N = receivers.size();
5452 for (int i=0; i<N; i++) {
5453 try {
5454 PendingThumbnailsRecord pr =
5455 (PendingThumbnailsRecord)receivers.get(i);
5456 pr.receiver.newThumbnail(
5457 task != null ? task.taskId : -1, thumbnail, description);
5458 if (pr.finished) {
5459 pr.receiver.finished();
5460 }
5461 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005462 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 }
5464 }
5465 }
5466 }
5467
5468 // =========================================================
5469 // CONTENT PROVIDERS
5470 // =========================================================
5471
5472 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5473 List providers = null;
5474 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005475 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005476 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005477 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005478 } catch (RemoteException ex) {
5479 }
5480 if (providers != null) {
5481 final int N = providers.size();
5482 for (int i=0; i<N; i++) {
5483 ProviderInfo cpi =
5484 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005485 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005486 if (cpr == null) {
5487 cpr = new ContentProviderRecord(cpi, app.info);
5488 mProvidersByClass.put(cpi.name, cpr);
5489 }
5490 app.pubProviders.put(cpi.name, cpr);
5491 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005492 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005493 }
5494 }
5495 return providers;
5496 }
5497
5498 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005499 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005500 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5501 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5502 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005503 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005504 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005505 return null;
5506 }
5507 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005508 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005509 == PackageManager.PERMISSION_GRANTED) {
5510 return null;
5511 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005512
5513 PathPermission[] pps = cpi.pathPermissions;
5514 if (pps != null) {
5515 int i = pps.length;
5516 while (i > 0) {
5517 i--;
5518 PathPermission pp = pps[i];
5519 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005520 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005521 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005522 return null;
5523 }
5524 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005525 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005526 == PackageManager.PERMISSION_GRANTED) {
5527 return null;
5528 }
5529 }
5530 }
5531
Dianne Hackbornb424b632010-08-18 15:59:05 -07005532 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5533 if (perms != null) {
5534 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5535 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5536 return null;
5537 }
5538 }
5539 }
5540
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005541 String msg;
5542 if (!cpi.exported) {
5543 msg = "Permission Denial: opening provider " + cpi.name
5544 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5545 + ", uid=" + callingUid + ") that is not exported from uid "
5546 + cpi.applicationInfo.uid;
5547 } else {
5548 msg = "Permission Denial: opening provider " + cpi.name
5549 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5550 + ", uid=" + callingUid + ") requires "
5551 + cpi.readPermission + " or " + cpi.writePermission;
5552 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005553 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005554 return msg;
5555 }
5556
5557 private final ContentProviderHolder getContentProviderImpl(
5558 IApplicationThread caller, String name) {
5559 ContentProviderRecord cpr;
5560 ProviderInfo cpi = null;
5561
5562 synchronized(this) {
5563 ProcessRecord r = null;
5564 if (caller != null) {
5565 r = getRecordForAppLocked(caller);
5566 if (r == null) {
5567 throw new SecurityException(
5568 "Unable to find app for caller " + caller
5569 + " (pid=" + Binder.getCallingPid()
5570 + ") when getting content provider " + name);
5571 }
5572 }
5573
5574 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005575 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005576 if (cpr != null) {
5577 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005578 String msg;
5579 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5580 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 }
5582
5583 if (r != null && cpr.canRunHere(r)) {
5584 // This provider has been published or is in the process
5585 // of being published... but it is also allowed to run
5586 // in the caller's process, so don't make a connection
5587 // and just let the caller instantiate its own instance.
5588 if (cpr.provider != null) {
5589 // don't give caller the provider object, it needs
5590 // to make its own.
5591 cpr = new ContentProviderRecord(cpr);
5592 }
5593 return cpr;
5594 }
5595
5596 final long origId = Binder.clearCallingIdentity();
5597
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005598 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005599 // return it right away.
5600 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005601 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005602 "Adding provider requested by "
5603 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005604 + cpr.info.processName);
5605 Integer cnt = r.conProviders.get(cpr);
5606 if (cnt == null) {
5607 r.conProviders.put(cpr, new Integer(1));
5608 } else {
5609 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5610 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005611 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005612 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5613 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005614 // make sure to count it as being accessed and thus
5615 // back up on the LRU list. This is good because
5616 // content providers are often expensive to start.
5617 updateLruProcessLocked(cpr.app, false, true);
5618 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005619 } else {
5620 cpr.externals++;
5621 }
5622
5623 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 updateOomAdjLocked(cpr.app);
5625 }
5626
5627 Binder.restoreCallingIdentity(origId);
5628
5629 } else {
5630 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005631 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005632 resolveContentProvider(name,
5633 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005634 } catch (RemoteException ex) {
5635 }
5636 if (cpi == null) {
5637 return null;
5638 }
5639
Dianne Hackbornb424b632010-08-18 15:59:05 -07005640 String msg;
5641 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5642 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 }
5644
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005645 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005646 && !cpi.processName.equals("system")) {
5647 // If this content provider does not run in the system
5648 // process, and the system is not yet ready to run other
5649 // processes, then fail fast instead of hanging.
5650 throw new IllegalArgumentException(
5651 "Attempt to launch content provider before system ready");
5652 }
5653
Dianne Hackborn860755f2010-06-03 18:47:52 -07005654 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005655 final boolean firstClass = cpr == null;
5656 if (firstClass) {
5657 try {
5658 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005659 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005660 getApplicationInfo(
5661 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005662 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005663 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005664 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005665 + cpi.name);
5666 return null;
5667 }
5668 cpr = new ContentProviderRecord(cpi, ai);
5669 } catch (RemoteException ex) {
5670 // pm is in same process, this will never happen.
5671 }
5672 }
5673
5674 if (r != null && cpr.canRunHere(r)) {
5675 // If this is a multiprocess provider, then just return its
5676 // info and allow the caller to instantiate it. Only do
5677 // this if the provider is the same user as the caller's
5678 // process, or can run as root (so can be in any process).
5679 return cpr;
5680 }
5681
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005682 if (DEBUG_PROVIDER) {
5683 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005684 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005685 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005686 }
5687
5688 // This is single process, and our app is now connecting to it.
5689 // See if we are already in the process of launching this
5690 // provider.
5691 final int N = mLaunchingProviders.size();
5692 int i;
5693 for (i=0; i<N; i++) {
5694 if (mLaunchingProviders.get(i) == cpr) {
5695 break;
5696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 }
5698
5699 // If the provider is not already being launched, then get it
5700 // started.
5701 if (i >= N) {
5702 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005703
5704 try {
5705 // Content provider is now in use, its package can't be stopped.
5706 try {
5707 AppGlobals.getPackageManager().setPackageStoppedState(
5708 cpr.appInfo.packageName, false);
5709 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005710 } catch (IllegalArgumentException e) {
5711 Slog.w(TAG, "Failed trying to unstop package "
5712 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005713 }
5714
5715 ProcessRecord proc = startProcessLocked(cpi.processName,
5716 cpr.appInfo, false, 0, "content provider",
5717 new ComponentName(cpi.applicationInfo.packageName,
5718 cpi.name), false);
5719 if (proc == null) {
5720 Slog.w(TAG, "Unable to launch app "
5721 + cpi.applicationInfo.packageName + "/"
5722 + cpi.applicationInfo.uid + " for provider "
5723 + name + ": process is bad");
5724 return null;
5725 }
5726 cpr.launchingApp = proc;
5727 mLaunchingProviders.add(cpr);
5728 } finally {
5729 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005730 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005731 }
5732
5733 // Make sure the provider is published (the same provider class
5734 // may be published under multiple names).
5735 if (firstClass) {
5736 mProvidersByClass.put(cpi.name, cpr);
5737 }
5738 mProvidersByName.put(name, cpr);
5739
5740 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005741 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005742 "Adding provider requested by "
5743 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005744 + cpr.info.processName);
5745 Integer cnt = r.conProviders.get(cpr);
5746 if (cnt == null) {
5747 r.conProviders.put(cpr, new Integer(1));
5748 } else {
5749 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5750 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 cpr.clients.add(r);
5752 } else {
5753 cpr.externals++;
5754 }
5755 }
5756 }
5757
5758 // Wait for the provider to be published...
5759 synchronized (cpr) {
5760 while (cpr.provider == null) {
5761 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005762 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 + cpi.applicationInfo.packageName + "/"
5764 + cpi.applicationInfo.uid + " for provider "
5765 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005766 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005767 cpi.applicationInfo.packageName,
5768 cpi.applicationInfo.uid, name);
5769 return null;
5770 }
5771 try {
5772 cpr.wait();
5773 } catch (InterruptedException ex) {
5774 }
5775 }
5776 }
5777 return cpr;
5778 }
5779
5780 public final ContentProviderHolder getContentProvider(
5781 IApplicationThread caller, String name) {
5782 if (caller == null) {
5783 String msg = "null IApplicationThread when getting content provider "
5784 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005785 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005786 throw new SecurityException(msg);
5787 }
5788
5789 return getContentProviderImpl(caller, name);
5790 }
5791
5792 private ContentProviderHolder getContentProviderExternal(String name) {
5793 return getContentProviderImpl(null, name);
5794 }
5795
5796 /**
5797 * Drop a content provider from a ProcessRecord's bookkeeping
5798 * @param cpr
5799 */
5800 public void removeContentProvider(IApplicationThread caller, String name) {
5801 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005802 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005803 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005804 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005805 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005806 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005807 return;
5808 }
5809 final ProcessRecord r = getRecordForAppLocked(caller);
5810 if (r == null) {
5811 throw new SecurityException(
5812 "Unable to find app for caller " + caller +
5813 " when removing content provider " + name);
5814 }
5815 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005816 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005817 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005818 + r.info.processName + " from process "
5819 + localCpr.appInfo.processName);
5820 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005821 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005822 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005823 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005824 return;
5825 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005826 Integer cnt = r.conProviders.get(localCpr);
5827 if (cnt == null || cnt.intValue() <= 1) {
5828 localCpr.clients.remove(r);
5829 r.conProviders.remove(localCpr);
5830 } else {
5831 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005833 }
5834 updateOomAdjLocked();
5835 }
5836 }
5837
5838 private void removeContentProviderExternal(String name) {
5839 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005840 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005841 if(cpr == null) {
5842 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005843 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005844 return;
5845 }
5846
5847 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005848 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005849 localCpr.externals--;
5850 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005851 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005852 }
5853 updateOomAdjLocked();
5854 }
5855 }
5856
5857 public final void publishContentProviders(IApplicationThread caller,
5858 List<ContentProviderHolder> providers) {
5859 if (providers == null) {
5860 return;
5861 }
5862
5863 synchronized(this) {
5864 final ProcessRecord r = getRecordForAppLocked(caller);
5865 if (r == null) {
5866 throw new SecurityException(
5867 "Unable to find app for caller " + caller
5868 + " (pid=" + Binder.getCallingPid()
5869 + ") when publishing content providers");
5870 }
5871
5872 final long origId = Binder.clearCallingIdentity();
5873
5874 final int N = providers.size();
5875 for (int i=0; i<N; i++) {
5876 ContentProviderHolder src = providers.get(i);
5877 if (src == null || src.info == null || src.provider == null) {
5878 continue;
5879 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005880 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005881 if (dst != null) {
5882 mProvidersByClass.put(dst.info.name, dst);
5883 String names[] = dst.info.authority.split(";");
5884 for (int j = 0; j < names.length; j++) {
5885 mProvidersByName.put(names[j], dst);
5886 }
5887
5888 int NL = mLaunchingProviders.size();
5889 int j;
5890 for (j=0; j<NL; j++) {
5891 if (mLaunchingProviders.get(j) == dst) {
5892 mLaunchingProviders.remove(j);
5893 j--;
5894 NL--;
5895 }
5896 }
5897 synchronized (dst) {
5898 dst.provider = src.provider;
5899 dst.app = r;
5900 dst.notifyAll();
5901 }
5902 updateOomAdjLocked(r);
5903 }
5904 }
5905
5906 Binder.restoreCallingIdentity(origId);
5907 }
5908 }
5909
5910 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005911 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005912 synchronized (mSelf) {
5913 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5914 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005915 if (providers != null) {
5916 for (int i=providers.size()-1; i>=0; i--) {
5917 ProviderInfo pi = (ProviderInfo)providers.get(i);
5918 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5919 Slog.w(TAG, "Not installing system proc provider " + pi.name
5920 + ": not system .apk");
5921 providers.remove(i);
5922 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005923 }
5924 }
5925 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005926 if (providers != null) {
5927 mSystemThread.installSystemProviders(providers);
5928 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005929
5930 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 }
5932
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005933 /**
5934 * Allows app to retrieve the MIME type of a URI without having permission
5935 * to access its content provider.
5936 *
5937 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5938 *
5939 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5940 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5941 */
5942 public String getProviderMimeType(Uri uri) {
5943 final String name = uri.getAuthority();
5944 final long ident = Binder.clearCallingIdentity();
5945 ContentProviderHolder holder = null;
5946
5947 try {
5948 holder = getContentProviderExternal(name);
5949 if (holder != null) {
5950 return holder.provider.getType(uri);
5951 }
5952 } catch (RemoteException e) {
5953 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5954 return null;
5955 } finally {
5956 if (holder != null) {
5957 removeContentProviderExternal(name);
5958 }
5959 Binder.restoreCallingIdentity(ident);
5960 }
5961
5962 return null;
5963 }
5964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005965 // =========================================================
5966 // GLOBAL MANAGEMENT
5967 // =========================================================
5968
5969 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5970 ApplicationInfo info, String customProcess) {
5971 String proc = customProcess != null ? customProcess : info.processName;
5972 BatteryStatsImpl.Uid.Proc ps = null;
5973 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5974 synchronized (stats) {
5975 ps = stats.getProcessStatsLocked(info.uid, proc);
5976 }
5977 return new ProcessRecord(ps, thread, info, proc);
5978 }
5979
5980 final ProcessRecord addAppLocked(ApplicationInfo info) {
5981 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5982
5983 if (app == null) {
5984 app = newProcessRecordLocked(null, info, null);
5985 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005986 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 }
5988
Dianne Hackborne7f97212011-02-24 14:40:20 -08005989 // This package really, really can not be stopped.
5990 try {
5991 AppGlobals.getPackageManager().setPackageStoppedState(
5992 info.packageName, false);
5993 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005994 } catch (IllegalArgumentException e) {
5995 Slog.w(TAG, "Failed trying to unstop package "
5996 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005997 }
5998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005999 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6000 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6001 app.persistent = true;
6002 app.maxAdj = CORE_SERVER_ADJ;
6003 }
6004 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6005 mPersistentStartingProcesses.add(app);
6006 startProcessLocked(app, "added application", app.processName);
6007 }
6008
6009 return app;
6010 }
6011
6012 public void unhandledBack() {
6013 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6014 "unhandledBack()");
6015
6016 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006017 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006018 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 TAG, "Performing unhandledBack(): stack size = " + count);
6020 if (count > 1) {
6021 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006022 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006023 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6024 Binder.restoreCallingIdentity(origId);
6025 }
6026 }
6027 }
6028
6029 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6030 String name = uri.getAuthority();
6031 ContentProviderHolder cph = getContentProviderExternal(name);
6032 ParcelFileDescriptor pfd = null;
6033 if (cph != null) {
6034 // We record the binder invoker's uid in thread-local storage before
6035 // going to the content provider to open the file. Later, in the code
6036 // that handles all permissions checks, we look for this uid and use
6037 // that rather than the Activity Manager's own uid. The effect is that
6038 // we do the check against the caller's permissions even though it looks
6039 // to the content provider like the Activity Manager itself is making
6040 // the request.
6041 sCallerIdentity.set(new Identity(
6042 Binder.getCallingPid(), Binder.getCallingUid()));
6043 try {
6044 pfd = cph.provider.openFile(uri, "r");
6045 } catch (FileNotFoundException e) {
6046 // do nothing; pfd will be returned null
6047 } finally {
6048 // Ensure that whatever happens, we clean up the identity state
6049 sCallerIdentity.remove();
6050 }
6051
6052 // We've got the fd now, so we're done with the provider.
6053 removeContentProviderExternal(name);
6054 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006055 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006056 }
6057 return pfd;
6058 }
6059
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006060 // Actually is sleeping or shutting down or whatever else in the future
6061 // is an inactive state.
6062 public boolean isSleeping() {
6063 return mSleeping || mShuttingDown;
6064 }
6065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 public void goingToSleep() {
6067 synchronized(this) {
6068 mSleeping = true;
6069 mWindowManager.setEventDispatching(false);
6070
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006071 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006072
6073 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006074 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006075 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6076 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006077 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006078 }
6079 }
6080
Dianne Hackborn55280a92009-05-07 15:53:46 -07006081 public boolean shutdown(int timeout) {
6082 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6083 != PackageManager.PERMISSION_GRANTED) {
6084 throw new SecurityException("Requires permission "
6085 + android.Manifest.permission.SHUTDOWN);
6086 }
6087
6088 boolean timedout = false;
6089
6090 synchronized(this) {
6091 mShuttingDown = true;
6092 mWindowManager.setEventDispatching(false);
6093
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006094 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006095 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006096 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006097 while (mMainStack.mResumedActivity != null
6098 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006099 long delay = endTime - System.currentTimeMillis();
6100 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006101 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006102 timedout = true;
6103 break;
6104 }
6105 try {
6106 this.wait();
6107 } catch (InterruptedException e) {
6108 }
6109 }
6110 }
6111 }
6112
6113 mUsageStatsService.shutdown();
6114 mBatteryStatsService.shutdown();
6115
6116 return timedout;
6117 }
6118
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006119 public final void activitySlept(IBinder token) {
6120 if (localLOGV) Slog.v(
6121 TAG, "Activity slept: token=" + token);
6122
6123 ActivityRecord r = null;
6124
6125 final long origId = Binder.clearCallingIdentity();
6126
6127 synchronized (this) {
6128 int index = mMainStack.indexOfTokenLocked(token);
6129 if (index >= 0) {
6130 r = (ActivityRecord)mMainStack.mHistory.get(index);
6131 mMainStack.activitySleptLocked(r);
6132 }
6133 }
6134
6135 Binder.restoreCallingIdentity(origId);
6136 }
6137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006138 public void wakingUp() {
6139 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 mWindowManager.setEventDispatching(true);
6141 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006142 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006143 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006144 }
6145 }
6146
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006147 public void stopAppSwitches() {
6148 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6149 != PackageManager.PERMISSION_GRANTED) {
6150 throw new SecurityException("Requires permission "
6151 + android.Manifest.permission.STOP_APP_SWITCHES);
6152 }
6153
6154 synchronized(this) {
6155 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6156 + APP_SWITCH_DELAY_TIME;
6157 mDidAppSwitch = false;
6158 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6159 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6160 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6161 }
6162 }
6163
6164 public void resumeAppSwitches() {
6165 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6166 != PackageManager.PERMISSION_GRANTED) {
6167 throw new SecurityException("Requires permission "
6168 + android.Manifest.permission.STOP_APP_SWITCHES);
6169 }
6170
6171 synchronized(this) {
6172 // Note that we don't execute any pending app switches... we will
6173 // let those wait until either the timeout, or the next start
6174 // activity request.
6175 mAppSwitchesAllowedTime = 0;
6176 }
6177 }
6178
6179 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6180 String name) {
6181 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6182 return true;
6183 }
6184
6185 final int perm = checkComponentPermission(
6186 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006187 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006188 if (perm == PackageManager.PERMISSION_GRANTED) {
6189 return true;
6190 }
6191
Joe Onorato8a9b2202010-02-26 18:56:32 -08006192 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006193 return false;
6194 }
6195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006196 public void setDebugApp(String packageName, boolean waitForDebugger,
6197 boolean persistent) {
6198 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6199 "setDebugApp()");
6200
6201 // Note that this is not really thread safe if there are multiple
6202 // callers into it at the same time, but that's not a situation we
6203 // care about.
6204 if (persistent) {
6205 final ContentResolver resolver = mContext.getContentResolver();
6206 Settings.System.putString(
6207 resolver, Settings.System.DEBUG_APP,
6208 packageName);
6209 Settings.System.putInt(
6210 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6211 waitForDebugger ? 1 : 0);
6212 }
6213
6214 synchronized (this) {
6215 if (!persistent) {
6216 mOrigDebugApp = mDebugApp;
6217 mOrigWaitForDebugger = mWaitForDebugger;
6218 }
6219 mDebugApp = packageName;
6220 mWaitForDebugger = waitForDebugger;
6221 mDebugTransient = !persistent;
6222 if (packageName != null) {
6223 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006224 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006225 Binder.restoreCallingIdentity(origId);
6226 }
6227 }
6228 }
6229
6230 public void setAlwaysFinish(boolean enabled) {
6231 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6232 "setAlwaysFinish()");
6233
6234 Settings.System.putInt(
6235 mContext.getContentResolver(),
6236 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6237
6238 synchronized (this) {
6239 mAlwaysFinishActivities = enabled;
6240 }
6241 }
6242
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006243 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006244 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006245 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006246 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006247 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006248 }
6249 }
6250
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006251 public boolean isUserAMonkey() {
6252 // For now the fact that there is a controller implies
6253 // we have a monkey.
6254 synchronized (this) {
6255 return mController != null;
6256 }
6257 }
6258
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006259 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006260 synchronized (this) {
6261 mWatchers.register(watcher);
6262 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006263 }
6264
6265 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006266 synchronized (this) {
6267 mWatchers.unregister(watcher);
6268 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006269 }
6270
Jeff Sharkeya4620792011-05-20 15:29:23 -07006271 public void registerProcessObserver(IProcessObserver observer) {
6272 mProcessObservers.register(observer);
6273 }
6274
6275 public void unregisterProcessObserver(IProcessObserver observer) {
6276 mProcessObservers.unregister(observer);
6277 }
6278
Daniel Sandler69a48172010-06-23 16:29:36 -04006279 public void setImmersive(IBinder token, boolean immersive) {
6280 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006281 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006282 if (index < 0) {
6283 throw new IllegalArgumentException();
6284 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006285 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006286 r.immersive = immersive;
6287 }
6288 }
6289
6290 public boolean isImmersive(IBinder token) {
6291 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006292 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006293 if (index < 0) {
6294 throw new IllegalArgumentException();
6295 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006296 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006297 return r.immersive;
6298 }
6299 }
6300
6301 public boolean isTopActivityImmersive() {
6302 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006303 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006304 return (r != null) ? r.immersive : false;
6305 }
6306 }
6307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 public final void enterSafeMode() {
6309 synchronized(this) {
6310 // It only makes sense to do this before the system is ready
6311 // and started launching other packages.
6312 if (!mSystemReady) {
6313 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006314 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006315 } catch (RemoteException e) {
6316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 }
6318 }
6319 }
6320
Jeff Brownb09abc12011-01-13 21:08:27 -08006321 public final void showSafeModeOverlay() {
6322 View v = LayoutInflater.from(mContext).inflate(
6323 com.android.internal.R.layout.safe_mode, null);
6324 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6325 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6326 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6327 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6328 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6329 lp.format = v.getBackground().getOpacity();
6330 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6331 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6332 ((WindowManager)mContext.getSystemService(
6333 Context.WINDOW_SERVICE)).addView(v, lp);
6334 }
6335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 public void noteWakeupAlarm(IIntentSender sender) {
6337 if (!(sender instanceof PendingIntentRecord)) {
6338 return;
6339 }
6340 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6341 synchronized (stats) {
6342 if (mBatteryStatsService.isOnBattery()) {
6343 mBatteryStatsService.enforceCallingPermission();
6344 PendingIntentRecord rec = (PendingIntentRecord)sender;
6345 int MY_UID = Binder.getCallingUid();
6346 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6347 BatteryStatsImpl.Uid.Pkg pkg =
6348 stats.getPackageStatsLocked(uid, rec.key.packageName);
6349 pkg.incWakeupsLocked();
6350 }
6351 }
6352 }
6353
Dianne Hackborn64825172011-03-02 21:32:58 -08006354 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006355 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006356 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006357 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006358 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 // XXX Note: don't acquire main activity lock here, because the window
6360 // manager calls in with its locks held.
6361
6362 boolean killed = false;
6363 synchronized (mPidsSelfLocked) {
6364 int[] types = new int[pids.length];
6365 int worstType = 0;
6366 for (int i=0; i<pids.length; i++) {
6367 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6368 if (proc != null) {
6369 int type = proc.setAdj;
6370 types[i] = type;
6371 if (type > worstType) {
6372 worstType = type;
6373 }
6374 }
6375 }
6376
Dianne Hackborn64825172011-03-02 21:32:58 -08006377 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006378 // then constrain it so we will kill all hidden procs.
6379 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6380 worstType = HIDDEN_APP_MIN_ADJ;
6381 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006382
6383 // If this is not a secure call, don't let it kill processes that
6384 // are important.
6385 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6386 worstType = SECONDARY_SERVER_ADJ;
6387 }
6388
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006389 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006390 for (int i=0; i<pids.length; i++) {
6391 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6392 if (proc == null) {
6393 continue;
6394 }
6395 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006396 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006397 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006398 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6399 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006400 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006401 proc.killedBackground = true;
6402 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006403 }
6404 }
6405 }
6406 return killed;
6407 }
6408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006409 public final void startRunning(String pkg, String cls, String action,
6410 String data) {
6411 synchronized(this) {
6412 if (mStartRunning) {
6413 return;
6414 }
6415 mStartRunning = true;
6416 mTopComponent = pkg != null && cls != null
6417 ? new ComponentName(pkg, cls) : null;
6418 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6419 mTopData = data;
6420 if (!mSystemReady) {
6421 return;
6422 }
6423 }
6424
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006425 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006426 }
6427
6428 private void retrieveSettings() {
6429 final ContentResolver resolver = mContext.getContentResolver();
6430 String debugApp = Settings.System.getString(
6431 resolver, Settings.System.DEBUG_APP);
6432 boolean waitForDebugger = Settings.System.getInt(
6433 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6434 boolean alwaysFinishActivities = Settings.System.getInt(
6435 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6436
6437 Configuration configuration = new Configuration();
6438 Settings.System.getConfiguration(resolver, configuration);
6439
6440 synchronized (this) {
6441 mDebugApp = mOrigDebugApp = debugApp;
6442 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6443 mAlwaysFinishActivities = alwaysFinishActivities;
6444 // This happens before any activities are started, so we can
6445 // change mConfiguration in-place.
6446 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006447 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006448 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006449 }
6450 }
6451
6452 public boolean testIsSystemReady() {
6453 // no need to synchronize(this) just to read & return the value
6454 return mSystemReady;
6455 }
6456
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006457 private static File getCalledPreBootReceiversFile() {
6458 File dataDir = Environment.getDataDirectory();
6459 File systemDir = new File(dataDir, "system");
6460 File fname = new File(systemDir, "called_pre_boots.dat");
6461 return fname;
6462 }
6463
6464 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6465 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6466 File file = getCalledPreBootReceiversFile();
6467 FileInputStream fis = null;
6468 try {
6469 fis = new FileInputStream(file);
6470 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6471 int vers = dis.readInt();
6472 String codename = dis.readUTF();
6473 if (vers == android.os.Build.VERSION.SDK_INT
6474 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6475 int num = dis.readInt();
6476 while (num > 0) {
6477 num--;
6478 String pkg = dis.readUTF();
6479 String cls = dis.readUTF();
6480 lastDoneReceivers.add(new ComponentName(pkg, cls));
6481 }
6482 }
6483 } catch (FileNotFoundException e) {
6484 } catch (IOException e) {
6485 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6486 } finally {
6487 if (fis != null) {
6488 try {
6489 fis.close();
6490 } catch (IOException e) {
6491 }
6492 }
6493 }
6494 return lastDoneReceivers;
6495 }
6496
6497 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6498 File file = getCalledPreBootReceiversFile();
6499 FileOutputStream fos = null;
6500 DataOutputStream dos = null;
6501 try {
6502 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6503 fos = new FileOutputStream(file);
6504 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6505 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6506 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6507 dos.writeInt(list.size());
6508 for (int i=0; i<list.size(); i++) {
6509 dos.writeUTF(list.get(i).getPackageName());
6510 dos.writeUTF(list.get(i).getClassName());
6511 }
6512 } catch (IOException e) {
6513 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6514 file.delete();
6515 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006516 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006517 if (dos != null) {
6518 try {
6519 dos.close();
6520 } catch (IOException e) {
6521 // TODO Auto-generated catch block
6522 e.printStackTrace();
6523 }
6524 }
6525 }
6526 }
6527
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006528 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006529 // In the simulator, startRunning will never have been called, which
6530 // normally sets a few crucial variables. Do it here instead.
6531 if (!Process.supportsProcesses()) {
6532 mStartRunning = true;
6533 mTopAction = Intent.ACTION_MAIN;
6534 }
6535
6536 synchronized(this) {
6537 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006538 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006539 return;
6540 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006541
6542 // Check to see if there are any update receivers to run.
6543 if (!mDidUpdate) {
6544 if (mWaitingUpdate) {
6545 return;
6546 }
6547 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6548 List<ResolveInfo> ris = null;
6549 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006550 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006551 intent, null, 0);
6552 } catch (RemoteException e) {
6553 }
6554 if (ris != null) {
6555 for (int i=ris.size()-1; i>=0; i--) {
6556 if ((ris.get(i).activityInfo.applicationInfo.flags
6557 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6558 ris.remove(i);
6559 }
6560 }
6561 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006562
6563 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6564
6565 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006566 for (int i=0; i<ris.size(); i++) {
6567 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006568 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6569 if (lastDoneReceivers.contains(comp)) {
6570 ris.remove(i);
6571 i--;
6572 }
6573 }
6574
6575 for (int i=0; i<ris.size(); i++) {
6576 ActivityInfo ai = ris.get(i).activityInfo;
6577 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6578 doneReceivers.add(comp);
6579 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006580 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006581 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006582 finisher = new IIntentReceiver.Stub() {
6583 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006584 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006585 boolean sticky) {
6586 // The raw IIntentReceiver interface is called
6587 // with the AM lock held, so redispatch to
6588 // execute our code without the lock.
6589 mHandler.post(new Runnable() {
6590 public void run() {
6591 synchronized (ActivityManagerService.this) {
6592 mDidUpdate = true;
6593 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006594 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006595 systemReady(goingCallback);
6596 }
6597 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006598 }
6599 };
6600 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006601 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006602 broadcastIntentLocked(null, null, intent, null, finisher,
6603 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006604 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006605 mWaitingUpdate = true;
6606 }
6607 }
6608 }
6609 if (mWaitingUpdate) {
6610 return;
6611 }
6612 mDidUpdate = true;
6613 }
6614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006615 mSystemReady = true;
6616 if (!mStartRunning) {
6617 return;
6618 }
6619 }
6620
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006621 ArrayList<ProcessRecord> procsToKill = null;
6622 synchronized(mPidsSelfLocked) {
6623 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6624 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6625 if (!isAllowedWhileBooting(proc.info)){
6626 if (procsToKill == null) {
6627 procsToKill = new ArrayList<ProcessRecord>();
6628 }
6629 procsToKill.add(proc);
6630 }
6631 }
6632 }
6633
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006634 synchronized(this) {
6635 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006636 for (int i=procsToKill.size()-1; i>=0; i--) {
6637 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006638 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006639 removeProcessLocked(proc, true);
6640 }
6641 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006642
6643 // Now that we have cleaned up any update processes, we
6644 // are ready to start launching real processes and know that
6645 // we won't trample on them any more.
6646 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006647 }
6648
Joe Onorato8a9b2202010-02-26 18:56:32 -08006649 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006650 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 SystemClock.uptimeMillis());
6652
6653 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006654 // Make sure we have no pre-ready processes sitting around.
6655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6657 ResolveInfo ri = mContext.getPackageManager()
6658 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006659 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 CharSequence errorMsg = null;
6661 if (ri != null) {
6662 ActivityInfo ai = ri.activityInfo;
6663 ApplicationInfo app = ai.applicationInfo;
6664 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6665 mTopAction = Intent.ACTION_FACTORY_TEST;
6666 mTopData = null;
6667 mTopComponent = new ComponentName(app.packageName,
6668 ai.name);
6669 } else {
6670 errorMsg = mContext.getResources().getText(
6671 com.android.internal.R.string.factorytest_not_system);
6672 }
6673 } else {
6674 errorMsg = mContext.getResources().getText(
6675 com.android.internal.R.string.factorytest_no_action);
6676 }
6677 if (errorMsg != null) {
6678 mTopAction = null;
6679 mTopData = null;
6680 mTopComponent = null;
6681 Message msg = Message.obtain();
6682 msg.what = SHOW_FACTORY_ERROR_MSG;
6683 msg.getData().putCharSequence("msg", errorMsg);
6684 mHandler.sendMessage(msg);
6685 }
6686 }
6687 }
6688
6689 retrieveSettings();
6690
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006691 if (goingCallback != null) goingCallback.run();
6692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006693 synchronized (this) {
6694 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6695 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006696 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006697 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 if (apps != null) {
6699 int N = apps.size();
6700 int i;
6701 for (i=0; i<N; i++) {
6702 ApplicationInfo info
6703 = (ApplicationInfo)apps.get(i);
6704 if (info != null &&
6705 !info.packageName.equals("android")) {
6706 addAppLocked(info);
6707 }
6708 }
6709 }
6710 } catch (RemoteException ex) {
6711 // pm is in same process, this will never happen.
6712 }
6713 }
6714
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006715 // Start up initial activity.
6716 mBooting = true;
6717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006718 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006719 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 Message msg = Message.obtain();
6721 msg.what = SHOW_UID_ERROR_MSG;
6722 mHandler.sendMessage(msg);
6723 }
6724 } catch (RemoteException e) {
6725 }
6726
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006727 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006728 }
6729 }
6730
Dan Egnorb7f03672009-12-09 16:22:32 -08006731 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006732 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006733 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006734 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006735 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006736 startAppProblemLocked(app);
6737 app.stopFreezingAllLocked();
6738 return handleAppCrashLocked(app);
6739 }
6740
Dan Egnorb7f03672009-12-09 16:22:32 -08006741 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006742 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006743 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006744 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006745 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6746 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006747 startAppProblemLocked(app);
6748 app.stopFreezingAllLocked();
6749 }
6750
6751 /**
6752 * Generate a process error record, suitable for attachment to a ProcessRecord.
6753 *
6754 * @param app The ProcessRecord in which the error occurred.
6755 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6756 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006757 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 * @param shortMsg Short message describing the crash.
6759 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006760 * @param stackTrace Full crash stack trace, may be null.
6761 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 * @return Returns a fully-formed AppErrorStateInfo record.
6763 */
6764 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006765 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006766 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006768 report.condition = condition;
6769 report.processName = app.processName;
6770 report.pid = app.pid;
6771 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006772 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006773 report.shortMsg = shortMsg;
6774 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006775 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776
6777 return report;
6778 }
6779
Dan Egnor42471dd2010-01-07 17:25:22 -08006780 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006781 synchronized (this) {
6782 app.crashing = false;
6783 app.crashingReport = null;
6784 app.notResponding = false;
6785 app.notRespondingReport = null;
6786 if (app.anrDialog == fromDialog) {
6787 app.anrDialog = null;
6788 }
6789 if (app.waitDialog == fromDialog) {
6790 app.waitDialog = null;
6791 }
6792 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006793 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006794 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006795 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6796 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006797 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 }
6800 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006801
Dan Egnorb7f03672009-12-09 16:22:32 -08006802 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006803 long now = SystemClock.uptimeMillis();
6804
6805 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6806 app.info.uid);
6807 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6808 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006809 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006811 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006812 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006813 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6814 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006816 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006817 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006818 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006819 }
6820 }
6821 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006822 // Don't let services in this process be restarted and potentially
6823 // annoy the user repeatedly. Unless it is persistent, since those
6824 // processes run critical code.
6825 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 // We don't want to start this process again until the user
6827 // explicitly does so... but for persistent process, we really
6828 // need to keep it running. If a persistent process is actually
6829 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006830 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006831 app.info.processName);
6832 mBadProcesses.put(app.info.processName, app.info.uid, now);
6833 app.bad = true;
6834 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6835 app.removed = true;
6836 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006837 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006838 return false;
6839 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006840 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006841 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006842 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006843 if (r.app == app) {
6844 // If the top running activity is from this crashing
6845 // process, then terminate it to avoid getting in a loop.
6846 Slog.w(TAG, " Force finishing activity "
6847 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006848 int index = mMainStack.indexOfTokenLocked(r);
6849 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006850 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006851 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006852 // stopped, to avoid a situation where one will get
6853 // re-start our crashing activity once it gets resumed again.
6854 index--;
6855 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006856 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006857 if (r.state == ActivityState.RESUMED
6858 || r.state == ActivityState.PAUSING
6859 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006860 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006861 Slog.w(TAG, " Force finishing activity "
6862 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006863 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006864 Activity.RESULT_CANCELED, null, "crashed");
6865 }
6866 }
6867 }
6868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006869 }
6870
6871 // Bump up the crash count of any services currently running in the proc.
6872 if (app.services.size() != 0) {
6873 // Any services running in the application need to be placed
6874 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006875 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006877 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006878 sr.crashCount++;
6879 }
6880 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006881
6882 // If the crashing process is what we consider to be the "home process" and it has been
6883 // replaced by a third-party app, clear the package preferred activities from packages
6884 // with a home activity running in the process to prevent a repeatedly crashing app
6885 // from blocking the user to manually clear the list.
6886 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6887 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6888 Iterator it = mHomeProcess.activities.iterator();
6889 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006890 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006891 if (r.isHomeActivity) {
6892 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6893 try {
6894 ActivityThread.getPackageManager()
6895 .clearPackagePreferredActivities(r.packageName);
6896 } catch (RemoteException c) {
6897 // pm is in same process, this will never happen.
6898 }
6899 }
6900 }
6901 }
6902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006903 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6904 return true;
6905 }
6906
6907 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006908 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6909 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006910 skipCurrentReceiverLocked(app);
6911 }
6912
6913 void skipCurrentReceiverLocked(ProcessRecord app) {
6914 boolean reschedule = false;
6915 BroadcastRecord r = app.curReceiver;
6916 if (r != null) {
6917 // The current broadcast is waiting for this app's receiver
6918 // to be finished. Looks like that's not going to happen, so
6919 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006920 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006921 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6922 r.resultExtras, r.resultAbort, true);
6923 reschedule = true;
6924 }
6925 r = mPendingBroadcast;
6926 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006927 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006928 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006929 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006930 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6931 r.resultExtras, r.resultAbort, true);
6932 reschedule = true;
6933 }
6934 if (reschedule) {
6935 scheduleBroadcastsLocked();
6936 }
6937 }
6938
Dan Egnor60d87622009-12-16 16:32:58 -08006939 /**
6940 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6941 * The application process will exit immediately after this call returns.
6942 * @param app object of the crashing app, null for the system server
6943 * @param crashInfo describing the exception
6944 */
6945 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006946 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006947
6948 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6949 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006950 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006951 crashInfo.exceptionClassName,
6952 crashInfo.exceptionMessage,
6953 crashInfo.throwFileName,
6954 crashInfo.throwLineNumber);
6955
Dan Egnor42471dd2010-01-07 17:25:22 -08006956 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006957
6958 crashApplication(r, crashInfo);
6959 }
6960
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006961 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006962 IBinder app,
6963 int violationMask,
6964 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006965 ProcessRecord r = findAppProcess(app, "StrictMode");
6966 if (r == null) {
6967 return;
6968 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006969
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006970 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006971 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006972 boolean logIt = true;
6973 synchronized (mAlreadyLoggedViolatedStacks) {
6974 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6975 logIt = false;
6976 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006977 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006978 // the relative pain numbers, without logging all
6979 // the stack traces repeatedly. We'd want to do
6980 // likewise in the client code, which also does
6981 // dup suppression, before the Binder call.
6982 } else {
6983 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6984 mAlreadyLoggedViolatedStacks.clear();
6985 }
6986 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6987 }
6988 }
6989 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006990 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006991 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006992 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006993
6994 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6995 AppErrorResult result = new AppErrorResult();
6996 synchronized (this) {
6997 final long origId = Binder.clearCallingIdentity();
6998
6999 Message msg = Message.obtain();
7000 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7001 HashMap<String, Object> data = new HashMap<String, Object>();
7002 data.put("result", result);
7003 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007004 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007005 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007006 msg.obj = data;
7007 mHandler.sendMessage(msg);
7008
7009 Binder.restoreCallingIdentity(origId);
7010 }
7011 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007012 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007013 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007014 }
7015
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007016 // Depending on the policy in effect, there could be a bunch of
7017 // these in quick succession so we try to batch these together to
7018 // minimize disk writes, number of dropbox entries, and maximize
7019 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007020 private void logStrictModeViolationToDropBox(
7021 ProcessRecord process,
7022 StrictMode.ViolationInfo info) {
7023 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007024 return;
7025 }
7026 final boolean isSystemApp = process == null ||
7027 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7028 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7029 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7030 final DropBoxManager dbox = (DropBoxManager)
7031 mContext.getSystemService(Context.DROPBOX_SERVICE);
7032
7033 // Exit early if the dropbox isn't configured to accept this report type.
7034 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7035
7036 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007037 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007038 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7039 synchronized (sb) {
7040 bufferWasEmpty = sb.length() == 0;
7041 appendDropBoxProcessHeaders(process, sb);
7042 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7043 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007044 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7045 if (info.violationNumThisLoop != 0) {
7046 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7047 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007048 if (info.numAnimationsRunning != 0) {
7049 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7050 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007051 if (info.broadcastIntentAction != null) {
7052 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7053 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007054 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007055 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007056 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007057 if (info.numInstances != -1) {
7058 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7059 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007060 if (info.tags != null) {
7061 for (String tag : info.tags) {
7062 sb.append("Span-Tag: ").append(tag).append("\n");
7063 }
7064 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007065 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007066 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7067 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007068 }
7069 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007070
7071 // Only buffer up to ~64k. Various logging bits truncate
7072 // things at 128k.
7073 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007074 }
7075
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007076 // Flush immediately if the buffer's grown too large, or this
7077 // is a non-system app. Non-system apps are isolated with a
7078 // different tag & policy and not batched.
7079 //
7080 // Batching is useful during internal testing with
7081 // StrictMode settings turned up high. Without batching,
7082 // thousands of separate files could be created on boot.
7083 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007084 new Thread("Error dump: " + dropboxTag) {
7085 @Override
7086 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007087 String report;
7088 synchronized (sb) {
7089 report = sb.toString();
7090 sb.delete(0, sb.length());
7091 sb.trimToSize();
7092 }
7093 if (report.length() != 0) {
7094 dbox.addText(dropboxTag, report);
7095 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007096 }
7097 }.start();
7098 return;
7099 }
7100
7101 // System app batching:
7102 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007103 // An existing dropbox-writing thread is outstanding, so
7104 // we don't need to start it up. The existing thread will
7105 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007106 return;
7107 }
7108
7109 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7110 // (After this point, we shouldn't access AMS internal data structures.)
7111 new Thread("Error dump: " + dropboxTag) {
7112 @Override
7113 public void run() {
7114 // 5 second sleep to let stacks arrive and be batched together
7115 try {
7116 Thread.sleep(5000); // 5 seconds
7117 } catch (InterruptedException e) {}
7118
7119 String errorReport;
7120 synchronized (mStrictModeBuffer) {
7121 errorReport = mStrictModeBuffer.toString();
7122 if (errorReport.length() == 0) {
7123 return;
7124 }
7125 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7126 mStrictModeBuffer.trimToSize();
7127 }
7128 dbox.addText(dropboxTag, errorReport);
7129 }
7130 }.start();
7131 }
7132
Dan Egnor60d87622009-12-16 16:32:58 -08007133 /**
7134 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7135 * @param app object of the crashing app, null for the system server
7136 * @param tag reported by the caller
7137 * @param crashInfo describing the context of the error
7138 * @return true if the process should exit immediately (WTF is fatal)
7139 */
7140 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007141 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007142 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007143
7144 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7145 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007146 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007147 tag, crashInfo.exceptionMessage);
7148
Dan Egnor42471dd2010-01-07 17:25:22 -08007149 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007150
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007151 if (r != null && r.pid != Process.myPid() &&
7152 Settings.Secure.getInt(mContext.getContentResolver(),
7153 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007154 crashApplication(r, crashInfo);
7155 return true;
7156 } else {
7157 return false;
7158 }
7159 }
7160
7161 /**
7162 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7163 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7164 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007165 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007166 if (app == null) {
7167 return null;
7168 }
7169
7170 synchronized (this) {
7171 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7172 final int NA = apps.size();
7173 for (int ia=0; ia<NA; ia++) {
7174 ProcessRecord p = apps.valueAt(ia);
7175 if (p.thread != null && p.thread.asBinder() == app) {
7176 return p;
7177 }
7178 }
7179 }
7180
Dianne Hackborncb44d962011-03-10 17:02:27 -08007181 Slog.w(TAG, "Can't find mystery application for " + reason
7182 + " from pid=" + Binder.getCallingPid()
7183 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007184 return null;
7185 }
7186 }
7187
7188 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007189 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7190 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007191 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007192 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007193 // Watchdog thread ends up invoking this function (with
7194 // a null ProcessRecord) to add the stack file to dropbox.
7195 // Do not acquire a lock on this (am) in such cases, as it
7196 // could cause a potential deadlock, if and when watchdog
7197 // is invoked due to unavailability of lock on am and it
7198 // would prevent watchdog from killing system_server.
7199 if (process == null) {
7200 sb.append("Process: system_server\n");
7201 return;
7202 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007203 // Note: ProcessRecord 'process' is guarded by the service
7204 // instance. (notably process.pkgList, which could otherwise change
7205 // concurrently during execution of this method)
7206 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007207 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007208 sb.append("Process: system_server\n");
7209 } else {
7210 sb.append("Process: ").append(process.processName).append("\n");
7211 }
Dan Egnora455d192010-03-12 08:52:28 -08007212 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007213 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007214 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7215 for (String pkg : process.pkgList) {
7216 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007217 try {
Dan Egnora455d192010-03-12 08:52:28 -08007218 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7219 if (pi != null) {
7220 sb.append(" v").append(pi.versionCode);
7221 if (pi.versionName != null) {
7222 sb.append(" (").append(pi.versionName).append(")");
7223 }
7224 }
7225 } catch (RemoteException e) {
7226 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007227 }
Dan Egnora455d192010-03-12 08:52:28 -08007228 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007229 }
Dan Egnora455d192010-03-12 08:52:28 -08007230 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007231 }
7232
7233 private static String processClass(ProcessRecord process) {
7234 if (process == null || process.pid == MY_PID) {
7235 return "system_server";
7236 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7237 return "system_app";
7238 } else {
7239 return "data_app";
7240 }
7241 }
7242
7243 /**
7244 * Write a description of an error (crash, WTF, ANR) to the drop box.
7245 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7246 * @param process which caused the error, null means the system server
7247 * @param activity which triggered the error, null if unknown
7248 * @param parent activity related to the error, null if unknown
7249 * @param subject line related to the error, null if absent
7250 * @param report in long form describing the error, null if absent
7251 * @param logFile to include in the report, null if none
7252 * @param crashInfo giving an application stack trace, null if absent
7253 */
7254 public void addErrorToDropBox(String eventType,
7255 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7256 final String report, final File logFile,
7257 final ApplicationErrorReport.CrashInfo crashInfo) {
7258 // NOTE -- this must never acquire the ActivityManagerService lock,
7259 // otherwise the watchdog may be prevented from resetting the system.
7260
7261 final String dropboxTag = processClass(process) + "_" + eventType;
7262 final DropBoxManager dbox = (DropBoxManager)
7263 mContext.getSystemService(Context.DROPBOX_SERVICE);
7264
7265 // Exit early if the dropbox isn't configured to accept this report type.
7266 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7267
7268 final StringBuilder sb = new StringBuilder(1024);
7269 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007270 if (activity != null) {
7271 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7272 }
7273 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7274 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7275 }
7276 if (parent != null && parent != activity) {
7277 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7278 }
7279 if (subject != null) {
7280 sb.append("Subject: ").append(subject).append("\n");
7281 }
7282 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007283 if (Debug.isDebuggerConnected()) {
7284 sb.append("Debugger: Connected\n");
7285 }
Dan Egnora455d192010-03-12 08:52:28 -08007286 sb.append("\n");
7287
7288 // Do the rest in a worker thread to avoid blocking the caller on I/O
7289 // (After this point, we shouldn't access AMS internal data structures.)
7290 Thread worker = new Thread("Error dump: " + dropboxTag) {
7291 @Override
7292 public void run() {
7293 if (report != null) {
7294 sb.append(report);
7295 }
7296 if (logFile != null) {
7297 try {
7298 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7299 } catch (IOException e) {
7300 Slog.e(TAG, "Error reading " + logFile, e);
7301 }
7302 }
7303 if (crashInfo != null && crashInfo.stackTrace != null) {
7304 sb.append(crashInfo.stackTrace);
7305 }
7306
7307 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7308 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7309 if (lines > 0) {
7310 sb.append("\n");
7311
7312 // Merge several logcat streams, and take the last N lines
7313 InputStreamReader input = null;
7314 try {
7315 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7316 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7317 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7318
7319 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7320 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7321 input = new InputStreamReader(logcat.getInputStream());
7322
7323 int num;
7324 char[] buf = new char[8192];
7325 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7326 } catch (IOException e) {
7327 Slog.e(TAG, "Error running logcat", e);
7328 } finally {
7329 if (input != null) try { input.close(); } catch (IOException e) {}
7330 }
7331 }
7332
7333 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007334 }
Dan Egnora455d192010-03-12 08:52:28 -08007335 };
7336
7337 if (process == null || process.pid == MY_PID) {
7338 worker.run(); // We may be about to die -- need to run this synchronously
7339 } else {
7340 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007341 }
7342 }
7343
7344 /**
7345 * Bring up the "unexpected error" dialog box for a crashing app.
7346 * Deal with edge cases (intercepts from instrumented applications,
7347 * ActivityController, error intent receivers, that sort of thing).
7348 * @param r the application crashing
7349 * @param crashInfo describing the failure
7350 */
7351 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007352 long timeMillis = System.currentTimeMillis();
7353 String shortMsg = crashInfo.exceptionClassName;
7354 String longMsg = crashInfo.exceptionMessage;
7355 String stackTrace = crashInfo.stackTrace;
7356 if (shortMsg != null && longMsg != null) {
7357 longMsg = shortMsg + ": " + longMsg;
7358 } else if (shortMsg != null) {
7359 longMsg = shortMsg;
7360 }
7361
Dan Egnor60d87622009-12-16 16:32:58 -08007362 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007364 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007365 try {
7366 String name = r != null ? r.processName : null;
7367 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007368 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007369 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007370 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 + " at watcher's request");
7372 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007373 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007374 }
7375 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007376 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007377 }
7378 }
7379
7380 final long origId = Binder.clearCallingIdentity();
7381
7382 // If this process is running instrumentation, finish it.
7383 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007384 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007385 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007386 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7387 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007388 Bundle info = new Bundle();
7389 info.putString("shortMsg", shortMsg);
7390 info.putString("longMsg", longMsg);
7391 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7392 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007393 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 }
7395
Dan Egnor60d87622009-12-16 16:32:58 -08007396 // If we can't identify the process or it's already exceeded its crash quota,
7397 // quit right away without showing a crash dialog.
7398 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007399 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007400 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007401 }
7402
7403 Message msg = Message.obtain();
7404 msg.what = SHOW_ERROR_MSG;
7405 HashMap data = new HashMap();
7406 data.put("result", result);
7407 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007408 msg.obj = data;
7409 mHandler.sendMessage(msg);
7410
7411 Binder.restoreCallingIdentity(origId);
7412 }
7413
7414 int res = result.get();
7415
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007416 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007417 synchronized (this) {
7418 if (r != null) {
7419 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7420 SystemClock.uptimeMillis());
7421 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007422 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007423 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007424 }
7425 }
7426
7427 if (appErrorIntent != null) {
7428 try {
7429 mContext.startActivity(appErrorIntent);
7430 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007431 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007435
7436 Intent createAppErrorIntentLocked(ProcessRecord r,
7437 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7438 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007439 if (report == null) {
7440 return null;
7441 }
7442 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7443 result.setComponent(r.errorReportReceiver);
7444 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7445 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7446 return result;
7447 }
7448
Dan Egnorb7f03672009-12-09 16:22:32 -08007449 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7450 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007451 if (r.errorReportReceiver == null) {
7452 return null;
7453 }
7454
7455 if (!r.crashing && !r.notResponding) {
7456 return null;
7457 }
7458
Dan Egnorb7f03672009-12-09 16:22:32 -08007459 ApplicationErrorReport report = new ApplicationErrorReport();
7460 report.packageName = r.info.packageName;
7461 report.installerPackageName = r.errorReportReceiver.getPackageName();
7462 report.processName = r.processName;
7463 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007464 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007465
Dan Egnorb7f03672009-12-09 16:22:32 -08007466 if (r.crashing) {
7467 report.type = ApplicationErrorReport.TYPE_CRASH;
7468 report.crashInfo = crashInfo;
7469 } else if (r.notResponding) {
7470 report.type = ApplicationErrorReport.TYPE_ANR;
7471 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007472
Dan Egnorb7f03672009-12-09 16:22:32 -08007473 report.anrInfo.activity = r.notRespondingReport.tag;
7474 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7475 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007476 }
7477
Dan Egnorb7f03672009-12-09 16:22:32 -08007478 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007479 }
7480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7482 // assume our apps are happy - lazy create the list
7483 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7484
7485 synchronized (this) {
7486
7487 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007488 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7489 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007490 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7491 // This one's in trouble, so we'll generate a report for it
7492 // crashes are higher priority (in case there's a crash *and* an anr)
7493 ActivityManager.ProcessErrorStateInfo report = null;
7494 if (app.crashing) {
7495 report = app.crashingReport;
7496 } else if (app.notResponding) {
7497 report = app.notRespondingReport;
7498 }
7499
7500 if (report != null) {
7501 if (errList == null) {
7502 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7503 }
7504 errList.add(report);
7505 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007506 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007507 " crashing = " + app.crashing +
7508 " notResponding = " + app.notResponding);
7509 }
7510 }
7511 }
7512 }
7513
7514 return errList;
7515 }
7516
7517 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7518 // Lazy instantiation of list
7519 List<ActivityManager.RunningAppProcessInfo> runList = null;
7520 synchronized (this) {
7521 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007522 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7523 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7525 // Generate process state info for running application
7526 ActivityManager.RunningAppProcessInfo currApp =
7527 new ActivityManager.RunningAppProcessInfo(app.processName,
7528 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007529 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007530 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007531 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007532 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007533 if (app.persistent) {
7534 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007537 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7539 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7540 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007541 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7542 } else if (adj >= HOME_APP_ADJ) {
7543 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7544 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 } else if (adj >= SECONDARY_SERVER_ADJ) {
7546 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007547 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007548 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007549 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7550 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007551 } else if (adj >= VISIBLE_APP_ADJ) {
7552 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7553 } else {
7554 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7555 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007556 currApp.importanceReasonCode = app.adjTypeCode;
7557 if (app.adjSource instanceof ProcessRecord) {
7558 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007559 } else if (app.adjSource instanceof ActivityRecord) {
7560 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007561 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7562 }
7563 if (app.adjTarget instanceof ComponentName) {
7564 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7565 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007566 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007567 // + " lru=" + currApp.lru);
7568 if (runList == null) {
7569 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7570 }
7571 runList.add(currApp);
7572 }
7573 }
7574 }
7575 return runList;
7576 }
7577
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007578 public List<ApplicationInfo> getRunningExternalApplications() {
7579 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7580 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7581 if (runningApps != null && runningApps.size() > 0) {
7582 Set<String> extList = new HashSet<String>();
7583 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7584 if (app.pkgList != null) {
7585 for (String pkg : app.pkgList) {
7586 extList.add(pkg);
7587 }
7588 }
7589 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007590 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007591 for (String pkg : extList) {
7592 try {
7593 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7594 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7595 retList.add(info);
7596 }
7597 } catch (RemoteException e) {
7598 }
7599 }
7600 }
7601 return retList;
7602 }
7603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007604 @Override
7605 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007606 if (checkCallingPermission(android.Manifest.permission.DUMP)
7607 != PackageManager.PERMISSION_GRANTED) {
7608 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7609 + Binder.getCallingPid()
7610 + ", uid=" + Binder.getCallingUid()
7611 + " without permission "
7612 + android.Manifest.permission.DUMP);
7613 return;
7614 }
7615
7616 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007617 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007618
7619 int opti = 0;
7620 while (opti < args.length) {
7621 String opt = args[opti];
7622 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7623 break;
7624 }
7625 opti++;
7626 if ("-a".equals(opt)) {
7627 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007628 } else if ("-c".equals(opt)) {
7629 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007630 } else if ("-h".equals(opt)) {
7631 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007632 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007633 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007634 pw.println(" a[ctivities]: activity stack state");
7635 pw.println(" b[roadcasts]: broadcast state");
7636 pw.println(" i[ntents]: pending intent state");
7637 pw.println(" p[rocesses]: process state");
7638 pw.println(" o[om]: out of memory management");
7639 pw.println(" prov[iders]: content provider state");
7640 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007641 pw.println(" service [COMP_SPEC]: service client-side state");
7642 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7643 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7644 pw.println(" a partial substring in a component name, an");
7645 pw.println(" ActivityRecord hex object identifier, or");
7646 pw.println(" \"all\" for all objects");
7647 pw.println(" -a: include all available server state.");
7648 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007649 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007650 } else {
7651 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007652 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007653 }
7654
7655 // Is the caller requesting to dump a particular piece of data?
7656 if (opti < args.length) {
7657 String cmd = args[opti];
7658 opti++;
7659 if ("activities".equals(cmd) || "a".equals(cmd)) {
7660 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007661 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007663 return;
7664 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7665 synchronized (this) {
7666 dumpBroadcastsLocked(fd, pw, args, opti, true);
7667 }
7668 return;
7669 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7670 synchronized (this) {
7671 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7672 }
7673 return;
7674 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7675 synchronized (this) {
7676 dumpProcessesLocked(fd, pw, args, opti, true);
7677 }
7678 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007679 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7680 synchronized (this) {
7681 dumpOomLocked(fd, pw, args, opti, true);
7682 }
7683 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007684 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7685 synchronized (this) {
7686 dumpProvidersLocked(fd, pw, args, opti, true);
7687 }
7688 return;
7689 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007690 String[] newArgs;
7691 String name;
7692 if (opti >= args.length) {
7693 name = null;
7694 newArgs = EMPTY_STRING_ARRAY;
7695 } else {
7696 name = args[opti];
7697 opti++;
7698 newArgs = new String[args.length - opti];
7699 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7700 }
7701 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7702 pw.println("No services match: " + name);
7703 pw.println("Use -h for help.");
7704 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007705 return;
7706 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7707 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007708 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007709 }
7710 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007711 } else {
7712 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007713 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7714 pw.println("Bad activity command, or no activities match: " + cmd);
7715 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007716 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007717 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007719 }
7720
7721 // No piece of data specified, dump everything.
7722 synchronized (this) {
7723 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007724 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007725 if (needSep) {
7726 pw.println(" ");
7727 }
7728 if (dumpAll) {
7729 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007730 }
7731 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7732 if (needSep) {
7733 pw.println(" ");
7734 }
7735 if (dumpAll) {
7736 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007737 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007738 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007739 if (needSep) {
7740 pw.println(" ");
7741 }
7742 if (dumpAll) {
7743 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007744 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007745 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007746 if (needSep) {
7747 pw.println(" ");
7748 }
7749 if (dumpAll) {
7750 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007751 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007752 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007753 if (needSep) {
7754 pw.println(" ");
7755 }
7756 if (dumpAll) {
7757 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007758 }
7759 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7760 }
7761 }
7762
7763 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007764 int opti, boolean dumpAll, boolean dumpClient) {
7765 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7766 pw.println(" Main stack:");
7767 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007768 pw.println(" ");
7769 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007770 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007771 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007773 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007774 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7775 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007776 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007777 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007778 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007779 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007780 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7781 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007782 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007783 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7784 pw.println(" ");
7785 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007786 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7787 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007788 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007789 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007790 pw.println(" ");
7791 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007792 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7793 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007795
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007796 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007797 if (mMainStack.mPausingActivity != null) {
7798 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7799 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007800 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007801 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007802 if (dumpAll) {
7803 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7804 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007806
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007807 if (mRecentTasks.size() > 0) {
7808 pw.println();
7809 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007810
7811 final int N = mRecentTasks.size();
7812 for (int i=0; i<N; i++) {
7813 TaskRecord tr = mRecentTasks.get(i);
7814 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7815 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007816 if (dumpAll) {
7817 mRecentTasks.get(i).dump(pw, " ");
7818 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007819 }
7820 }
7821
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007822 if (dumpAll) {
7823 pw.println(" ");
7824 pw.println(" mCurTask: " + mCurTask);
7825 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007826
7827 return true;
7828 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007829
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007830 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7831 int opti, boolean dumpAll) {
7832 boolean needSep = false;
7833 int numPers = 0;
7834
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007835 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7836
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007837 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007838 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7839 final int NA = procs.size();
7840 for (int ia=0; ia<NA; ia++) {
7841 if (!needSep) {
7842 pw.println(" All known processes:");
7843 needSep = true;
7844 }
7845 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007846 pw.print(r.persistent ? " *PERS*" : " *APP*");
7847 pw.print(" UID "); pw.print(procs.keyAt(ia));
7848 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007849 r.dump(pw, " ");
7850 if (r.persistent) {
7851 numPers++;
7852 }
7853 }
7854 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007855 }
7856
7857 if (mLruProcesses.size() > 0) {
7858 if (needSep) pw.println(" ");
7859 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007860 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007861 dumpProcessOomList(pw, this, mLruProcesses, " ",
7862 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007863 needSep = true;
7864 }
7865
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007866 if (dumpAll) {
7867 synchronized (mPidsSelfLocked) {
7868 if (mPidsSelfLocked.size() > 0) {
7869 if (needSep) pw.println(" ");
7870 needSep = true;
7871 pw.println(" PID mappings:");
7872 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7873 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7874 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007876 }
7877 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007878 }
7879
7880 if (mForegroundProcesses.size() > 0) {
7881 if (needSep) pw.println(" ");
7882 needSep = true;
7883 pw.println(" Foreground Processes:");
7884 for (int i=0; i<mForegroundProcesses.size(); i++) {
7885 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7886 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007887 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007888 }
7889
7890 if (mPersistentStartingProcesses.size() > 0) {
7891 if (needSep) pw.println(" ");
7892 needSep = true;
7893 pw.println(" Persisent processes that are starting:");
7894 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007895 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007897
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007898 if (mStartingProcesses.size() > 0) {
7899 if (needSep) pw.println(" ");
7900 needSep = true;
7901 pw.println(" Processes that are starting:");
7902 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007903 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007906 if (mRemovedProcesses.size() > 0) {
7907 if (needSep) pw.println(" ");
7908 needSep = true;
7909 pw.println(" Processes that are being removed:");
7910 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007911 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007912 }
7913
7914 if (mProcessesOnHold.size() > 0) {
7915 if (needSep) pw.println(" ");
7916 needSep = true;
7917 pw.println(" Processes that are on old until the system is ready:");
7918 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007919 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007921
Dianne Hackborn287952c2010-09-22 22:34:31 -07007922 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007923
7924 if (mProcessCrashTimes.getMap().size() > 0) {
7925 if (needSep) pw.println(" ");
7926 needSep = true;
7927 pw.println(" Time since processes crashed:");
7928 long now = SystemClock.uptimeMillis();
7929 for (Map.Entry<String, SparseArray<Long>> procs
7930 : mProcessCrashTimes.getMap().entrySet()) {
7931 SparseArray<Long> uids = procs.getValue();
7932 final int N = uids.size();
7933 for (int i=0; i<N; i++) {
7934 pw.print(" Process "); pw.print(procs.getKey());
7935 pw.print(" uid "); pw.print(uids.keyAt(i));
7936 pw.print(": last crashed ");
7937 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007938 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007939 }
7940 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007941 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007942
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007943 if (mBadProcesses.getMap().size() > 0) {
7944 if (needSep) pw.println(" ");
7945 needSep = true;
7946 pw.println(" Bad processes:");
7947 for (Map.Entry<String, SparseArray<Long>> procs
7948 : mBadProcesses.getMap().entrySet()) {
7949 SparseArray<Long> uids = procs.getValue();
7950 final int N = uids.size();
7951 for (int i=0; i<N; i++) {
7952 pw.print(" Bad process "); pw.print(procs.getKey());
7953 pw.print(" uid "); pw.print(uids.keyAt(i));
7954 pw.print(": crashed at time ");
7955 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956 }
7957 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007959
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007960 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007961 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007962 if (mHeavyWeightProcess != null) {
7963 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7964 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007965 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007966 if (dumpAll) {
7967 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007968 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007969 pw.print(" mScreenCompatPackages=");
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007970 pw.println(mCompatModePackages.getPackages());
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007971 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007972 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007973 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7974 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7975 || mOrigWaitForDebugger) {
7976 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7977 + " mDebugTransient=" + mDebugTransient
7978 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7979 }
7980 if (mAlwaysFinishActivities || mController != null) {
7981 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7982 + " mController=" + mController);
7983 }
7984 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007987 + " mProcessesReady=" + mProcessesReady
7988 + " mSystemReady=" + mSystemReady);
7989 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007990 + " mBooted=" + mBooted
7991 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007992 pw.print(" mLastPowerCheckRealtime=");
7993 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7994 pw.println("");
7995 pw.print(" mLastPowerCheckUptime=");
7996 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7997 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007998 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7999 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008000 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008001 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008002
8003 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008004 }
8005
Dianne Hackborn287952c2010-09-22 22:34:31 -07008006 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8007 int opti, boolean needSep, boolean dumpAll) {
8008 if (mProcessesToGc.size() > 0) {
8009 if (needSep) pw.println(" ");
8010 needSep = true;
8011 pw.println(" Processes that are waiting to GC:");
8012 long now = SystemClock.uptimeMillis();
8013 for (int i=0; i<mProcessesToGc.size(); i++) {
8014 ProcessRecord proc = mProcessesToGc.get(i);
8015 pw.print(" Process "); pw.println(proc);
8016 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8017 pw.print(", last gced=");
8018 pw.print(now-proc.lastRequestedGc);
8019 pw.print(" ms ago, last lowMem=");
8020 pw.print(now-proc.lastLowMemory);
8021 pw.println(" ms ago");
8022
8023 }
8024 }
8025 return needSep;
8026 }
8027
8028 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8029 int opti, boolean dumpAll) {
8030 boolean needSep = false;
8031
8032 if (mLruProcesses.size() > 0) {
8033 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8034
8035 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8036 @Override
8037 public int compare(ProcessRecord object1, ProcessRecord object2) {
8038 if (object1.setAdj != object2.setAdj) {
8039 return object1.setAdj > object2.setAdj ? -1 : 1;
8040 }
8041 if (object1.setSchedGroup != object2.setSchedGroup) {
8042 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8043 }
8044 if (object1.keeping != object2.keeping) {
8045 return object1.keeping ? -1 : 1;
8046 }
8047 if (object1.pid != object2.pid) {
8048 return object1.pid > object2.pid ? -1 : 1;
8049 }
8050 return 0;
8051 }
8052 };
8053
8054 Collections.sort(procs, comparator);
8055
8056 if (needSep) pw.println(" ");
8057 needSep = true;
8058 pw.println(" Process OOM control:");
8059 dumpProcessOomList(pw, this, procs, " ",
8060 "Proc", "PERS", true);
8061 needSep = true;
8062 }
8063
8064 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8065
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008066 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008067 pw.println(" mHomeProcess: " + mHomeProcess);
8068 if (mHeavyWeightProcess != null) {
8069 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8070 }
8071
8072 return true;
8073 }
8074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008075 /**
8076 * There are three ways to call this:
8077 * - no service specified: dump all the services
8078 * - a flattened component name that matched an existing service was specified as the
8079 * first arg: dump that one service
8080 * - the first arg isn't the flattened component name of an existing service:
8081 * dump all services whose component contains the first arg as a substring
8082 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008083 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8084 int opti, boolean dumpAll) {
8085 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008086
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008087 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008088 synchronized (this) {
8089 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008090 services.add(r1);
8091 }
8092 }
8093 } else {
8094 ComponentName componentName = name != null
8095 ? ComponentName.unflattenFromString(name) : null;
8096 int objectId = 0;
8097 if (componentName == null) {
8098 // Not a '/' separated full component name; maybe an object ID?
8099 try {
8100 objectId = Integer.parseInt(name, 16);
8101 name = null;
8102 componentName = null;
8103 } catch (RuntimeException e) {
8104 }
8105 }
8106
8107 synchronized (this) {
8108 for (ServiceRecord r1 : mServices.values()) {
8109 if (componentName != null) {
8110 if (r1.name.equals(componentName)) {
8111 services.add(r1);
8112 }
8113 } else if (name != null) {
8114 if (r1.name.flattenToString().contains(name)) {
8115 services.add(r1);
8116 }
8117 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008118 services.add(r1);
8119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008120 }
8121 }
8122 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008123
8124 if (services.size() <= 0) {
8125 return false;
8126 }
8127
8128 boolean needSep = false;
8129 for (int i=0; i<services.size(); i++) {
8130 if (needSep) {
8131 pw.println();
8132 }
8133 needSep = true;
8134 dumpService("", fd, pw, services.get(i), args, dumpAll);
8135 }
8136 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 }
8138
8139 /**
8140 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8141 * there is a thread associated with the service.
8142 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008143 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8144 final ServiceRecord r, String[] args, boolean dumpAll) {
8145 String innerPrefix = prefix + " ";
8146 synchronized (this) {
8147 pw.print(prefix); pw.print("SERVICE ");
8148 pw.print(r.shortName); pw.print(" ");
8149 pw.print(Integer.toHexString(System.identityHashCode(r)));
8150 pw.print(" pid=");
8151 if (r.app != null) pw.println(r.app.pid);
8152 else pw.println("(not running)");
8153 if (dumpAll) {
8154 r.dump(pw, innerPrefix);
8155 }
8156 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008157 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008158 pw.print(prefix); pw.println(" Client:");
8159 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008161 TransferPipe tp = new TransferPipe();
8162 try {
8163 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8164 tp.setBufferPrefix(prefix + " ");
8165 tp.go(fd);
8166 } finally {
8167 tp.kill();
8168 }
8169 } catch (IOException e) {
8170 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008171 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008172 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008173 }
8174 }
8175 }
8176
Dianne Hackborn625ac272010-09-17 18:29:22 -07008177 /**
8178 * There are three things that cmd can be:
8179 * - a flattened component name that matched an existing activity
8180 * - the cmd arg isn't the flattened component name of an existing activity:
8181 * dump all activity whose component contains the cmd as a substring
8182 * - A hex number of the ActivityRecord object instance.
8183 */
8184 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8185 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008186 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008187
8188 if ("all".equals(name)) {
8189 synchronized (this) {
8190 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008191 activities.add(r1);
8192 }
8193 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008194 } else {
8195 ComponentName componentName = ComponentName.unflattenFromString(name);
8196 int objectId = 0;
8197 if (componentName == null) {
8198 // Not a '/' separated full component name; maybe an object ID?
8199 try {
8200 objectId = Integer.parseInt(name, 16);
8201 name = null;
8202 componentName = null;
8203 } catch (RuntimeException e) {
8204 }
8205 }
8206
8207 synchronized (this) {
8208 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8209 if (componentName != null) {
8210 if (r1.intent.getComponent().equals(componentName)) {
8211 activities.add(r1);
8212 }
8213 } else if (name != null) {
8214 if (r1.intent.getComponent().flattenToString().contains(name)) {
8215 activities.add(r1);
8216 }
8217 } else if (System.identityHashCode(r1) == objectId) {
8218 activities.add(r1);
8219 }
8220 }
8221 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008222 }
8223
8224 if (activities.size() <= 0) {
8225 return false;
8226 }
8227
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008228 String[] newArgs = new String[args.length - opti];
8229 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8230
Dianne Hackborn30d71892010-12-11 10:37:55 -08008231 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008232 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008233 for (int i=activities.size()-1; i>=0; i--) {
8234 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008235 if (needSep) {
8236 pw.println();
8237 }
8238 needSep = true;
8239 synchronized (this) {
8240 if (lastTask != r.task) {
8241 lastTask = r.task;
8242 pw.print("TASK "); pw.print(lastTask.affinity);
8243 pw.print(" id="); pw.println(lastTask.taskId);
8244 if (dumpAll) {
8245 lastTask.dump(pw, " ");
8246 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008247 }
8248 }
8249 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008250 }
8251 return true;
8252 }
8253
8254 /**
8255 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8256 * there is a thread associated with the activity.
8257 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008258 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008259 final ActivityRecord r, String[] args, boolean dumpAll) {
8260 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008261 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008262 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8263 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8264 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008265 if (r.app != null) pw.println(r.app.pid);
8266 else pw.println("(not running)");
8267 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008268 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008269 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008270 }
8271 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008272 // flush anything that is already in the PrintWriter since the thread is going
8273 // to write to the file descriptor directly
8274 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008275 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008276 TransferPipe tp = new TransferPipe();
8277 try {
8278 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8279 innerPrefix, args);
8280 tp.go(fd);
8281 } finally {
8282 tp.kill();
8283 }
8284 } catch (IOException e) {
8285 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008286 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008287 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008288 }
8289 }
8290 }
8291
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008292 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8293 int opti, boolean dumpAll) {
8294 boolean needSep = false;
8295
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008296 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008297 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008299 pw.println(" Registered Receivers:");
8300 Iterator it = mRegisteredReceivers.values().iterator();
8301 while (it.hasNext()) {
8302 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008303 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 r.dump(pw, " ");
8305 }
8306 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008307
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008308 pw.println();
8309 pw.println(" Receiver Resolver Table:");
8310 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008311 needSep = true;
8312 }
8313
8314 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8315 || mPendingBroadcast != null) {
8316 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008317 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008318 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008319 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008320 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8321 pw.println(" Broadcast #" + i + ":");
8322 mParallelBroadcasts.get(i).dump(pw, " ");
8323 }
8324 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008325 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008326 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008327 }
8328 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8329 pw.println(" Serialized Broadcast #" + i + ":");
8330 mOrderedBroadcasts.get(i).dump(pw, " ");
8331 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008332 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008333 pw.println(" Pending broadcast:");
8334 if (mPendingBroadcast != null) {
8335 mPendingBroadcast.dump(pw, " ");
8336 } else {
8337 pw.println(" (null)");
8338 }
8339 needSep = true;
8340 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008341
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008342 if (needSep) {
8343 pw.println();
8344 }
8345 pw.println(" Historical broadcasts:");
8346 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8347 BroadcastRecord r = mBroadcastHistory[i];
8348 if (r == null) {
8349 break;
8350 }
8351 if (dumpAll) {
8352 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8353 r.dump(pw, " ");
8354 } else {
8355 if (i >= 50) {
8356 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008357 break;
8358 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008359 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008360 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008361 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008362 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008363
8364 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008365 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008366 pw.println(" Sticky broadcasts:");
8367 StringBuilder sb = new StringBuilder(128);
8368 for (Map.Entry<String, ArrayList<Intent>> ent
8369 : mStickyBroadcasts.entrySet()) {
8370 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008371 if (dumpAll) {
8372 pw.println(":");
8373 ArrayList<Intent> intents = ent.getValue();
8374 final int N = intents.size();
8375 for (int i=0; i<N; i++) {
8376 sb.setLength(0);
8377 sb.append(" Intent: ");
8378 intents.get(i).toShortString(sb, true, false);
8379 pw.println(sb.toString());
8380 Bundle bundle = intents.get(i).getExtras();
8381 if (bundle != null) {
8382 pw.print(" ");
8383 pw.println(bundle.toString());
8384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008385 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008386 } else {
8387 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 }
8389 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008390 needSep = true;
8391 }
8392
8393 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008394 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008395 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008396 pw.println(" mHandler:");
8397 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008398 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008399 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008400
8401 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 }
8403
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008404 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008405 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008406 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008408 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8409 if (mServices.size() > 0) {
8410 pw.println(" Active services:");
8411 long nowReal = SystemClock.elapsedRealtime();
8412 Iterator<ServiceRecord> it = mServices.values().iterator();
8413 needSep = false;
8414 while (it.hasNext()) {
8415 ServiceRecord r = it.next();
8416 if (needSep) {
8417 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008419 pw.print(" * "); pw.println(r);
8420 if (dumpAll) {
8421 r.dump(pw, " ");
8422 needSep = true;
8423 } else {
8424 pw.print(" app="); pw.println(r.app);
8425 pw.print(" created=");
8426 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8427 pw.print(" started="); pw.print(r.startRequested);
8428 pw.print(" connections="); pw.println(r.connections.size());
8429 }
8430 if (dumpClient && r.app != null && r.app.thread != null) {
8431 pw.println(" Client:");
8432 pw.flush();
8433 try {
8434 TransferPipe tp = new TransferPipe();
8435 try {
8436 r.app.thread.dumpService(
8437 tp.getWriteFd().getFileDescriptor(), r, args);
8438 tp.setBufferPrefix(" ");
8439 // Short timeout, since blocking here can
8440 // deadlock with the application.
8441 tp.go(fd, 2000);
8442 } finally {
8443 tp.kill();
8444 }
8445 } catch (IOException e) {
8446 pw.println(" Failure while dumping the service: " + e);
8447 } catch (RemoteException e) {
8448 pw.println(" Got a RemoteException while dumping the service");
8449 }
8450 needSep = true;
8451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008452 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008453 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008456 if (mPendingServices.size() > 0) {
8457 if (needSep) pw.println(" ");
8458 pw.println(" Pending services:");
8459 for (int i=0; i<mPendingServices.size(); i++) {
8460 ServiceRecord r = mPendingServices.get(i);
8461 pw.print(" * Pending "); pw.println(r);
8462 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008463 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008464 needSep = true;
8465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008467 if (mRestartingServices.size() > 0) {
8468 if (needSep) pw.println(" ");
8469 pw.println(" Restarting services:");
8470 for (int i=0; i<mRestartingServices.size(); i++) {
8471 ServiceRecord r = mRestartingServices.get(i);
8472 pw.print(" * Restarting "); pw.println(r);
8473 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008475 needSep = true;
8476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008477
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008478 if (mStoppingServices.size() > 0) {
8479 if (needSep) pw.println(" ");
8480 pw.println(" Stopping services:");
8481 for (int i=0; i<mStoppingServices.size(); i++) {
8482 ServiceRecord r = mStoppingServices.get(i);
8483 pw.print(" * Stopping "); pw.println(r);
8484 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008486 needSep = true;
8487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008488
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008489 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008490 if (mServiceConnections.size() > 0) {
8491 if (needSep) pw.println(" ");
8492 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008493 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008494 = mServiceConnections.values().iterator();
8495 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008496 ArrayList<ConnectionRecord> r = it.next();
8497 for (int i=0; i<r.size(); i++) {
8498 pw.print(" * "); pw.println(r.get(i));
8499 r.get(i).dump(pw, " ");
8500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008502 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008503 }
8504 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008505
8506 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008507 }
8508
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008509 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8510 int opti, boolean dumpAll) {
8511 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008512
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008513 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8514 if (mProvidersByClass.size() > 0) {
8515 if (needSep) pw.println(" ");
8516 pw.println(" Published content providers (by class):");
8517 Iterator<Map.Entry<String, ContentProviderRecord>> it
8518 = mProvidersByClass.entrySet().iterator();
8519 while (it.hasNext()) {
8520 Map.Entry<String, ContentProviderRecord> e = it.next();
8521 ContentProviderRecord r = e.getValue();
8522 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008523 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008525 } else {
8526 pw.print(" * "); pw.print(r.name.toShortString());
8527 if (r.app != null) {
8528 pw.println(":");
8529 pw.print(" "); pw.println(r.app);
8530 } else {
8531 pw.println();
8532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008534 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008535 needSep = true;
8536 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008537
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008538 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008539 if (mProvidersByName.size() > 0) {
8540 pw.println(" ");
8541 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008542 Iterator<Map.Entry<String, ContentProviderRecord>> it
8543 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008544 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008545 Map.Entry<String, ContentProviderRecord> e = it.next();
8546 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008547 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8548 pw.println(r);
8549 }
8550 needSep = true;
8551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008552 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008553
8554 if (mLaunchingProviders.size() > 0) {
8555 if (needSep) pw.println(" ");
8556 pw.println(" Launching content providers:");
8557 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8558 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8559 pw.println(mLaunchingProviders.get(i));
8560 }
8561 needSep = true;
8562 }
8563
8564 if (mGrantedUriPermissions.size() > 0) {
8565 pw.println();
8566 pw.println("Granted Uri Permissions:");
8567 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8568 int uid = mGrantedUriPermissions.keyAt(i);
8569 HashMap<Uri, UriPermission> perms
8570 = mGrantedUriPermissions.valueAt(i);
8571 pw.print(" * UID "); pw.print(uid);
8572 pw.println(" holds:");
8573 for (UriPermission perm : perms.values()) {
8574 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008575 if (dumpAll) {
8576 perm.dump(pw, " ");
8577 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008578 }
8579 }
8580 needSep = true;
8581 }
8582
8583 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008584 }
8585
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008586 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8587 int opti, boolean dumpAll) {
8588 boolean needSep = false;
8589
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008590 if (this.mIntentSenderRecords.size() > 0) {
8591 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8592 Iterator<WeakReference<PendingIntentRecord>> it
8593 = mIntentSenderRecords.values().iterator();
8594 while (it.hasNext()) {
8595 WeakReference<PendingIntentRecord> ref = it.next();
8596 PendingIntentRecord rec = ref != null ? ref.get(): null;
8597 needSep = true;
8598 if (rec != null) {
8599 pw.print(" * "); pw.println(rec);
8600 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008602 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008603 } else {
8604 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008605 }
8606 }
8607 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008608
8609 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008610 }
8611
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008612 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8613 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008614 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008615 boolean needNL = false;
8616 final String innerPrefix = prefix + " ";
8617 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008619 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008620 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008621 if (needNL) {
8622 pw.println(" ");
8623 needNL = false;
8624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008625 if (lastTask != r.task) {
8626 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008627 pw.print(prefix);
8628 pw.print(full ? "* " : " ");
8629 pw.println(lastTask);
8630 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008631 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008632 } else if (complete) {
8633 // Complete + brief == give a summary. Isn't that obvious?!?
8634 if (lastTask.intent != null) {
8635 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8636 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008639 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8640 pw.print(" #"); pw.print(i); pw.print(": ");
8641 pw.println(r);
8642 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008643 r.dump(pw, innerPrefix);
8644 } else if (complete) {
8645 // Complete + brief == give a summary. Isn't that obvious?!?
8646 pw.print(innerPrefix); pw.println(r.intent);
8647 if (r.app != null) {
8648 pw.print(innerPrefix); pw.println(r.app);
8649 }
8650 }
8651 if (client && r.app != null && r.app.thread != null) {
8652 // flush anything that is already in the PrintWriter since the thread is going
8653 // to write to the file descriptor directly
8654 pw.flush();
8655 try {
8656 TransferPipe tp = new TransferPipe();
8657 try {
8658 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8659 innerPrefix, args);
8660 // Short timeout, since blocking here can
8661 // deadlock with the application.
8662 tp.go(fd, 2000);
8663 } finally {
8664 tp.kill();
8665 }
8666 } catch (IOException e) {
8667 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8668 } catch (RemoteException e) {
8669 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8670 }
8671 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008672 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008673 }
8674 }
8675
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008676 private static String buildOomTag(String prefix, String space, int val, int base) {
8677 if (val == base) {
8678 if (space == null) return prefix;
8679 return prefix + " ";
8680 }
8681 return prefix + "+" + Integer.toString(val-base);
8682 }
8683
8684 private static final int dumpProcessList(PrintWriter pw,
8685 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008686 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008687 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008688 final int N = list.size()-1;
8689 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008690 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008691 pw.println(String.format("%s%s #%2d: %s",
8692 prefix, (r.persistent ? persistentLabel : normalLabel),
8693 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008694 if (r.persistent) {
8695 numPers++;
8696 }
8697 }
8698 return numPers;
8699 }
8700
Dianne Hackborn287952c2010-09-22 22:34:31 -07008701 private static final void dumpProcessOomList(PrintWriter pw,
8702 ActivityManagerService service, List<ProcessRecord> list,
8703 String prefix, String normalLabel, String persistentLabel,
8704 boolean inclDetails) {
8705
8706 final long curRealtime = SystemClock.elapsedRealtime();
8707 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8708 final long curUptime = SystemClock.uptimeMillis();
8709 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8710
8711 final int N = list.size()-1;
8712 for (int i=N; i>=0; i--) {
8713 ProcessRecord r = list.get(i);
8714 String oomAdj;
8715 if (r.setAdj >= EMPTY_APP_ADJ) {
8716 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8717 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8718 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8719 } else if (r.setAdj >= HOME_APP_ADJ) {
8720 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8721 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8722 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8723 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8724 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8725 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8726 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8727 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8728 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8729 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8730 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8731 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8732 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8733 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8734 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8735 } else if (r.setAdj >= SYSTEM_ADJ) {
8736 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8737 } else {
8738 oomAdj = Integer.toString(r.setAdj);
8739 }
8740 String schedGroup;
8741 switch (r.setSchedGroup) {
8742 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8743 schedGroup = "B";
8744 break;
8745 case Process.THREAD_GROUP_DEFAULT:
8746 schedGroup = "F";
8747 break;
8748 default:
8749 schedGroup = Integer.toString(r.setSchedGroup);
8750 break;
8751 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008752 String foreground;
8753 if (r.foregroundActivities) {
8754 foreground = "A";
8755 } else if (r.foregroundServices) {
8756 foreground = "S";
8757 } else {
8758 foreground = " ";
8759 }
8760 pw.println(String.format("%s%s #%2d: adj=%s/%s%s %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008761 prefix, (r.persistent ? persistentLabel : normalLabel),
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008762 N-i, oomAdj, schedGroup, foreground, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008763 if (r.adjSource != null || r.adjTarget != null) {
8764 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008765 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008766 if (r.adjTarget instanceof ComponentName) {
8767 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8768 } else if (r.adjTarget != null) {
8769 pw.print(r.adjTarget.toString());
8770 } else {
8771 pw.print("{null}");
8772 }
8773 pw.print("<=");
8774 if (r.adjSource instanceof ProcessRecord) {
8775 pw.print("Proc{");
8776 pw.print(((ProcessRecord)r.adjSource).toShortString());
8777 pw.println("}");
8778 } else if (r.adjSource != null) {
8779 pw.println(r.adjSource.toString());
8780 } else {
8781 pw.println("{null}");
8782 }
8783 }
8784 if (inclDetails) {
8785 pw.print(prefix);
8786 pw.print(" ");
8787 pw.print("oom: max="); pw.print(r.maxAdj);
8788 pw.print(" hidden="); pw.print(r.hiddenAdj);
8789 pw.print(" curRaw="); pw.print(r.curRawAdj);
8790 pw.print(" setRaw="); pw.print(r.setRawAdj);
8791 pw.print(" cur="); pw.print(r.curAdj);
8792 pw.print(" set="); pw.println(r.setAdj);
8793 pw.print(prefix);
8794 pw.print(" ");
8795 pw.print("keeping="); pw.print(r.keeping);
8796 pw.print(" hidden="); pw.print(r.hidden);
8797 pw.print(" empty="); pw.println(r.empty);
8798
8799 if (!r.keeping) {
8800 if (r.lastWakeTime != 0) {
8801 long wtime;
8802 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8803 synchronized (stats) {
8804 wtime = stats.getProcessWakeTime(r.info.uid,
8805 r.pid, curRealtime);
8806 }
8807 long timeUsed = wtime - r.lastWakeTime;
8808 pw.print(prefix);
8809 pw.print(" ");
8810 pw.print("keep awake over ");
8811 TimeUtils.formatDuration(realtimeSince, pw);
8812 pw.print(" used ");
8813 TimeUtils.formatDuration(timeUsed, pw);
8814 pw.print(" (");
8815 pw.print((timeUsed*100)/realtimeSince);
8816 pw.println("%)");
8817 }
8818 if (r.lastCpuTime != 0) {
8819 long timeUsed = r.curCpuTime - r.lastCpuTime;
8820 pw.print(prefix);
8821 pw.print(" ");
8822 pw.print("run cpu over ");
8823 TimeUtils.formatDuration(uptimeSince, pw);
8824 pw.print(" used ");
8825 TimeUtils.formatDuration(timeUsed, pw);
8826 pw.print(" (");
8827 pw.print((timeUsed*100)/uptimeSince);
8828 pw.println("%)");
8829 }
8830 }
8831 }
8832 }
8833 }
8834
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008835 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8836 ArrayList<ProcessRecord> procs;
8837 synchronized (this) {
8838 if (args != null && args.length > 0
8839 && args[0].charAt(0) != '-') {
8840 procs = new ArrayList<ProcessRecord>();
8841 int pid = -1;
8842 try {
8843 pid = Integer.parseInt(args[0]);
8844 } catch (NumberFormatException e) {
8845
8846 }
8847 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8848 ProcessRecord proc = mLruProcesses.get(i);
8849 if (proc.pid == pid) {
8850 procs.add(proc);
8851 } else if (proc.processName.equals(args[0])) {
8852 procs.add(proc);
8853 }
8854 }
8855 if (procs.size() <= 0) {
8856 pw.println("No process found for: " + args[0]);
8857 return null;
8858 }
8859 } else {
8860 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8861 }
8862 }
8863 return procs;
8864 }
8865
8866 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8867 PrintWriter pw, String[] args) {
8868 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8869 if (procs == null) {
8870 return;
8871 }
8872
8873 long uptime = SystemClock.uptimeMillis();
8874 long realtime = SystemClock.elapsedRealtime();
8875 pw.println("Applications Graphics Acceleration Info:");
8876 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8877
8878 String callArgs[] = {"graphics"};
8879 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8880 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008881 if (r.thread != null) {
8882 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8883 pw.flush();
8884 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008885 TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
8886 } catch (IOException e) {
8887 pw.println("Failure: " + e);
8888 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008889 } catch (RemoteException e) {
8890 pw.println("Got RemoteException!");
8891 pw.flush();
8892 }
8893 }
8894 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008895 }
8896
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008897 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8898 PrintWriter pw, String prefix, String[] args) {
8899 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8900 if (procs == null) {
8901 return;
8902 }
8903
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008904 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008905 long uptime = SystemClock.uptimeMillis();
8906 long realtime = SystemClock.elapsedRealtime();
8907
8908 if (isCheckinRequest) {
8909 // short checkin version
8910 pw.println(uptime + "," + realtime);
8911 pw.flush();
8912 } else {
8913 pw.println("Applications Memory Usage (kB):");
8914 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8915 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008916 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8917 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008918 if (r.thread != null) {
8919 if (!isCheckinRequest) {
8920 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8921 pw.flush();
8922 }
8923 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008924 TransferPipe.goDump(r.thread.asBinder(), fd, args);
8925 } catch (IOException e) {
8926 pw.println("Failure: " + e);
8927 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008928 } catch (RemoteException e) {
8929 if (!isCheckinRequest) {
8930 pw.println("Got RemoteException!");
8931 pw.flush();
8932 }
8933 }
8934 }
8935 }
8936 }
8937
8938 /**
8939 * Searches array of arguments for the specified string
8940 * @param args array of argument strings
8941 * @param value value to search for
8942 * @return true if the value is contained in the array
8943 */
8944 private static boolean scanArgs(String[] args, String value) {
8945 if (args != null) {
8946 for (String arg : args) {
8947 if (value.equals(arg)) {
8948 return true;
8949 }
8950 }
8951 }
8952 return false;
8953 }
8954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 private final void killServicesLocked(ProcessRecord app,
8956 boolean allowRestart) {
8957 // Report disconnected services.
8958 if (false) {
8959 // XXX we are letting the client link to the service for
8960 // death notifications.
8961 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008962 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008963 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008964 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008965 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008966 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008967 = r.connections.values().iterator();
8968 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008969 ArrayList<ConnectionRecord> cl = jt.next();
8970 for (int i=0; i<cl.size(); i++) {
8971 ConnectionRecord c = cl.get(i);
8972 if (c.binding.client != app) {
8973 try {
8974 //c.conn.connected(r.className, null);
8975 } catch (Exception e) {
8976 // todo: this should be asynchronous!
8977 Slog.w(TAG, "Exception thrown disconnected servce "
8978 + r.shortName
8979 + " from app " + app.processName, e);
8980 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008981 }
8982 }
8983 }
8984 }
8985 }
8986 }
8987 }
8988
8989 // Clean up any connections this application has to other services.
8990 if (app.connections.size() > 0) {
8991 Iterator<ConnectionRecord> it = app.connections.iterator();
8992 while (it.hasNext()) {
8993 ConnectionRecord r = it.next();
8994 removeConnectionLocked(r, app, null);
8995 }
8996 }
8997 app.connections.clear();
8998
8999 if (app.services.size() != 0) {
9000 // Any services running in the application need to be placed
9001 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009002 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009003 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009004 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 synchronized (sr.stats.getBatteryStats()) {
9006 sr.stats.stopLaunchedLocked();
9007 }
9008 sr.app = null;
9009 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009010 if (mStoppingServices.remove(sr)) {
9011 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9012 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009013
9014 boolean hasClients = sr.bindings.size() > 0;
9015 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009016 Iterator<IntentBindRecord> bindings
9017 = sr.bindings.values().iterator();
9018 while (bindings.hasNext()) {
9019 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009020 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009021 + ": shouldUnbind=" + b.hasBound);
9022 b.binder = null;
9023 b.requested = b.received = b.hasBound = false;
9024 }
9025 }
9026
Dianne Hackborn070783f2010-12-29 16:46:28 -08009027 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9028 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009029 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009030 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009031 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009032 sr.crashCount, sr.shortName, app.pid);
9033 bringDownServiceLocked(sr, true);
9034 } else if (!allowRestart) {
9035 bringDownServiceLocked(sr, true);
9036 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009037 boolean canceled = scheduleServiceRestartLocked(sr, true);
9038
9039 // Should the service remain running? Note that in the
9040 // extreme case of so many attempts to deliver a command
9041 // that it failed, that we also will stop it here.
9042 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9043 if (sr.pendingStarts.size() == 0) {
9044 sr.startRequested = false;
9045 if (!hasClients) {
9046 // Whoops, no reason to restart!
9047 bringDownServiceLocked(sr, true);
9048 }
9049 }
9050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009051 }
9052 }
9053
9054 if (!allowRestart) {
9055 app.services.clear();
9056 }
9057 }
9058
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009059 // Make sure we have no more records on the stopping list.
9060 int i = mStoppingServices.size();
9061 while (i > 0) {
9062 i--;
9063 ServiceRecord sr = mStoppingServices.get(i);
9064 if (sr.app == app) {
9065 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009066 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009067 }
9068 }
9069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009070 app.executingServices.clear();
9071 }
9072
9073 private final void removeDyingProviderLocked(ProcessRecord proc,
9074 ContentProviderRecord cpr) {
9075 synchronized (cpr) {
9076 cpr.launchingApp = null;
9077 cpr.notifyAll();
9078 }
9079
9080 mProvidersByClass.remove(cpr.info.name);
9081 String names[] = cpr.info.authority.split(";");
9082 for (int j = 0; j < names.length; j++) {
9083 mProvidersByName.remove(names[j]);
9084 }
9085
9086 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9087 while (cit.hasNext()) {
9088 ProcessRecord capp = cit.next();
9089 if (!capp.persistent && capp.thread != null
9090 && capp.pid != 0
9091 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009092 Slog.i(TAG, "Kill " + capp.processName
9093 + " (pid " + capp.pid + "): provider " + cpr.info.name
9094 + " in dying process " + proc.processName);
9095 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9096 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009097 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009098 }
9099 }
9100
9101 mLaunchingProviders.remove(cpr);
9102 }
9103
9104 /**
9105 * Main code for cleaning up a process when it has gone away. This is
9106 * called both as a result of the process dying, or directly when stopping
9107 * a process when running in single process mode.
9108 */
9109 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9110 boolean restarting, int index) {
9111 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009112 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009113 }
9114
Dianne Hackborn36124872009-10-08 16:22:03 -07009115 mProcessesToGc.remove(app);
9116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009117 // Dismiss any open dialogs.
9118 if (app.crashDialog != null) {
9119 app.crashDialog.dismiss();
9120 app.crashDialog = null;
9121 }
9122 if (app.anrDialog != null) {
9123 app.anrDialog.dismiss();
9124 app.anrDialog = null;
9125 }
9126 if (app.waitDialog != null) {
9127 app.waitDialog.dismiss();
9128 app.waitDialog = null;
9129 }
9130
9131 app.crashing = false;
9132 app.notResponding = false;
9133
9134 app.resetPackageList();
9135 app.thread = null;
9136 app.forcingToForeground = null;
9137 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009138 app.foregroundActivities = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009139
9140 killServicesLocked(app, true);
9141
9142 boolean restart = false;
9143
9144 int NL = mLaunchingProviders.size();
9145
9146 // Remove published content providers.
9147 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009148 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009149 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009150 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009151 cpr.provider = null;
9152 cpr.app = null;
9153
9154 // See if someone is waiting for this provider... in which
9155 // case we don't remove it, but just let it restart.
9156 int i = 0;
9157 if (!app.bad) {
9158 for (; i<NL; i++) {
9159 if (mLaunchingProviders.get(i) == cpr) {
9160 restart = true;
9161 break;
9162 }
9163 }
9164 } else {
9165 i = NL;
9166 }
9167
9168 if (i >= NL) {
9169 removeDyingProviderLocked(app, cpr);
9170 NL = mLaunchingProviders.size();
9171 }
9172 }
9173 app.pubProviders.clear();
9174 }
9175
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009176 // Take care of any launching providers waiting for this process.
9177 if (checkAppInLaunchingProvidersLocked(app, false)) {
9178 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009179 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009181 // Unregister from connected content providers.
9182 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009183 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009184 while (it.hasNext()) {
9185 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9186 cpr.clients.remove(app);
9187 }
9188 app.conProviders.clear();
9189 }
9190
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009191 // At this point there may be remaining entries in mLaunchingProviders
9192 // where we were the only one waiting, so they are no longer of use.
9193 // Look for these and clean up if found.
9194 // XXX Commented out for now. Trying to figure out a way to reproduce
9195 // the actual situation to identify what is actually going on.
9196 if (false) {
9197 for (int i=0; i<NL; i++) {
9198 ContentProviderRecord cpr = (ContentProviderRecord)
9199 mLaunchingProviders.get(i);
9200 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9201 synchronized (cpr) {
9202 cpr.launchingApp = null;
9203 cpr.notifyAll();
9204 }
9205 }
9206 }
9207 }
9208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009209 skipCurrentReceiverLocked(app);
9210
9211 // Unregister any receivers.
9212 if (app.receivers.size() > 0) {
9213 Iterator<ReceiverList> it = app.receivers.iterator();
9214 while (it.hasNext()) {
9215 removeReceiverLocked(it.next());
9216 }
9217 app.receivers.clear();
9218 }
9219
Christopher Tate181fafa2009-05-14 11:12:14 -07009220 // If the app is undergoing backup, tell the backup manager about it
9221 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009222 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009223 try {
9224 IBackupManager bm = IBackupManager.Stub.asInterface(
9225 ServiceManager.getService(Context.BACKUP_SERVICE));
9226 bm.agentDisconnected(app.info.packageName);
9227 } catch (RemoteException e) {
9228 // can't happen; backup manager is local
9229 }
9230 }
9231
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009232 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app).sendToTarget();
9233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009234 // If the caller is restarting this app, then leave it in its
9235 // current lists and let the caller take care of it.
9236 if (restarting) {
9237 return;
9238 }
9239
9240 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009241 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009242 "Removing non-persistent process during cleanup: " + app);
9243 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009244 if (mHeavyWeightProcess == app) {
9245 mHeavyWeightProcess = null;
9246 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9247 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009248 } else if (!app.removed) {
9249 // This app is persistent, so we need to keep its record around.
9250 // If it is not already on the pending app list, add it there
9251 // and start a new process for it.
9252 app.thread = null;
9253 app.forcingToForeground = null;
9254 app.foregroundServices = false;
9255 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9256 mPersistentStartingProcesses.add(app);
9257 restart = true;
9258 }
9259 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009260 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9261 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009262 mProcessesOnHold.remove(app);
9263
The Android Open Source Project4df24232009-03-05 14:34:35 -08009264 if (app == mHomeProcess) {
9265 mHomeProcess = null;
9266 }
9267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009268 if (restart) {
9269 // We have components that still need to be running in the
9270 // process, so re-launch it.
9271 mProcessNames.put(app.processName, app.info.uid, app);
9272 startProcessLocked(app, "restart", app.processName);
9273 } else if (app.pid > 0 && app.pid != MY_PID) {
9274 // Goodbye!
9275 synchronized (mPidsSelfLocked) {
9276 mPidsSelfLocked.remove(app.pid);
9277 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9278 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009279 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 }
9281 }
9282
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009283 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9284 // Look through the content providers we are waiting to have launched,
9285 // and if any run in this process then either schedule a restart of
9286 // the process or kill the client waiting for it if this process has
9287 // gone bad.
9288 int NL = mLaunchingProviders.size();
9289 boolean restart = false;
9290 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009291 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009292 if (cpr.launchingApp == app) {
9293 if (!alwaysBad && !app.bad) {
9294 restart = true;
9295 } else {
9296 removeDyingProviderLocked(app, cpr);
9297 NL = mLaunchingProviders.size();
9298 }
9299 }
9300 }
9301 return restart;
9302 }
9303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009304 // =========================================================
9305 // SERVICES
9306 // =========================================================
9307
9308 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9309 ActivityManager.RunningServiceInfo info =
9310 new ActivityManager.RunningServiceInfo();
9311 info.service = r.name;
9312 if (r.app != null) {
9313 info.pid = r.app.pid;
9314 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009315 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009316 info.process = r.processName;
9317 info.foreground = r.isForeground;
9318 info.activeSince = r.createTime;
9319 info.started = r.startRequested;
9320 info.clientCount = r.connections.size();
9321 info.crashCount = r.crashCount;
9322 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009323 if (r.isForeground) {
9324 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9325 }
9326 if (r.startRequested) {
9327 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9328 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009329 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009330 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9331 }
9332 if (r.app != null && r.app.persistent) {
9333 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9334 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009335
9336 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9337 for (int i=0; i<connl.size(); i++) {
9338 ConnectionRecord conn = connl.get(i);
9339 if (conn.clientLabel != 0) {
9340 info.clientPackage = conn.binding.client.info.packageName;
9341 info.clientLabel = conn.clientLabel;
9342 return info;
9343 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009344 }
9345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009346 return info;
9347 }
9348
9349 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9350 int flags) {
9351 synchronized (this) {
9352 ArrayList<ActivityManager.RunningServiceInfo> res
9353 = new ArrayList<ActivityManager.RunningServiceInfo>();
9354
9355 if (mServices.size() > 0) {
9356 Iterator<ServiceRecord> it = mServices.values().iterator();
9357 while (it.hasNext() && res.size() < maxNum) {
9358 res.add(makeRunningServiceInfoLocked(it.next()));
9359 }
9360 }
9361
9362 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9363 ServiceRecord r = mRestartingServices.get(i);
9364 ActivityManager.RunningServiceInfo info =
9365 makeRunningServiceInfoLocked(r);
9366 info.restarting = r.nextRestartTime;
9367 res.add(info);
9368 }
9369
9370 return res;
9371 }
9372 }
9373
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009374 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9375 synchronized (this) {
9376 ServiceRecord r = mServices.get(name);
9377 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009378 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9379 for (int i=0; i<conn.size(); i++) {
9380 if (conn.get(i).clientIntent != null) {
9381 return conn.get(i).clientIntent;
9382 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009383 }
9384 }
9385 }
9386 }
9387 return null;
9388 }
9389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009390 private final ServiceRecord findServiceLocked(ComponentName name,
9391 IBinder token) {
9392 ServiceRecord r = mServices.get(name);
9393 return r == token ? r : null;
9394 }
9395
9396 private final class ServiceLookupResult {
9397 final ServiceRecord record;
9398 final String permission;
9399
9400 ServiceLookupResult(ServiceRecord _record, String _permission) {
9401 record = _record;
9402 permission = _permission;
9403 }
9404 };
9405
9406 private ServiceLookupResult findServiceLocked(Intent service,
9407 String resolvedType) {
9408 ServiceRecord r = null;
9409 if (service.getComponent() != null) {
9410 r = mServices.get(service.getComponent());
9411 }
9412 if (r == null) {
9413 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9414 r = mServicesByIntent.get(filter);
9415 }
9416
9417 if (r == null) {
9418 try {
9419 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009420 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 service, resolvedType, 0);
9422 ServiceInfo sInfo =
9423 rInfo != null ? rInfo.serviceInfo : null;
9424 if (sInfo == null) {
9425 return null;
9426 }
9427
9428 ComponentName name = new ComponentName(
9429 sInfo.applicationInfo.packageName, sInfo.name);
9430 r = mServices.get(name);
9431 } catch (RemoteException ex) {
9432 // pm is in same process, this will never happen.
9433 }
9434 }
9435 if (r != null) {
9436 int callingPid = Binder.getCallingPid();
9437 int callingUid = Binder.getCallingUid();
9438 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009439 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009440 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009441 if (!r.exported) {
9442 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9443 + " from pid=" + callingPid
9444 + ", uid=" + callingUid
9445 + " that is not exported from uid " + r.appInfo.uid);
9446 return new ServiceLookupResult(null, "not exported from uid "
9447 + r.appInfo.uid);
9448 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009449 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009450 + " from pid=" + callingPid
9451 + ", uid=" + callingUid
9452 + " requires " + r.permission);
9453 return new ServiceLookupResult(null, r.permission);
9454 }
9455 return new ServiceLookupResult(r, null);
9456 }
9457 return null;
9458 }
9459
9460 private class ServiceRestarter implements Runnable {
9461 private ServiceRecord mService;
9462
9463 void setService(ServiceRecord service) {
9464 mService = service;
9465 }
9466
9467 public void run() {
9468 synchronized(ActivityManagerService.this) {
9469 performServiceRestartLocked(mService);
9470 }
9471 }
9472 }
9473
9474 private ServiceLookupResult retrieveServiceLocked(Intent service,
9475 String resolvedType, int callingPid, int callingUid) {
9476 ServiceRecord r = null;
9477 if (service.getComponent() != null) {
9478 r = mServices.get(service.getComponent());
9479 }
9480 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9481 r = mServicesByIntent.get(filter);
9482 if (r == null) {
9483 try {
9484 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009485 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009486 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009487 ServiceInfo sInfo =
9488 rInfo != null ? rInfo.serviceInfo : null;
9489 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009490 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 ": not found");
9492 return null;
9493 }
9494
9495 ComponentName name = new ComponentName(
9496 sInfo.applicationInfo.packageName, sInfo.name);
9497 r = mServices.get(name);
9498 if (r == null) {
9499 filter = new Intent.FilterComparison(service.cloneFilter());
9500 ServiceRestarter res = new ServiceRestarter();
9501 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9502 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9503 synchronized (stats) {
9504 ss = stats.getServiceStatsLocked(
9505 sInfo.applicationInfo.uid, sInfo.packageName,
9506 sInfo.name);
9507 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009508 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509 res.setService(r);
9510 mServices.put(name, r);
9511 mServicesByIntent.put(filter, r);
9512
9513 // Make sure this component isn't in the pending list.
9514 int N = mPendingServices.size();
9515 for (int i=0; i<N; i++) {
9516 ServiceRecord pr = mPendingServices.get(i);
9517 if (pr.name.equals(name)) {
9518 mPendingServices.remove(i);
9519 i--;
9520 N--;
9521 }
9522 }
9523 }
9524 } catch (RemoteException ex) {
9525 // pm is in same process, this will never happen.
9526 }
9527 }
9528 if (r != null) {
9529 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009530 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009532 if (!r.exported) {
9533 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9534 + " from pid=" + callingPid
9535 + ", uid=" + callingUid
9536 + " that is not exported from uid " + r.appInfo.uid);
9537 return new ServiceLookupResult(null, "not exported from uid "
9538 + r.appInfo.uid);
9539 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009540 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009541 + " from pid=" + callingPid
9542 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 + " requires " + r.permission);
9544 return new ServiceLookupResult(null, r.permission);
9545 }
9546 return new ServiceLookupResult(r, null);
9547 }
9548 return null;
9549 }
9550
Dianne Hackborn287952c2010-09-22 22:34:31 -07009551 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9552 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9553 + why + " of " + r + " in app " + r.app);
9554 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9555 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009556 long now = SystemClock.uptimeMillis();
9557 if (r.executeNesting == 0 && r.app != null) {
9558 if (r.app.executingServices.size() == 0) {
9559 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9560 msg.obj = r.app;
9561 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9562 }
9563 r.app.executingServices.add(r);
9564 }
9565 r.executeNesting++;
9566 r.executingStart = now;
9567 }
9568
9569 private final void sendServiceArgsLocked(ServiceRecord r,
9570 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009571 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009572 if (N == 0) {
9573 return;
9574 }
9575
Dianne Hackborn39792d22010-08-19 18:01:52 -07009576 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009577 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009578 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009579 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9580 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009581 if (si.intent == null && N > 1) {
9582 // If somehow we got a dummy null intent in the middle,
9583 // then skip it. DO NOT skip a null intent when it is
9584 // the only one in the list -- this is to support the
9585 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009586 continue;
9587 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009588 si.deliveredTime = SystemClock.uptimeMillis();
9589 r.deliveredStarts.add(si);
9590 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009591 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009592 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009593 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009594 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009595 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009596 if (!oomAdjusted) {
9597 oomAdjusted = true;
9598 updateOomAdjLocked(r.app);
9599 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009600 int flags = 0;
9601 if (si.deliveryCount > 0) {
9602 flags |= Service.START_FLAG_RETRY;
9603 }
9604 if (si.doneExecutingCount > 0) {
9605 flags |= Service.START_FLAG_REDELIVERY;
9606 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009607 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009608 } catch (RemoteException e) {
9609 // Remote process gone... we'll let the normal cleanup take
9610 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009611 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009612 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009613 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009614 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009615 break;
9616 }
9617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 }
9619
9620 private final boolean requestServiceBindingLocked(ServiceRecord r,
9621 IntentBindRecord i, boolean rebind) {
9622 if (r.app == null || r.app.thread == null) {
9623 // If service is not currently running, can't yet bind.
9624 return false;
9625 }
9626 if ((!i.requested || rebind) && i.apps.size() > 0) {
9627 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009628 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009629 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9630 if (!rebind) {
9631 i.requested = true;
9632 }
9633 i.hasBound = true;
9634 i.doRebind = false;
9635 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009636 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009637 return false;
9638 }
9639 }
9640 return true;
9641 }
9642
9643 private final void requestServiceBindingsLocked(ServiceRecord r) {
9644 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9645 while (bindings.hasNext()) {
9646 IntentBindRecord i = bindings.next();
9647 if (!requestServiceBindingLocked(r, i, false)) {
9648 break;
9649 }
9650 }
9651 }
9652
9653 private final void realStartServiceLocked(ServiceRecord r,
9654 ProcessRecord app) throws RemoteException {
9655 if (app.thread == null) {
9656 throw new RemoteException();
9657 }
9658
9659 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009660 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661
9662 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009663 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009664 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009665
9666 boolean created = false;
9667 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009668 mStringBuilder.setLength(0);
9669 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009670 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009671 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009672 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009673 synchronized (r.stats.getBatteryStats()) {
9674 r.stats.startLaunchedLocked();
9675 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009676 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009677 app.thread.scheduleCreateService(r, r.serviceInfo,
9678 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009679 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009680 created = true;
9681 } finally {
9682 if (!created) {
9683 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009684 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 }
9686 }
9687
9688 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009689
9690 // If the service is in the started state, and there are no
9691 // pending arguments, then fake up one so its onStartCommand() will
9692 // be called.
9693 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009694 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9695 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009696 }
9697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 sendServiceArgsLocked(r, true);
9699 }
9700
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009701 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9702 boolean allowCancel) {
9703 boolean canceled = false;
9704
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009705 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009706 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009707 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009708
Dianne Hackborn070783f2010-12-29 16:46:28 -08009709 if ((r.serviceInfo.applicationInfo.flags
9710 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9711 minDuration /= 4;
9712 }
9713
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009714 // Any delivered but not yet finished starts should be put back
9715 // on the pending list.
9716 final int N = r.deliveredStarts.size();
9717 if (N > 0) {
9718 for (int i=N-1; i>=0; i--) {
9719 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009720 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009721 if (si.intent == null) {
9722 // We'll generate this again if needed.
9723 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9724 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9725 r.pendingStarts.add(0, si);
9726 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9727 dur *= 2;
9728 if (minDuration < dur) minDuration = dur;
9729 if (resetTime < dur) resetTime = dur;
9730 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009731 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009732 + r.name);
9733 canceled = true;
9734 }
9735 }
9736 r.deliveredStarts.clear();
9737 }
9738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009739 r.totalRestartCount++;
9740 if (r.restartDelay == 0) {
9741 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009742 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009743 } else {
9744 // If it has been a "reasonably long time" since the service
9745 // was started, then reset our restart duration back to
9746 // the beginning, so we don't infinitely increase the duration
9747 // on a service that just occasionally gets killed (which is
9748 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009749 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009750 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009751 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009752 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009753 if ((r.serviceInfo.applicationInfo.flags
9754 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9755 // Services in peristent processes will restart much more
9756 // quickly, since they are pretty important. (Think SystemUI).
9757 r.restartDelay += minDuration/2;
9758 } else {
9759 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9760 if (r.restartDelay < minDuration) {
9761 r.restartDelay = minDuration;
9762 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009763 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009764 }
9765 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009766
9767 r.nextRestartTime = now + r.restartDelay;
9768
9769 // Make sure that we don't end up restarting a bunch of services
9770 // all at the same time.
9771 boolean repeat;
9772 do {
9773 repeat = false;
9774 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9775 ServiceRecord r2 = mRestartingServices.get(i);
9776 if (r2 != r && r.nextRestartTime
9777 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9778 && r.nextRestartTime
9779 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9780 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9781 r.restartDelay = r.nextRestartTime - now;
9782 repeat = true;
9783 break;
9784 }
9785 }
9786 } while (repeat);
9787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009788 if (!mRestartingServices.contains(r)) {
9789 mRestartingServices.add(r);
9790 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009791
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009792 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009794 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009795 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009796 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009797 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009798 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009799 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009800 r.shortName, r.restartDelay);
9801
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009802 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009803 }
9804
9805 final void performServiceRestartLocked(ServiceRecord r) {
9806 if (!mRestartingServices.contains(r)) {
9807 return;
9808 }
9809 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9810 }
9811
9812 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9813 if (r.restartDelay == 0) {
9814 return false;
9815 }
9816 r.resetRestartCounter();
9817 mRestartingServices.remove(r);
9818 mHandler.removeCallbacks(r.restarter);
9819 return true;
9820 }
9821
9822 private final boolean bringUpServiceLocked(ServiceRecord r,
9823 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009824 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009825 //r.dump(" ");
9826
Dianne Hackborn36124872009-10-08 16:22:03 -07009827 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828 sendServiceArgsLocked(r, false);
9829 return true;
9830 }
9831
9832 if (!whileRestarting && r.restartDelay > 0) {
9833 // If waiting for a restart, then do nothing.
9834 return true;
9835 }
9836
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009837 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009838
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009839 // We are now bringing the service up, so no longer in the
9840 // restarting state.
9841 mRestartingServices.remove(r);
9842
Dianne Hackborne7f97212011-02-24 14:40:20 -08009843 // Service is now being launched, its package can't be stopped.
9844 try {
9845 AppGlobals.getPackageManager().setPackageStoppedState(
9846 r.packageName, false);
9847 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009848 } catch (IllegalArgumentException e) {
9849 Slog.w(TAG, "Failed trying to unstop package "
9850 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009851 }
9852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009853 final String appName = r.processName;
9854 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9855 if (app != null && app.thread != null) {
9856 try {
9857 realStartServiceLocked(r, app);
9858 return true;
9859 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009860 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009861 }
9862
9863 // If a dead object exception was thrown -- fall through to
9864 // restart the application.
9865 }
9866
Dianne Hackborn36124872009-10-08 16:22:03 -07009867 // Not running -- get it started, and enqueue this service record
9868 // to be executed when the app comes up.
9869 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9870 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009871 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009872 + r.appInfo.packageName + "/"
9873 + r.appInfo.uid + " for service "
9874 + r.intent.getIntent() + ": process is bad");
9875 bringDownServiceLocked(r, true);
9876 return false;
9877 }
9878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009879 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009880 mPendingServices.add(r);
9881 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009883 return true;
9884 }
9885
9886 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009887 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009888 //r.dump(" ");
9889
9890 // Does it still need to run?
9891 if (!force && r.startRequested) {
9892 return;
9893 }
9894 if (r.connections.size() > 0) {
9895 if (!force) {
9896 // XXX should probably keep a count of the number of auto-create
9897 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009898 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009899 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009900 ArrayList<ConnectionRecord> cr = it.next();
9901 for (int i=0; i<cr.size(); i++) {
9902 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9903 return;
9904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 }
9906 }
9907 }
9908
9909 // Report to all of the connections that the service is no longer
9910 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009911 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009913 ArrayList<ConnectionRecord> c = it.next();
9914 for (int i=0; i<c.size(); i++) {
9915 try {
9916 c.get(i).conn.connected(r.name, null);
9917 } catch (Exception e) {
9918 Slog.w(TAG, "Failure disconnecting service " + r.name +
9919 " to connection " + c.get(i).conn.asBinder() +
9920 " (in " + c.get(i).binding.client.processName + ")", e);
9921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009922 }
9923 }
9924 }
9925
9926 // Tell the service that it has been unbound.
9927 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9928 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9929 while (it.hasNext()) {
9930 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009931 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009932 + ": hasBound=" + ibr.hasBound);
9933 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9934 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009935 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 updateOomAdjLocked(r.app);
9937 ibr.hasBound = false;
9938 r.app.thread.scheduleUnbindService(r,
9939 ibr.intent.getIntent());
9940 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009941 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009942 + r.shortName, e);
9943 serviceDoneExecutingLocked(r, true);
9944 }
9945 }
9946 }
9947 }
9948
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009949 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009950 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009951 System.identityHashCode(r), r.shortName,
9952 (r.app != null) ? r.app.pid : -1);
9953
9954 mServices.remove(r.name);
9955 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 r.totalRestartCount = 0;
9957 unscheduleServiceRestartLocked(r);
9958
9959 // Also make sure it is not on the pending list.
9960 int N = mPendingServices.size();
9961 for (int i=0; i<N; i++) {
9962 if (mPendingServices.get(i) == r) {
9963 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009964 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 i--;
9966 N--;
9967 }
9968 }
9969
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009970 r.cancelNotification();
9971 r.isForeground = false;
9972 r.foregroundId = 0;
9973 r.foregroundNoti = null;
9974
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009975 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009976 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009977 r.pendingStarts.clear();
9978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009979 if (r.app != null) {
9980 synchronized (r.stats.getBatteryStats()) {
9981 r.stats.stopLaunchedLocked();
9982 }
9983 r.app.services.remove(r);
9984 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009985 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009986 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009987 mStoppingServices.add(r);
9988 updateOomAdjLocked(r.app);
9989 r.app.thread.scheduleStopService(r);
9990 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009991 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 + r.shortName, e);
9993 serviceDoneExecutingLocked(r, true);
9994 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009995 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009997 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009998 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009999 }
10000 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010001 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010002 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010003 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010004
10005 if (r.bindings.size() > 0) {
10006 r.bindings.clear();
10007 }
10008
10009 if (r.restarter instanceof ServiceRestarter) {
10010 ((ServiceRestarter)r.restarter).setService(null);
10011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012 }
10013
10014 ComponentName startServiceLocked(IApplicationThread caller,
10015 Intent service, String resolvedType,
10016 int callingPid, int callingUid) {
10017 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010018 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010019 + " type=" + resolvedType + " args=" + service.getExtras());
10020
10021 if (caller != null) {
10022 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10023 if (callerApp == null) {
10024 throw new SecurityException(
10025 "Unable to find app for caller " + caller
10026 + " (pid=" + Binder.getCallingPid()
10027 + ") when starting service " + service);
10028 }
10029 }
10030
10031 ServiceLookupResult res =
10032 retrieveServiceLocked(service, resolvedType,
10033 callingPid, callingUid);
10034 if (res == null) {
10035 return null;
10036 }
10037 if (res.record == null) {
10038 return new ComponentName("!", res.permission != null
10039 ? res.permission : "private to package");
10040 }
10041 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010042 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10043 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010044 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010045 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010046 }
10047 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010048 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010049 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010050 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051 r.lastActivity = SystemClock.uptimeMillis();
10052 synchronized (r.stats.getBatteryStats()) {
10053 r.stats.startRunningLocked();
10054 }
10055 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10056 return new ComponentName("!", "Service process is bad");
10057 }
10058 return r.name;
10059 }
10060 }
10061
10062 public ComponentName startService(IApplicationThread caller, Intent service,
10063 String resolvedType) {
10064 // Refuse possible leaked file descriptors
10065 if (service != null && service.hasFileDescriptors() == true) {
10066 throw new IllegalArgumentException("File descriptors passed in Intent");
10067 }
10068
10069 synchronized(this) {
10070 final int callingPid = Binder.getCallingPid();
10071 final int callingUid = Binder.getCallingUid();
10072 final long origId = Binder.clearCallingIdentity();
10073 ComponentName res = startServiceLocked(caller, service,
10074 resolvedType, callingPid, callingUid);
10075 Binder.restoreCallingIdentity(origId);
10076 return res;
10077 }
10078 }
10079
10080 ComponentName startServiceInPackage(int uid,
10081 Intent service, String resolvedType) {
10082 synchronized(this) {
10083 final long origId = Binder.clearCallingIdentity();
10084 ComponentName res = startServiceLocked(null, service,
10085 resolvedType, -1, uid);
10086 Binder.restoreCallingIdentity(origId);
10087 return res;
10088 }
10089 }
10090
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010091 private void stopServiceLocked(ServiceRecord service) {
10092 synchronized (service.stats.getBatteryStats()) {
10093 service.stats.stopRunningLocked();
10094 }
10095 service.startRequested = false;
10096 service.callStart = false;
10097 bringDownServiceLocked(service, false);
10098 }
10099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010100 public int stopService(IApplicationThread caller, Intent service,
10101 String resolvedType) {
10102 // Refuse possible leaked file descriptors
10103 if (service != null && service.hasFileDescriptors() == true) {
10104 throw new IllegalArgumentException("File descriptors passed in Intent");
10105 }
10106
10107 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010108 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010109 + " type=" + resolvedType);
10110
10111 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10112 if (caller != null && callerApp == null) {
10113 throw new SecurityException(
10114 "Unable to find app for caller " + caller
10115 + " (pid=" + Binder.getCallingPid()
10116 + ") when stopping service " + service);
10117 }
10118
10119 // If this service is active, make sure it is stopped.
10120 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10121 if (r != null) {
10122 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010123 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010124 try {
10125 stopServiceLocked(r.record);
10126 } finally {
10127 Binder.restoreCallingIdentity(origId);
10128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 return 1;
10130 }
10131 return -1;
10132 }
10133 }
10134
10135 return 0;
10136 }
10137
10138 public IBinder peekService(Intent service, String resolvedType) {
10139 // Refuse possible leaked file descriptors
10140 if (service != null && service.hasFileDescriptors() == true) {
10141 throw new IllegalArgumentException("File descriptors passed in Intent");
10142 }
10143
10144 IBinder ret = null;
10145
10146 synchronized(this) {
10147 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10148
10149 if (r != null) {
10150 // r.record is null if findServiceLocked() failed the caller permission check
10151 if (r.record == null) {
10152 throw new SecurityException(
10153 "Permission Denial: Accessing service " + r.record.name
10154 + " from pid=" + Binder.getCallingPid()
10155 + ", uid=" + Binder.getCallingUid()
10156 + " requires " + r.permission);
10157 }
10158 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10159 if (ib != null) {
10160 ret = ib.binder;
10161 }
10162 }
10163 }
10164
10165 return ret;
10166 }
10167
10168 public boolean stopServiceToken(ComponentName className, IBinder token,
10169 int startId) {
10170 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010171 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010172 + " " + token + " startId=" + startId);
10173 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010174 if (r != null) {
10175 if (startId >= 0) {
10176 // Asked to only stop if done with all work. Note that
10177 // to avoid leaks, we will take this as dropping all
10178 // start items up to and including this one.
10179 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10180 if (si != null) {
10181 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010182 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10183 cur.removeUriPermissionsLocked();
10184 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010185 break;
10186 }
10187 }
10188 }
10189
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010190 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010191 return false;
10192 }
10193
10194 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010195 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010196 + " is last, but have " + r.deliveredStarts.size()
10197 + " remaining args");
10198 }
10199 }
10200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201 synchronized (r.stats.getBatteryStats()) {
10202 r.stats.stopRunningLocked();
10203 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010204 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010205 }
10206 final long origId = Binder.clearCallingIdentity();
10207 bringDownServiceLocked(r, false);
10208 Binder.restoreCallingIdentity(origId);
10209 return true;
10210 }
10211 }
10212 return false;
10213 }
10214
10215 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010216 int id, Notification notification, boolean removeNotification) {
10217 final long origId = Binder.clearCallingIdentity();
10218 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 synchronized(this) {
10220 ServiceRecord r = findServiceLocked(className, token);
10221 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010222 if (id != 0) {
10223 if (notification == null) {
10224 throw new IllegalArgumentException("null notification");
10225 }
10226 if (r.foregroundId != id) {
10227 r.cancelNotification();
10228 r.foregroundId = id;
10229 }
10230 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10231 r.foregroundNoti = notification;
10232 r.isForeground = true;
10233 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010234 if (r.app != null) {
10235 updateServiceForegroundLocked(r.app, true);
10236 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010237 } else {
10238 if (r.isForeground) {
10239 r.isForeground = false;
10240 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010241 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010242 updateServiceForegroundLocked(r.app, true);
10243 }
10244 }
10245 if (removeNotification) {
10246 r.cancelNotification();
10247 r.foregroundId = 0;
10248 r.foregroundNoti = null;
10249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010250 }
10251 }
10252 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010253 } finally {
10254 Binder.restoreCallingIdentity(origId);
10255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010256 }
10257
10258 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10259 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010260 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 if (sr.isForeground) {
10262 anyForeground = true;
10263 break;
10264 }
10265 }
10266 if (anyForeground != proc.foregroundServices) {
10267 proc.foregroundServices = anyForeground;
10268 if (oomAdj) {
10269 updateOomAdjLocked();
10270 }
10271 }
10272 }
10273
10274 public int bindService(IApplicationThread caller, IBinder token,
10275 Intent service, String resolvedType,
10276 IServiceConnection connection, int flags) {
10277 // Refuse possible leaked file descriptors
10278 if (service != null && service.hasFileDescriptors() == true) {
10279 throw new IllegalArgumentException("File descriptors passed in Intent");
10280 }
10281
10282 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010283 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010284 + " type=" + resolvedType + " conn=" + connection.asBinder()
10285 + " flags=0x" + Integer.toHexString(flags));
10286 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10287 if (callerApp == null) {
10288 throw new SecurityException(
10289 "Unable to find app for caller " + caller
10290 + " (pid=" + Binder.getCallingPid()
10291 + ") when binding service " + service);
10292 }
10293
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010294 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010295 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010296 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010298 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010299 return 0;
10300 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010301 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 }
10303
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010304 int clientLabel = 0;
10305 PendingIntent clientIntent = null;
10306
10307 if (callerApp.info.uid == Process.SYSTEM_UID) {
10308 // Hacky kind of thing -- allow system stuff to tell us
10309 // what they are, so we can report this elsewhere for
10310 // others to know why certain services are running.
10311 try {
10312 clientIntent = (PendingIntent)service.getParcelableExtra(
10313 Intent.EXTRA_CLIENT_INTENT);
10314 } catch (RuntimeException e) {
10315 }
10316 if (clientIntent != null) {
10317 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10318 if (clientLabel != 0) {
10319 // There are no useful extras in the intent, trash them.
10320 // System code calling with this stuff just needs to know
10321 // this will happen.
10322 service = service.cloneFilter();
10323 }
10324 }
10325 }
10326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010327 ServiceLookupResult res =
10328 retrieveServiceLocked(service, resolvedType,
10329 Binder.getCallingPid(), Binder.getCallingUid());
10330 if (res == null) {
10331 return 0;
10332 }
10333 if (res.record == null) {
10334 return -1;
10335 }
10336 ServiceRecord s = res.record;
10337
10338 final long origId = Binder.clearCallingIdentity();
10339
10340 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010341 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010342 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010343 }
10344
10345 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10346 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010347 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010348
10349 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010350 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10351 if (clist == null) {
10352 clist = new ArrayList<ConnectionRecord>();
10353 s.connections.put(binder, clist);
10354 }
10355 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010356 b.connections.add(c);
10357 if (activity != null) {
10358 if (activity.connections == null) {
10359 activity.connections = new HashSet<ConnectionRecord>();
10360 }
10361 activity.connections.add(c);
10362 }
10363 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010364 clist = mServiceConnections.get(binder);
10365 if (clist == null) {
10366 clist = new ArrayList<ConnectionRecord>();
10367 mServiceConnections.put(binder, clist);
10368 }
10369 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010370
10371 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10372 s.lastActivity = SystemClock.uptimeMillis();
10373 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10374 return 0;
10375 }
10376 }
10377
10378 if (s.app != null) {
10379 // This could have made the service more important.
10380 updateOomAdjLocked(s.app);
10381 }
10382
Joe Onorato8a9b2202010-02-26 18:56:32 -080010383 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010384 + ": received=" + b.intent.received
10385 + " apps=" + b.intent.apps.size()
10386 + " doRebind=" + b.intent.doRebind);
10387
10388 if (s.app != null && b.intent.received) {
10389 // Service is already running, so we can immediately
10390 // publish the connection.
10391 try {
10392 c.conn.connected(s.name, b.intent.binder);
10393 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010394 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010395 + " to connection " + c.conn.asBinder()
10396 + " (in " + c.binding.client.processName + ")", e);
10397 }
10398
10399 // If this is the first app connected back to this binding,
10400 // and the service had previously asked to be told when
10401 // rebound, then do so.
10402 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10403 requestServiceBindingLocked(s, b.intent, true);
10404 }
10405 } else if (!b.intent.requested) {
10406 requestServiceBindingLocked(s, b.intent, false);
10407 }
10408
10409 Binder.restoreCallingIdentity(origId);
10410 }
10411
10412 return 1;
10413 }
10414
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010415 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010416 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010417 IBinder binder = c.conn.asBinder();
10418 AppBindRecord b = c.binding;
10419 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010420 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10421 if (clist != null) {
10422 clist.remove(c);
10423 if (clist.size() == 0) {
10424 s.connections.remove(binder);
10425 }
10426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010427 b.connections.remove(c);
10428 if (c.activity != null && c.activity != skipAct) {
10429 if (c.activity.connections != null) {
10430 c.activity.connections.remove(c);
10431 }
10432 }
10433 if (b.client != skipApp) {
10434 b.client.connections.remove(c);
10435 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010436 clist = mServiceConnections.get(binder);
10437 if (clist != null) {
10438 clist.remove(c);
10439 if (clist.size() == 0) {
10440 mServiceConnections.remove(binder);
10441 }
10442 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443
10444 if (b.connections.size() == 0) {
10445 b.intent.apps.remove(b.client);
10446 }
10447
Joe Onorato8a9b2202010-02-26 18:56:32 -080010448 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010449 + ": shouldUnbind=" + b.intent.hasBound);
10450 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10451 && b.intent.hasBound) {
10452 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010453 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010454 updateOomAdjLocked(s.app);
10455 b.intent.hasBound = false;
10456 // Assume the client doesn't want to know about a rebind;
10457 // we will deal with that later if it asks for one.
10458 b.intent.doRebind = false;
10459 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10460 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010461 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010462 serviceDoneExecutingLocked(s, true);
10463 }
10464 }
10465
10466 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10467 bringDownServiceLocked(s, false);
10468 }
10469 }
10470
10471 public boolean unbindService(IServiceConnection connection) {
10472 synchronized (this) {
10473 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010474 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010475 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10476 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010477 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010478 + connection.asBinder());
10479 return false;
10480 }
10481
10482 final long origId = Binder.clearCallingIdentity();
10483
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010484 while (clist.size() > 0) {
10485 ConnectionRecord r = clist.get(0);
10486 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010487
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010488 if (r.binding.service.app != null) {
10489 // This could have made the service less important.
10490 updateOomAdjLocked(r.binding.service.app);
10491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010492 }
10493
10494 Binder.restoreCallingIdentity(origId);
10495 }
10496
10497 return true;
10498 }
10499
10500 public void publishService(IBinder token, Intent intent, IBinder service) {
10501 // Refuse possible leaked file descriptors
10502 if (intent != null && intent.hasFileDescriptors() == true) {
10503 throw new IllegalArgumentException("File descriptors passed in Intent");
10504 }
10505
10506 synchronized(this) {
10507 if (!(token instanceof ServiceRecord)) {
10508 throw new IllegalArgumentException("Invalid service token");
10509 }
10510 ServiceRecord r = (ServiceRecord)token;
10511
10512 final long origId = Binder.clearCallingIdentity();
10513
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010514 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010515 + " " + intent + ": " + service);
10516 if (r != null) {
10517 Intent.FilterComparison filter
10518 = new Intent.FilterComparison(intent);
10519 IntentBindRecord b = r.bindings.get(filter);
10520 if (b != null && !b.received) {
10521 b.binder = service;
10522 b.requested = true;
10523 b.received = true;
10524 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010525 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010526 = r.connections.values().iterator();
10527 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010528 ArrayList<ConnectionRecord> clist = it.next();
10529 for (int i=0; i<clist.size(); i++) {
10530 ConnectionRecord c = clist.get(i);
10531 if (!filter.equals(c.binding.intent.intent)) {
10532 if (DEBUG_SERVICE) Slog.v(
10533 TAG, "Not publishing to: " + c);
10534 if (DEBUG_SERVICE) Slog.v(
10535 TAG, "Bound intent: " + c.binding.intent.intent);
10536 if (DEBUG_SERVICE) Slog.v(
10537 TAG, "Published intent: " + intent);
10538 continue;
10539 }
10540 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10541 try {
10542 c.conn.connected(r.name, service);
10543 } catch (Exception e) {
10544 Slog.w(TAG, "Failure sending service " + r.name +
10545 " to connection " + c.conn.asBinder() +
10546 " (in " + c.binding.client.processName + ")", e);
10547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 }
10549 }
10550 }
10551 }
10552
10553 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10554
10555 Binder.restoreCallingIdentity(origId);
10556 }
10557 }
10558 }
10559
10560 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10561 // Refuse possible leaked file descriptors
10562 if (intent != null && intent.hasFileDescriptors() == true) {
10563 throw new IllegalArgumentException("File descriptors passed in Intent");
10564 }
10565
10566 synchronized(this) {
10567 if (!(token instanceof ServiceRecord)) {
10568 throw new IllegalArgumentException("Invalid service token");
10569 }
10570 ServiceRecord r = (ServiceRecord)token;
10571
10572 final long origId = Binder.clearCallingIdentity();
10573
10574 if (r != null) {
10575 Intent.FilterComparison filter
10576 = new Intent.FilterComparison(intent);
10577 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010578 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010579 + " at " + b + ": apps="
10580 + (b != null ? b.apps.size() : 0));
10581 if (b != null) {
10582 if (b.apps.size() > 0) {
10583 // Applications have already bound since the last
10584 // unbind, so just rebind right here.
10585 requestServiceBindingLocked(r, b, true);
10586 } else {
10587 // Note to tell the service the next time there is
10588 // a new client.
10589 b.doRebind = true;
10590 }
10591 }
10592
10593 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10594
10595 Binder.restoreCallingIdentity(origId);
10596 }
10597 }
10598 }
10599
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010600 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010601 synchronized(this) {
10602 if (!(token instanceof ServiceRecord)) {
10603 throw new IllegalArgumentException("Invalid service token");
10604 }
10605 ServiceRecord r = (ServiceRecord)token;
10606 boolean inStopping = mStoppingServices.contains(token);
10607 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010608 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010609 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010610 + " with incorrect token: given " + token
10611 + ", expected " + r);
10612 return;
10613 }
10614
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010615 if (type == 1) {
10616 // This is a call from a service start... take care of
10617 // book-keeping.
10618 r.callStart = true;
10619 switch (res) {
10620 case Service.START_STICKY_COMPATIBILITY:
10621 case Service.START_STICKY: {
10622 // We are done with the associated start arguments.
10623 r.findDeliveredStart(startId, true);
10624 // Don't stop if killed.
10625 r.stopIfKilled = false;
10626 break;
10627 }
10628 case Service.START_NOT_STICKY: {
10629 // We are done with the associated start arguments.
10630 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010631 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010632 // There is no more work, and this service
10633 // doesn't want to hang around if killed.
10634 r.stopIfKilled = true;
10635 }
10636 break;
10637 }
10638 case Service.START_REDELIVER_INTENT: {
10639 // We'll keep this item until they explicitly
10640 // call stop for it, but keep track of the fact
10641 // that it was delivered.
10642 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10643 if (si != null) {
10644 si.deliveryCount = 0;
10645 si.doneExecutingCount++;
10646 // Don't stop if killed.
10647 r.stopIfKilled = true;
10648 }
10649 break;
10650 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010651 case Service.START_TASK_REMOVED_COMPLETE: {
10652 // Special processing for onTaskRemoved(). Don't
10653 // impact normal onStartCommand() processing.
10654 r.findDeliveredStart(startId, true);
10655 break;
10656 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010657 default:
10658 throw new IllegalArgumentException(
10659 "Unknown service start result: " + res);
10660 }
10661 if (res == Service.START_STICKY_COMPATIBILITY) {
10662 r.callStart = false;
10663 }
10664 }
10665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010666 final long origId = Binder.clearCallingIdentity();
10667 serviceDoneExecutingLocked(r, inStopping);
10668 Binder.restoreCallingIdentity(origId);
10669 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010670 Slog.w(TAG, "Done executing unknown service from pid "
10671 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010672 }
10673 }
10674 }
10675
10676 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010677 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10678 + ": nesting=" + r.executeNesting
10679 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010680 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010681 r.executeNesting--;
10682 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010683 if (DEBUG_SERVICE) Slog.v(TAG,
10684 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010685 r.app.executingServices.remove(r);
10686 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010687 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10688 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10690 }
10691 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010692 if (DEBUG_SERVICE) Slog.v(TAG,
10693 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010694 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010695 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010696 }
10697 updateOomAdjLocked(r.app);
10698 }
10699 }
10700
10701 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010702 String anrMessage = null;
10703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010704 synchronized(this) {
10705 if (proc.executingServices.size() == 0 || proc.thread == null) {
10706 return;
10707 }
10708 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10709 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10710 ServiceRecord timeout = null;
10711 long nextTime = 0;
10712 while (it.hasNext()) {
10713 ServiceRecord sr = it.next();
10714 if (sr.executingStart < maxTime) {
10715 timeout = sr;
10716 break;
10717 }
10718 if (sr.executingStart > nextTime) {
10719 nextTime = sr.executingStart;
10720 }
10721 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010722 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010723 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010724 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010725 } else {
10726 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10727 msg.obj = proc;
10728 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10729 }
10730 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010731
10732 if (anrMessage != null) {
10733 appNotResponding(proc, null, null, anrMessage);
10734 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010735 }
10736
10737 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010738 // BACKUP AND RESTORE
10739 // =========================================================
10740
10741 // Cause the target app to be launched if necessary and its backup agent
10742 // instantiated. The backup agent will invoke backupAgentCreated() on the
10743 // activity manager to announce its creation.
10744 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010745 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010746 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10747
10748 synchronized(this) {
10749 // !!! TODO: currently no check here that we're already bound
10750 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10751 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10752 synchronized (stats) {
10753 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10754 }
10755
Dianne Hackborne7f97212011-02-24 14:40:20 -080010756 // Backup agent is now in use, its package can't be stopped.
10757 try {
10758 AppGlobals.getPackageManager().setPackageStoppedState(
10759 app.packageName, false);
10760 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010761 } catch (IllegalArgumentException e) {
10762 Slog.w(TAG, "Failed trying to unstop package "
10763 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010764 }
10765
Christopher Tate181fafa2009-05-14 11:12:14 -070010766 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010767 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10768 ? new ComponentName(app.packageName, app.backupAgentName)
10769 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010770 // startProcessLocked() returns existing proc's record if it's already running
10771 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010772 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010773 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010774 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010775 return false;
10776 }
10777
10778 r.app = proc;
10779 mBackupTarget = r;
10780 mBackupAppName = app.packageName;
10781
Christopher Tate6fa95972009-06-05 18:43:55 -070010782 // Try not to kill the process during backup
10783 updateOomAdjLocked(proc);
10784
Christopher Tate181fafa2009-05-14 11:12:14 -070010785 // If the process is already attached, schedule the creation of the backup agent now.
10786 // If it is not yet live, this will be done when it attaches to the framework.
10787 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010788 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010789 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010790 proc.thread.scheduleCreateBackupAgent(app,
10791 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010792 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010793 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010794 }
10795 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010796 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010797 }
10798 // Invariants: at this point, the target app process exists and the application
10799 // is either already running or in the process of coming up. mBackupTarget and
10800 // mBackupAppName describe the app, so that when it binds back to the AM we
10801 // know that it's scheduled for a backup-agent operation.
10802 }
10803
10804 return true;
10805 }
10806
10807 // A backup agent has just come up
10808 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010809 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010810 + " = " + agent);
10811
10812 synchronized(this) {
10813 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010814 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010815 return;
10816 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010817 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010818
Dianne Hackborn06740692010-09-22 22:46:21 -070010819 long oldIdent = Binder.clearCallingIdentity();
10820 try {
10821 IBackupManager bm = IBackupManager.Stub.asInterface(
10822 ServiceManager.getService(Context.BACKUP_SERVICE));
10823 bm.agentConnected(agentPackageName, agent);
10824 } catch (RemoteException e) {
10825 // can't happen; the backup manager service is local
10826 } catch (Exception e) {
10827 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10828 e.printStackTrace();
10829 } finally {
10830 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010831 }
10832 }
10833
10834 // done with this agent
10835 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010836 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010837 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010838 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010839 return;
10840 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010841
10842 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010843 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010844 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010845 return;
10846 }
10847
Christopher Tate181fafa2009-05-14 11:12:14 -070010848 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010849 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010850 return;
10851 }
10852
Christopher Tate6fa95972009-06-05 18:43:55 -070010853 ProcessRecord proc = mBackupTarget.app;
10854 mBackupTarget = null;
10855 mBackupAppName = null;
10856
10857 // Not backing this app up any more; reset its OOM adjustment
10858 updateOomAdjLocked(proc);
10859
Christopher Tatec7b31e32009-06-10 15:49:30 -070010860 // If the app crashed during backup, 'thread' will be null here
10861 if (proc.thread != null) {
10862 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010863 proc.thread.scheduleDestroyBackupAgent(appInfo,
10864 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010865 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010866 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010867 e.printStackTrace();
10868 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010869 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010870 }
10871 }
10872 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010873 // BROADCASTS
10874 // =========================================================
10875
Josh Bartel7f208742010-02-25 11:01:44 -060010876 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010877 List cur) {
10878 final ContentResolver resolver = mContext.getContentResolver();
10879 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10880 if (list == null) {
10881 return cur;
10882 }
10883 int N = list.size();
10884 for (int i=0; i<N; i++) {
10885 Intent intent = list.get(i);
10886 if (filter.match(resolver, intent, true, TAG) >= 0) {
10887 if (cur == null) {
10888 cur = new ArrayList<Intent>();
10889 }
10890 cur.add(intent);
10891 }
10892 }
10893 return cur;
10894 }
10895
10896 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010897 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 + mBroadcastsScheduled);
10899
10900 if (mBroadcastsScheduled) {
10901 return;
10902 }
10903 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10904 mBroadcastsScheduled = true;
10905 }
10906
10907 public Intent registerReceiver(IApplicationThread caller,
10908 IIntentReceiver receiver, IntentFilter filter, String permission) {
10909 synchronized(this) {
10910 ProcessRecord callerApp = null;
10911 if (caller != null) {
10912 callerApp = getRecordForAppLocked(caller);
10913 if (callerApp == null) {
10914 throw new SecurityException(
10915 "Unable to find app for caller " + caller
10916 + " (pid=" + Binder.getCallingPid()
10917 + ") when registering receiver " + receiver);
10918 }
10919 }
10920
10921 List allSticky = null;
10922
10923 // Look for any matching sticky broadcasts...
10924 Iterator actions = filter.actionsIterator();
10925 if (actions != null) {
10926 while (actions.hasNext()) {
10927 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010928 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010929 }
10930 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010931 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010932 }
10933
10934 // The first sticky in the list is returned directly back to
10935 // the client.
10936 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10937
Joe Onorato8a9b2202010-02-26 18:56:32 -080010938 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010939 + ": " + sticky);
10940
10941 if (receiver == null) {
10942 return sticky;
10943 }
10944
10945 ReceiverList rl
10946 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10947 if (rl == null) {
10948 rl = new ReceiverList(this, callerApp,
10949 Binder.getCallingPid(),
10950 Binder.getCallingUid(), receiver);
10951 if (rl.app != null) {
10952 rl.app.receivers.add(rl);
10953 } else {
10954 try {
10955 receiver.asBinder().linkToDeath(rl, 0);
10956 } catch (RemoteException e) {
10957 return sticky;
10958 }
10959 rl.linkedToDeath = true;
10960 }
10961 mRegisteredReceivers.put(receiver.asBinder(), rl);
10962 }
10963 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10964 rl.add(bf);
10965 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010966 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 }
10968 mReceiverResolver.addFilter(bf);
10969
10970 // Enqueue broadcasts for all existing stickies that match
10971 // this filter.
10972 if (allSticky != null) {
10973 ArrayList receivers = new ArrayList();
10974 receivers.add(bf);
10975
10976 int N = allSticky.size();
10977 for (int i=0; i<N; i++) {
10978 Intent intent = (Intent)allSticky.get(i);
10979 BroadcastRecord r = new BroadcastRecord(intent, null,
10980 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010981 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010982 if (mParallelBroadcasts.size() == 0) {
10983 scheduleBroadcastsLocked();
10984 }
10985 mParallelBroadcasts.add(r);
10986 }
10987 }
10988
10989 return sticky;
10990 }
10991 }
10992
10993 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010994 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010995
10996 boolean doNext = false;
10997
10998 synchronized(this) {
10999 ReceiverList rl
11000 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11001 if (rl != null) {
11002 if (rl.curBroadcast != null) {
11003 BroadcastRecord r = rl.curBroadcast;
11004 doNext = finishReceiverLocked(
11005 receiver.asBinder(), r.resultCode, r.resultData,
11006 r.resultExtras, r.resultAbort, true);
11007 }
11008
11009 if (rl.app != null) {
11010 rl.app.receivers.remove(rl);
11011 }
11012 removeReceiverLocked(rl);
11013 if (rl.linkedToDeath) {
11014 rl.linkedToDeath = false;
11015 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11016 }
11017 }
11018 }
11019
11020 if (!doNext) {
11021 return;
11022 }
11023
11024 final long origId = Binder.clearCallingIdentity();
11025 processNextBroadcast(false);
11026 trimApplications();
11027 Binder.restoreCallingIdentity(origId);
11028 }
11029
11030 void removeReceiverLocked(ReceiverList rl) {
11031 mRegisteredReceivers.remove(rl.receiver.asBinder());
11032 int N = rl.size();
11033 for (int i=0; i<N; i++) {
11034 mReceiverResolver.removeFilter(rl.get(i));
11035 }
11036 }
11037
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011038 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11039 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11040 ProcessRecord r = mLruProcesses.get(i);
11041 if (r.thread != null) {
11042 try {
11043 r.thread.dispatchPackageBroadcast(cmd, packages);
11044 } catch (RemoteException ex) {
11045 }
11046 }
11047 }
11048 }
11049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 private final int broadcastIntentLocked(ProcessRecord callerApp,
11051 String callerPackage, Intent intent, String resolvedType,
11052 IIntentReceiver resultTo, int resultCode, String resultData,
11053 Bundle map, String requiredPermission,
11054 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11055 intent = new Intent(intent);
11056
Dianne Hackborne7f97212011-02-24 14:40:20 -080011057 // By default broadcasts do not go to stopped apps.
11058 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11059
Joe Onorato8a9b2202010-02-26 18:56:32 -080011060 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011061 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11062 + " ordered=" + ordered);
11063 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011064 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011065 }
11066
11067 // Handle special intents: if this broadcast is from the package
11068 // manager about a package being removed, we need to remove all of
11069 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011070 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011071 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011072 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11073 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011074 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011075 || uidRemoved) {
11076 if (checkComponentPermission(
11077 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011078 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011079 == PackageManager.PERMISSION_GRANTED) {
11080 if (uidRemoved) {
11081 final Bundle intentExtras = intent.getExtras();
11082 final int uid = intentExtras != null
11083 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11084 if (uid >= 0) {
11085 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11086 synchronized (bs) {
11087 bs.removeUidStatsLocked(uid);
11088 }
11089 }
11090 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011091 // If resources are unvailble just force stop all
11092 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011093 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011094 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11095 if (list != null && (list.length > 0)) {
11096 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011097 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011098 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011099 sendPackageBroadcastLocked(
11100 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011101 }
11102 } else {
11103 Uri data = intent.getData();
11104 String ssp;
11105 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11106 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11107 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011108 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011109 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011110 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011111 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11112 new String[] {ssp});
11113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011114 }
11115 }
11116 }
11117 } else {
11118 String msg = "Permission Denial: " + intent.getAction()
11119 + " broadcast from " + callerPackage + " (pid=" + callingPid
11120 + ", uid=" + callingUid + ")"
11121 + " requires "
11122 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011123 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011124 throw new SecurityException(msg);
11125 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011126
11127 // Special case for adding a package: by default turn on compatibility
11128 // mode.
11129 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11130 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
11131 Uri data = intent.getData();
11132 String ssp;
11133 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11134 mCompatModePackages.setPackageScreenCompatModeLocked(ssp,
11135 ActivityManager.COMPAT_MODE_ENABLED);
11136 }
11137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011138 }
11139
11140 /*
11141 * If this is the time zone changed action, queue up a message that will reset the timezone
11142 * of all currently running processes. This message will get queued up before the broadcast
11143 * happens.
11144 */
11145 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11146 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11147 }
11148
Robert Greenwalt03595d02010-11-02 14:08:23 -070011149 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11150 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11151 }
11152
Robert Greenwalt434203a2010-10-11 16:00:27 -070011153 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11154 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11155 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11156 }
11157
Dianne Hackborn854060af2009-07-09 18:14:31 -070011158 /*
11159 * Prevent non-system code (defined here to be non-persistent
11160 * processes) from sending protected broadcasts.
11161 */
11162 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11163 || callingUid == Process.SHELL_UID || callingUid == 0) {
11164 // Always okay.
11165 } else if (callerApp == null || !callerApp.persistent) {
11166 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011167 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011168 intent.getAction())) {
11169 String msg = "Permission Denial: not allowed to send broadcast "
11170 + intent.getAction() + " from pid="
11171 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011172 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011173 throw new SecurityException(msg);
11174 }
11175 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011176 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011177 return BROADCAST_SUCCESS;
11178 }
11179 }
11180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 // Add to the sticky list if requested.
11182 if (sticky) {
11183 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11184 callingPid, callingUid)
11185 != PackageManager.PERMISSION_GRANTED) {
11186 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11187 + callingPid + ", uid=" + callingUid
11188 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011189 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011190 throw new SecurityException(msg);
11191 }
11192 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011193 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011194 + " and enforce permission " + requiredPermission);
11195 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11196 }
11197 if (intent.getComponent() != null) {
11198 throw new SecurityException(
11199 "Sticky broadcasts can't target a specific component");
11200 }
11201 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11202 if (list == null) {
11203 list = new ArrayList<Intent>();
11204 mStickyBroadcasts.put(intent.getAction(), list);
11205 }
11206 int N = list.size();
11207 int i;
11208 for (i=0; i<N; i++) {
11209 if (intent.filterEquals(list.get(i))) {
11210 // This sticky already exists, replace it.
11211 list.set(i, new Intent(intent));
11212 break;
11213 }
11214 }
11215 if (i >= N) {
11216 list.add(new Intent(intent));
11217 }
11218 }
11219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011220 // Figure out who all will receive this broadcast.
11221 List receivers = null;
11222 List<BroadcastFilter> registeredReceivers = null;
11223 try {
11224 if (intent.getComponent() != null) {
11225 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011226 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011227 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011228 if (ai != null) {
11229 receivers = new ArrayList();
11230 ResolveInfo ri = new ResolveInfo();
11231 ri.activityInfo = ai;
11232 receivers.add(ri);
11233 }
11234 } else {
11235 // Need to resolve the intent to interested receivers...
11236 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11237 == 0) {
11238 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011239 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011240 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011241 }
Mihai Preda074edef2009-05-18 17:13:31 +020011242 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011243 }
11244 } catch (RemoteException ex) {
11245 // pm is in same process, this will never happen.
11246 }
11247
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011248 final boolean replacePending =
11249 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11250
Joe Onorato8a9b2202010-02-26 18:56:32 -080011251 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011252 + " replacePending=" + replacePending);
11253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011254 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11255 if (!ordered && NR > 0) {
11256 // If we are not serializing this broadcast, then send the
11257 // registered receivers separately so they don't wait for the
11258 // components to be launched.
11259 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11260 callerPackage, callingPid, callingUid, requiredPermission,
11261 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011262 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011263 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011264 TAG, "Enqueueing parallel broadcast " + r
11265 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011266 boolean replaced = false;
11267 if (replacePending) {
11268 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11269 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011270 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011271 "***** DROPPING PARALLEL: " + intent);
11272 mParallelBroadcasts.set(i, r);
11273 replaced = true;
11274 break;
11275 }
11276 }
11277 }
11278 if (!replaced) {
11279 mParallelBroadcasts.add(r);
11280 scheduleBroadcastsLocked();
11281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011282 registeredReceivers = null;
11283 NR = 0;
11284 }
11285
11286 // Merge into one list.
11287 int ir = 0;
11288 if (receivers != null) {
11289 // A special case for PACKAGE_ADDED: do not allow the package
11290 // being added to see this broadcast. This prevents them from
11291 // using this as a back door to get run as soon as they are
11292 // installed. Maybe in the future we want to have a special install
11293 // broadcast or such for apps, but we'd like to deliberately make
11294 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011295 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011296 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11297 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11298 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011299 Uri data = intent.getData();
11300 if (data != null) {
11301 String pkgName = data.getSchemeSpecificPart();
11302 if (pkgName != null) {
11303 skipPackages = new String[] { pkgName };
11304 }
11305 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011306 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011307 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011308 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011309 if (skipPackages != null && (skipPackages.length > 0)) {
11310 for (String skipPackage : skipPackages) {
11311 if (skipPackage != null) {
11312 int NT = receivers.size();
11313 for (int it=0; it<NT; it++) {
11314 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11315 if (curt.activityInfo.packageName.equals(skipPackage)) {
11316 receivers.remove(it);
11317 it--;
11318 NT--;
11319 }
11320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 }
11322 }
11323 }
11324
11325 int NT = receivers != null ? receivers.size() : 0;
11326 int it = 0;
11327 ResolveInfo curt = null;
11328 BroadcastFilter curr = null;
11329 while (it < NT && ir < NR) {
11330 if (curt == null) {
11331 curt = (ResolveInfo)receivers.get(it);
11332 }
11333 if (curr == null) {
11334 curr = registeredReceivers.get(ir);
11335 }
11336 if (curr.getPriority() >= curt.priority) {
11337 // Insert this broadcast record into the final list.
11338 receivers.add(it, curr);
11339 ir++;
11340 curr = null;
11341 it++;
11342 NT++;
11343 } else {
11344 // Skip to the next ResolveInfo in the final list.
11345 it++;
11346 curt = null;
11347 }
11348 }
11349 }
11350 while (ir < NR) {
11351 if (receivers == null) {
11352 receivers = new ArrayList();
11353 }
11354 receivers.add(registeredReceivers.get(ir));
11355 ir++;
11356 }
11357
11358 if ((receivers != null && receivers.size() > 0)
11359 || resultTo != null) {
11360 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11361 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011362 receivers, resultTo, resultCode, resultData, map, ordered,
11363 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011364 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011365 TAG, "Enqueueing ordered broadcast " + r
11366 + ": prev had " + mOrderedBroadcasts.size());
11367 if (DEBUG_BROADCAST) {
11368 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011369 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011370 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011371 boolean replaced = false;
11372 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011373 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011374 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011375 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011376 "***** DROPPING ORDERED: " + intent);
11377 mOrderedBroadcasts.set(i, r);
11378 replaced = true;
11379 break;
11380 }
11381 }
11382 }
11383 if (!replaced) {
11384 mOrderedBroadcasts.add(r);
11385 scheduleBroadcastsLocked();
11386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011387 }
11388
11389 return BROADCAST_SUCCESS;
11390 }
11391
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011392 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011393 // Refuse possible leaked file descriptors
11394 if (intent != null && intent.hasFileDescriptors() == true) {
11395 throw new IllegalArgumentException("File descriptors passed in Intent");
11396 }
11397
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011398 int flags = intent.getFlags();
11399
11400 if (!mProcessesReady) {
11401 // if the caller really truly claims to know what they're doing, go
11402 // ahead and allow the broadcast without launching any receivers
11403 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11404 intent = new Intent(intent);
11405 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11406 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11407 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11408 + " before boot completion");
11409 throw new IllegalStateException("Cannot broadcast before boot completed");
11410 }
11411 }
11412
11413 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11414 throw new IllegalArgumentException(
11415 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11416 }
11417
11418 return intent;
11419 }
11420
11421 public final int broadcastIntent(IApplicationThread caller,
11422 Intent intent, String resolvedType, IIntentReceiver resultTo,
11423 int resultCode, String resultData, Bundle map,
11424 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011425 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011426 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011428 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11429 final int callingPid = Binder.getCallingPid();
11430 final int callingUid = Binder.getCallingUid();
11431 final long origId = Binder.clearCallingIdentity();
11432 int res = broadcastIntentLocked(callerApp,
11433 callerApp != null ? callerApp.info.packageName : null,
11434 intent, resolvedType, resultTo,
11435 resultCode, resultData, map, requiredPermission, serialized,
11436 sticky, callingPid, callingUid);
11437 Binder.restoreCallingIdentity(origId);
11438 return res;
11439 }
11440 }
11441
11442 int broadcastIntentInPackage(String packageName, int uid,
11443 Intent intent, String resolvedType, IIntentReceiver resultTo,
11444 int resultCode, String resultData, Bundle map,
11445 String requiredPermission, boolean serialized, boolean sticky) {
11446 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011447 intent = verifyBroadcastLocked(intent);
11448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011449 final long origId = Binder.clearCallingIdentity();
11450 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11451 resultTo, resultCode, resultData, map, requiredPermission,
11452 serialized, sticky, -1, uid);
11453 Binder.restoreCallingIdentity(origId);
11454 return res;
11455 }
11456 }
11457
11458 public final void unbroadcastIntent(IApplicationThread caller,
11459 Intent intent) {
11460 // Refuse possible leaked file descriptors
11461 if (intent != null && intent.hasFileDescriptors() == true) {
11462 throw new IllegalArgumentException("File descriptors passed in Intent");
11463 }
11464
11465 synchronized(this) {
11466 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11467 != PackageManager.PERMISSION_GRANTED) {
11468 String msg = "Permission Denial: unbroadcastIntent() from pid="
11469 + Binder.getCallingPid()
11470 + ", uid=" + Binder.getCallingUid()
11471 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011472 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011473 throw new SecurityException(msg);
11474 }
11475 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11476 if (list != null) {
11477 int N = list.size();
11478 int i;
11479 for (i=0; i<N; i++) {
11480 if (intent.filterEquals(list.get(i))) {
11481 list.remove(i);
11482 break;
11483 }
11484 }
11485 }
11486 }
11487 }
11488
11489 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11490 String resultData, Bundle resultExtras, boolean resultAbort,
11491 boolean explicit) {
11492 if (mOrderedBroadcasts.size() == 0) {
11493 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011494 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011495 }
11496 return false;
11497 }
11498 BroadcastRecord r = mOrderedBroadcasts.get(0);
11499 if (r.receiver == null) {
11500 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011501 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011502 }
11503 return false;
11504 }
11505 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011506 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011507 return false;
11508 }
11509 int state = r.state;
11510 r.state = r.IDLE;
11511 if (state == r.IDLE) {
11512 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011513 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011514 }
11515 }
11516 r.receiver = null;
11517 r.intent.setComponent(null);
11518 if (r.curApp != null) {
11519 r.curApp.curReceiver = null;
11520 }
11521 if (r.curFilter != null) {
11522 r.curFilter.receiverList.curBroadcast = null;
11523 }
11524 r.curFilter = null;
11525 r.curApp = null;
11526 r.curComponent = null;
11527 r.curReceiver = null;
11528 mPendingBroadcast = null;
11529
11530 r.resultCode = resultCode;
11531 r.resultData = resultData;
11532 r.resultExtras = resultExtras;
11533 r.resultAbort = resultAbort;
11534
11535 // We will process the next receiver right now if this is finishing
11536 // an app receiver (which is always asynchronous) or after we have
11537 // come back from calling a receiver.
11538 return state == BroadcastRecord.APP_RECEIVE
11539 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11540 }
11541
11542 public void finishReceiver(IBinder who, int resultCode, String resultData,
11543 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011544 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011545
11546 // Refuse possible leaked file descriptors
11547 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11548 throw new IllegalArgumentException("File descriptors passed in Bundle");
11549 }
11550
11551 boolean doNext;
11552
11553 final long origId = Binder.clearCallingIdentity();
11554
11555 synchronized(this) {
11556 doNext = finishReceiverLocked(
11557 who, resultCode, resultData, resultExtras, resultAbort, true);
11558 }
11559
11560 if (doNext) {
11561 processNextBroadcast(false);
11562 }
11563 trimApplications();
11564
11565 Binder.restoreCallingIdentity(origId);
11566 }
11567
Jeff Brown4d94a762010-09-23 11:33:28 -070011568 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011569 if (r.nextReceiver > 0) {
11570 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11571 if (curReceiver instanceof BroadcastFilter) {
11572 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011573 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011574 System.identityHashCode(r),
11575 r.intent.getAction(),
11576 r.nextReceiver - 1,
11577 System.identityHashCode(bf));
11578 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011579 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011580 System.identityHashCode(r),
11581 r.intent.getAction(),
11582 r.nextReceiver - 1,
11583 ((ResolveInfo)curReceiver).toString());
11584 }
11585 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011586 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011588 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011589 System.identityHashCode(r),
11590 r.intent.getAction(),
11591 r.nextReceiver,
11592 "NONE");
11593 }
11594 }
11595
Jeff Brown4d94a762010-09-23 11:33:28 -070011596 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11597 if (! mPendingBroadcastTimeoutMessage) {
11598 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11599 mHandler.sendMessageAtTime(msg, timeoutTime);
11600 mPendingBroadcastTimeoutMessage = true;
11601 }
11602 }
11603
11604 private final void cancelBroadcastTimeoutLocked() {
11605 if (mPendingBroadcastTimeoutMessage) {
11606 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11607 mPendingBroadcastTimeoutMessage = false;
11608 }
11609 }
11610
11611 private final void broadcastTimeoutLocked(boolean fromMsg) {
11612 if (fromMsg) {
11613 mPendingBroadcastTimeoutMessage = false;
11614 }
11615
11616 if (mOrderedBroadcasts.size() == 0) {
11617 return;
11618 }
11619
11620 long now = SystemClock.uptimeMillis();
11621 BroadcastRecord r = mOrderedBroadcasts.get(0);
11622 if (fromMsg) {
11623 if (mDidDexOpt) {
11624 // Delay timeouts until dexopt finishes.
11625 mDidDexOpt = false;
11626 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11627 setBroadcastTimeoutLocked(timeoutTime);
11628 return;
11629 }
11630 if (! mProcessesReady) {
11631 // Only process broadcast timeouts if the system is ready. That way
11632 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11633 // to do heavy lifting for system up.
11634 return;
11635 }
11636
11637 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11638 if (timeoutTime > now) {
11639 // We can observe premature timeouts because we do not cancel and reset the
11640 // broadcast timeout message after each receiver finishes. Instead, we set up
11641 // an initial timeout then kick it down the road a little further as needed
11642 // when it expires.
11643 if (DEBUG_BROADCAST) Slog.v(TAG,
11644 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11645 + timeoutTime);
11646 setBroadcastTimeoutLocked(timeoutTime);
11647 return;
11648 }
11649 }
11650
11651 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11652 + ", started " + (now - r.receiverTime) + "ms ago");
11653 r.receiverTime = now;
11654 r.anrCount++;
11655
11656 // Current receiver has passed its expiration date.
11657 if (r.nextReceiver <= 0) {
11658 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11659 return;
11660 }
11661
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011662 ProcessRecord app = null;
11663 String anrMessage = null;
11664
Jeff Brown4d94a762010-09-23 11:33:28 -070011665 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11666 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11667 logBroadcastReceiverDiscardLocked(r);
11668 if (curReceiver instanceof BroadcastFilter) {
11669 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11670 if (bf.receiverList.pid != 0
11671 && bf.receiverList.pid != MY_PID) {
11672 synchronized (this.mPidsSelfLocked) {
11673 app = this.mPidsSelfLocked.get(
11674 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011676 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011677 } else {
11678 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011680
Jeff Brown4d94a762010-09-23 11:33:28 -070011681 if (app != null) {
11682 anrMessage = "Broadcast of " + r.intent.toString();
11683 }
11684
11685 if (mPendingBroadcast == r) {
11686 mPendingBroadcast = null;
11687 }
11688
11689 // Move on to the next receiver.
11690 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11691 r.resultExtras, r.resultAbort, true);
11692 scheduleBroadcastsLocked();
11693
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011694 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011695 // Post the ANR to the handler since we do not want to process ANRs while
11696 // potentially holding our lock.
11697 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011699 }
11700
11701 private final void processCurBroadcastLocked(BroadcastRecord r,
11702 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011703 if (DEBUG_BROADCAST) Slog.v(TAG,
11704 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011705 if (app.thread == null) {
11706 throw new RemoteException();
11707 }
11708 r.receiver = app.thread.asBinder();
11709 r.curApp = app;
11710 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011711 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011712
11713 // Tell the application to launch this receiver.
11714 r.intent.setComponent(r.curComponent);
11715
11716 boolean started = false;
11717 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011718 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011719 "Delivering to component " + r.curComponent
11720 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011721 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011722 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011723 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011724 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011725 if (DEBUG_BROADCAST) Slog.v(TAG,
11726 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011727 started = true;
11728 } finally {
11729 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011730 if (DEBUG_BROADCAST) Slog.v(TAG,
11731 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011732 r.receiver = null;
11733 r.curApp = null;
11734 app.curReceiver = null;
11735 }
11736 }
11737
11738 }
11739
Jeff Brown4d94a762010-09-23 11:33:28 -070011740 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011741 Intent intent, int resultCode, String data, Bundle extras,
11742 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011743 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011744 if (app != null && app.thread != null) {
11745 // If we have an app thread, do the call through that so it is
11746 // correctly ordered with other one-way calls.
11747 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011748 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011749 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011750 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 }
11752 }
11753
Jeff Brown4d94a762010-09-23 11:33:28 -070011754 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011755 BroadcastFilter filter, boolean ordered) {
11756 boolean skip = false;
11757 if (filter.requiredPermission != null) {
11758 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011759 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011761 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011762 + r.intent.toString()
11763 + " from " + r.callerPackage + " (pid="
11764 + r.callingPid + ", uid=" + r.callingUid + ")"
11765 + " requires " + filter.requiredPermission
11766 + " due to registered receiver " + filter);
11767 skip = true;
11768 }
11769 }
11770 if (r.requiredPermission != null) {
11771 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011772 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011773 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011774 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 + r.intent.toString()
11776 + " to " + filter.receiverList.app
11777 + " (pid=" + filter.receiverList.pid
11778 + ", uid=" + filter.receiverList.uid + ")"
11779 + " requires " + r.requiredPermission
11780 + " due to sender " + r.callerPackage
11781 + " (uid " + r.callingUid + ")");
11782 skip = true;
11783 }
11784 }
11785
11786 if (!skip) {
11787 // If this is not being sent as an ordered broadcast, then we
11788 // don't want to touch the fields that keep track of the current
11789 // state of ordered broadcasts.
11790 if (ordered) {
11791 r.receiver = filter.receiverList.receiver.asBinder();
11792 r.curFilter = filter;
11793 filter.receiverList.curBroadcast = r;
11794 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011795 if (filter.receiverList.app != null) {
11796 // Bump hosting application to no longer be in background
11797 // scheduling class. Note that we can't do that if there
11798 // isn't an app... but we can only be in that case for
11799 // things that directly call the IActivityManager API, which
11800 // are already core system stuff so don't matter for this.
11801 r.curApp = filter.receiverList.app;
11802 filter.receiverList.app.curReceiver = r;
11803 updateOomAdjLocked();
11804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011805 }
11806 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011807 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011808 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011809 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011810 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011811 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011812 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011813 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011814 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011815 if (ordered) {
11816 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11817 }
11818 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011819 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011820 if (ordered) {
11821 r.receiver = null;
11822 r.curFilter = null;
11823 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011824 if (filter.receiverList.app != null) {
11825 filter.receiverList.app.curReceiver = null;
11826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011827 }
11828 }
11829 }
11830 }
11831
Dianne Hackborn12527f92009-11-11 17:39:50 -080011832 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11833 if (r.callingUid < 0) {
11834 // This was from a registerReceiver() call; ignore it.
11835 return;
11836 }
11837 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11838 MAX_BROADCAST_HISTORY-1);
11839 r.finishTime = SystemClock.uptimeMillis();
11840 mBroadcastHistory[0] = r;
11841 }
11842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011843 private final void processNextBroadcast(boolean fromMsg) {
11844 synchronized(this) {
11845 BroadcastRecord r;
11846
Joe Onorato8a9b2202010-02-26 18:56:32 -080011847 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011848 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011849 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850
11851 updateCpuStats();
11852
11853 if (fromMsg) {
11854 mBroadcastsScheduled = false;
11855 }
11856
11857 // First, deliver any non-serialized broadcasts right away.
11858 while (mParallelBroadcasts.size() > 0) {
11859 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011860 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011861 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011862 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011863 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011864 for (int i=0; i<N; i++) {
11865 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011866 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011867 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011868 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011869 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011870 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011871 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011872 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011873 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011874 }
11875
11876 // Now take care of the next serialized one...
11877
11878 // If we are waiting for a process to come up to handle the next
11879 // broadcast, then do nothing at this point. Just in case, we
11880 // check that the process we're waiting for still exists.
11881 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011882 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011883 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011884 + mPendingBroadcast.curApp);
11885 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886
11887 boolean isDead;
11888 synchronized (mPidsSelfLocked) {
11889 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11890 }
11891 if (!isDead) {
11892 // It's still alive, so keep waiting
11893 return;
11894 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011895 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011896 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011897 mPendingBroadcast.state = BroadcastRecord.IDLE;
11898 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011899 mPendingBroadcast = null;
11900 }
11901 }
11902
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011903 boolean looped = false;
11904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011905 do {
11906 if (mOrderedBroadcasts.size() == 0) {
11907 // No more broadcasts pending, so all done!
11908 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011909 if (looped) {
11910 // If we had finished the last ordered broadcast, then
11911 // make sure all processes have correct oom and sched
11912 // adjustments.
11913 updateOomAdjLocked();
11914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011915 return;
11916 }
11917 r = mOrderedBroadcasts.get(0);
11918 boolean forceReceive = false;
11919
11920 // Ensure that even if something goes awry with the timeout
11921 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011922 // and continue to make progress.
11923 //
11924 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011925 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011926 // one time heavy lifting after system upgrades and can take
11927 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011928 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011929 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011930 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011931 if ((numReceivers > 0) &&
11932 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011933 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011934 + " now=" + now
11935 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011936 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011937 + " intent=" + r.intent
11938 + " numReceivers=" + numReceivers
11939 + " nextReceiver=" + r.nextReceiver
11940 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011941 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942 forceReceive = true;
11943 r.state = BroadcastRecord.IDLE;
11944 }
11945 }
11946
11947 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011948 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011949 "processNextBroadcast() called when not idle (state="
11950 + r.state + ")");
11951 return;
11952 }
11953
11954 if (r.receivers == null || r.nextReceiver >= numReceivers
11955 || r.resultAbort || forceReceive) {
11956 // No more receivers for this broadcast! Send the final
11957 // result if requested...
11958 if (r.resultTo != null) {
11959 try {
11960 if (DEBUG_BROADCAST) {
11961 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011962 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011963 + " seq=" + seq + " app=" + r.callerApp);
11964 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011965 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011966 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011967 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011968 // Set this to null so that the reference
11969 // (local and remote) isnt kept in the mBroadcastHistory.
11970 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011971 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011972 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011973 }
11974 }
11975
Joe Onorato8a9b2202010-02-26 18:56:32 -080011976 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011977 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011978
Joe Onorato8a9b2202010-02-26 18:56:32 -080011979 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011980 + r);
11981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011982 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011983 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011984 mOrderedBroadcasts.remove(0);
11985 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011986 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011987 continue;
11988 }
11989 } while (r == null);
11990
11991 // Get the next receiver...
11992 int recIdx = r.nextReceiver++;
11993
11994 // Keep track of when this receiver started, and make sure there
11995 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011996 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011997 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011998 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011999
Joe Onorato8a9b2202010-02-26 18:56:32 -080012000 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012001 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012002 }
12003 if (! mPendingBroadcastTimeoutMessage) {
12004 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012005 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012006 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12007 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012008 }
12009
12010 Object nextReceiver = r.receivers.get(recIdx);
12011 if (nextReceiver instanceof BroadcastFilter) {
12012 // Simple case: this is a registered receiver who gets
12013 // a direct call.
12014 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012015 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012016 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012017 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012018 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012019 if (r.receiver == null || !r.ordered) {
12020 // The receiver has already finished, so schedule to
12021 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012022 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12023 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012024 r.state = BroadcastRecord.IDLE;
12025 scheduleBroadcastsLocked();
12026 }
12027 return;
12028 }
12029
12030 // Hard case: need to instantiate the receiver, possibly
12031 // starting its application process to host it.
12032
12033 ResolveInfo info =
12034 (ResolveInfo)nextReceiver;
12035
12036 boolean skip = false;
12037 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012038 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12039 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012040 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012041 if (!info.activityInfo.exported) {
12042 Slog.w(TAG, "Permission Denial: broadcasting "
12043 + r.intent.toString()
12044 + " from " + r.callerPackage + " (pid=" + r.callingPid
12045 + ", uid=" + r.callingUid + ")"
12046 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12047 + " due to receiver " + info.activityInfo.packageName
12048 + "/" + info.activityInfo.name);
12049 } else {
12050 Slog.w(TAG, "Permission Denial: broadcasting "
12051 + r.intent.toString()
12052 + " from " + r.callerPackage + " (pid=" + r.callingPid
12053 + ", uid=" + r.callingUid + ")"
12054 + " requires " + info.activityInfo.permission
12055 + " due to receiver " + info.activityInfo.packageName
12056 + "/" + info.activityInfo.name);
12057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 skip = true;
12059 }
12060 if (r.callingUid != Process.SYSTEM_UID &&
12061 r.requiredPermission != null) {
12062 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012063 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012064 checkPermission(r.requiredPermission,
12065 info.activityInfo.applicationInfo.packageName);
12066 } catch (RemoteException e) {
12067 perm = PackageManager.PERMISSION_DENIED;
12068 }
12069 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012070 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 + r.intent + " to "
12072 + info.activityInfo.applicationInfo.packageName
12073 + " requires " + r.requiredPermission
12074 + " due to sender " + r.callerPackage
12075 + " (uid " + r.callingUid + ")");
12076 skip = true;
12077 }
12078 }
12079 if (r.curApp != null && r.curApp.crashing) {
12080 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012081 if (DEBUG_BROADCAST) Slog.v(TAG,
12082 "Skipping deliver ordered " + r + " to " + r.curApp
12083 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012084 skip = true;
12085 }
12086
12087 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012088 if (DEBUG_BROADCAST) Slog.v(TAG,
12089 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012090 r.receiver = null;
12091 r.curFilter = null;
12092 r.state = BroadcastRecord.IDLE;
12093 scheduleBroadcastsLocked();
12094 return;
12095 }
12096
12097 r.state = BroadcastRecord.APP_RECEIVE;
12098 String targetProcess = info.activityInfo.processName;
12099 r.curComponent = new ComponentName(
12100 info.activityInfo.applicationInfo.packageName,
12101 info.activityInfo.name);
12102 r.curReceiver = info.activityInfo;
12103
Dianne Hackborne7f97212011-02-24 14:40:20 -080012104 // Broadcast is being executed, its package can't be stopped.
12105 try {
12106 AppGlobals.getPackageManager().setPackageStoppedState(
12107 r.curComponent.getPackageName(), false);
12108 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012109 } catch (IllegalArgumentException e) {
12110 Slog.w(TAG, "Failed trying to unstop package "
12111 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012112 }
12113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114 // Is this receiver's application already running?
12115 ProcessRecord app = getProcessRecordLocked(targetProcess,
12116 info.activityInfo.applicationInfo.uid);
12117 if (app != null && app.thread != null) {
12118 try {
12119 processCurBroadcastLocked(r, app);
12120 return;
12121 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012122 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012123 + r.curComponent, e);
12124 }
12125
12126 // If a dead object exception was thrown -- fall through to
12127 // restart the application.
12128 }
12129
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012130 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012131 if (DEBUG_BROADCAST) Slog.v(TAG,
12132 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012133 if ((r.curApp=startProcessLocked(targetProcess,
12134 info.activityInfo.applicationInfo, true,
12135 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012136 "broadcast", r.curComponent,
12137 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12138 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139 // Ah, this recipient is unavailable. Finish it if necessary,
12140 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012141 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012142 + info.activityInfo.applicationInfo.packageName + "/"
12143 + info.activityInfo.applicationInfo.uid + " for broadcast "
12144 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012145 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12147 r.resultExtras, r.resultAbort, true);
12148 scheduleBroadcastsLocked();
12149 r.state = BroadcastRecord.IDLE;
12150 return;
12151 }
12152
12153 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012154 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012155 }
12156 }
12157
12158 // =========================================================
12159 // INSTRUMENTATION
12160 // =========================================================
12161
12162 public boolean startInstrumentation(ComponentName className,
12163 String profileFile, int flags, Bundle arguments,
12164 IInstrumentationWatcher watcher) {
12165 // Refuse possible leaked file descriptors
12166 if (arguments != null && arguments.hasFileDescriptors()) {
12167 throw new IllegalArgumentException("File descriptors passed in Bundle");
12168 }
12169
12170 synchronized(this) {
12171 InstrumentationInfo ii = null;
12172 ApplicationInfo ai = null;
12173 try {
12174 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012175 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012176 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012177 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012178 } catch (PackageManager.NameNotFoundException e) {
12179 }
12180 if (ii == null) {
12181 reportStartInstrumentationFailure(watcher, className,
12182 "Unable to find instrumentation info for: " + className);
12183 return false;
12184 }
12185 if (ai == null) {
12186 reportStartInstrumentationFailure(watcher, className,
12187 "Unable to find instrumentation target package: " + ii.targetPackage);
12188 return false;
12189 }
12190
12191 int match = mContext.getPackageManager().checkSignatures(
12192 ii.targetPackage, ii.packageName);
12193 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12194 String msg = "Permission Denial: starting instrumentation "
12195 + className + " from pid="
12196 + Binder.getCallingPid()
12197 + ", uid=" + Binder.getCallingPid()
12198 + " not allowed because package " + ii.packageName
12199 + " does not have a signature matching the target "
12200 + ii.targetPackage;
12201 reportStartInstrumentationFailure(watcher, className, msg);
12202 throw new SecurityException(msg);
12203 }
12204
12205 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012206 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012207 ProcessRecord app = addAppLocked(ai);
12208 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012209 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012210 app.instrumentationProfileFile = profileFile;
12211 app.instrumentationArguments = arguments;
12212 app.instrumentationWatcher = watcher;
12213 app.instrumentationResultClass = className;
12214 Binder.restoreCallingIdentity(origId);
12215 }
12216
12217 return true;
12218 }
12219
12220 /**
12221 * Report errors that occur while attempting to start Instrumentation. Always writes the
12222 * error to the logs, but if somebody is watching, send the report there too. This enables
12223 * the "am" command to report errors with more information.
12224 *
12225 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12226 * @param cn The component name of the instrumentation.
12227 * @param report The error report.
12228 */
12229 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12230 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012231 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012232 try {
12233 if (watcher != null) {
12234 Bundle results = new Bundle();
12235 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12236 results.putString("Error", report);
12237 watcher.instrumentationStatus(cn, -1, results);
12238 }
12239 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012240 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012241 }
12242 }
12243
12244 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12245 if (app.instrumentationWatcher != null) {
12246 try {
12247 // NOTE: IInstrumentationWatcher *must* be oneway here
12248 app.instrumentationWatcher.instrumentationFinished(
12249 app.instrumentationClass,
12250 resultCode,
12251 results);
12252 } catch (RemoteException e) {
12253 }
12254 }
12255 app.instrumentationWatcher = null;
12256 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012257 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012258 app.instrumentationProfileFile = null;
12259 app.instrumentationArguments = null;
12260
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012261 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012262 }
12263
12264 public void finishInstrumentation(IApplicationThread target,
12265 int resultCode, Bundle results) {
12266 // Refuse possible leaked file descriptors
12267 if (results != null && results.hasFileDescriptors()) {
12268 throw new IllegalArgumentException("File descriptors passed in Intent");
12269 }
12270
12271 synchronized(this) {
12272 ProcessRecord app = getRecordForAppLocked(target);
12273 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012274 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012275 return;
12276 }
12277 final long origId = Binder.clearCallingIdentity();
12278 finishInstrumentationLocked(app, resultCode, results);
12279 Binder.restoreCallingIdentity(origId);
12280 }
12281 }
12282
12283 // =========================================================
12284 // CONFIGURATION
12285 // =========================================================
12286
12287 public ConfigurationInfo getDeviceConfigurationInfo() {
12288 ConfigurationInfo config = new ConfigurationInfo();
12289 synchronized (this) {
12290 config.reqTouchScreen = mConfiguration.touchscreen;
12291 config.reqKeyboardType = mConfiguration.keyboard;
12292 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012293 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12294 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012295 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12296 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012297 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12298 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012299 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12300 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012301 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012302 }
12303 return config;
12304 }
12305
12306 public Configuration getConfiguration() {
12307 Configuration ci;
12308 synchronized(this) {
12309 ci = new Configuration(mConfiguration);
12310 }
12311 return ci;
12312 }
12313
12314 public void updateConfiguration(Configuration values) {
12315 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12316 "updateConfiguration()");
12317
12318 synchronized(this) {
12319 if (values == null && mWindowManager != null) {
12320 // sentinel: fetch the current configuration from the window manager
12321 values = mWindowManager.computeNewConfiguration();
12322 }
12323
12324 final long origId = Binder.clearCallingIdentity();
12325 updateConfigurationLocked(values, null);
12326 Binder.restoreCallingIdentity(origId);
12327 }
12328 }
12329
12330 /**
12331 * Do either or both things: (1) change the current configuration, and (2)
12332 * make sure the given activity is running with the (now) current
12333 * configuration. Returns true if the activity has been left running, or
12334 * false if <var>starting</var> is being destroyed to match the new
12335 * configuration.
12336 */
12337 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012338 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012339 int changes = 0;
12340
12341 boolean kept = true;
12342
12343 if (values != null) {
12344 Configuration newConfig = new Configuration(mConfiguration);
12345 changes = newConfig.updateFrom(values);
12346 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012347 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012348 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349 }
12350
Doug Zongker2bec3d42009-12-04 12:52:44 -080012351 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012352
12353 if (values.locale != null) {
12354 saveLocaleLocked(values.locale,
12355 !values.locale.equals(mConfiguration.locale),
12356 values.userSetLocale);
12357 }
12358
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012359 mConfigurationSeq++;
12360 if (mConfigurationSeq <= 0) {
12361 mConfigurationSeq = 1;
12362 }
12363 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012365 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012366
12367 AttributeCache ac = AttributeCache.instance();
12368 if (ac != null) {
12369 ac.updateConfiguration(mConfiguration);
12370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012372 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12373 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12374 msg.obj = new Configuration(mConfiguration);
12375 mHandler.sendMessage(msg);
12376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012377
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012378 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12379 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012380 try {
12381 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012382 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012383 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012384 app.thread.scheduleConfigurationChanged(mConfiguration);
12385 }
12386 } catch (Exception e) {
12387 }
12388 }
12389 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012390 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12391 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012392 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12393 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012394 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12395 broadcastIntentLocked(null, null,
12396 new Intent(Intent.ACTION_LOCALE_CHANGED),
12397 null, null, 0, null, null,
12398 null, false, false, MY_PID, Process.SYSTEM_UID);
12399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012400 }
12401 }
12402
12403 if (changes != 0 && starting == null) {
12404 // If the configuration changed, and the caller is not already
12405 // in the process of starting an activity, then find the top
12406 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012407 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012408 }
12409
12410 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012411 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012412 // And we need to make sure at this point that all other activities
12413 // are made visible with the correct configuration.
12414 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012415 }
12416
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012417 if (values != null && mWindowManager != null) {
12418 mWindowManager.setNewConfiguration(mConfiguration);
12419 }
12420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012421 return kept;
12422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012423
12424 /**
12425 * Save the locale. You must be inside a synchronized (this) block.
12426 */
12427 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12428 if(isDiff) {
12429 SystemProperties.set("user.language", l.getLanguage());
12430 SystemProperties.set("user.region", l.getCountry());
12431 }
12432
12433 if(isPersist) {
12434 SystemProperties.set("persist.sys.language", l.getLanguage());
12435 SystemProperties.set("persist.sys.country", l.getCountry());
12436 SystemProperties.set("persist.sys.localevar", l.getVariant());
12437 }
12438 }
12439
12440 // =========================================================
12441 // LIFETIME MANAGEMENT
12442 // =========================================================
12443
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012444 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12445 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012446 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012447 // This adjustment has already been computed. If we are calling
12448 // from the top, we may have already computed our adjustment with
12449 // an earlier hidden adjustment that isn't really for us... if
12450 // so, use the new hidden adjustment.
12451 if (!recursed && app.hidden) {
12452 app.curAdj = hiddenAdj;
12453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012454 return app.curAdj;
12455 }
12456
12457 if (app.thread == null) {
12458 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012459 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012460 return (app.curAdj=EMPTY_APP_ADJ);
12461 }
12462
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012463 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12464 // The max adjustment doesn't allow this app to be anything
12465 // below foreground, so it is not worth doing work for it.
12466 app.adjType = "fixed";
12467 app.adjSeq = mAdjSeq;
12468 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012469 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012470 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12471 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012472 }
12473
12474 final boolean hadForegroundActivities = app.foregroundActivities;
12475
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012476 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012477 app.adjSource = null;
12478 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012479 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012480 app.empty = false;
12481 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012482 app.foregroundActivities = false;
12483
12484 final int activitiesSize = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012485
The Android Open Source Project4df24232009-03-05 14:34:35 -080012486 // Determine the importance of the process, starting with most
12487 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012488 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012489 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012490 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012491 // The last app on the list is the foreground app.
12492 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012493 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012494 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012495 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012496 } else if (app.instrumentationClass != null) {
12497 // Don't want to kill running instrumentation.
12498 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012499 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012500 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012501 } else if (app.curReceiver != null ||
12502 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12503 // An app that is currently receiving a broadcast also
12504 // counts as being in the foreground.
12505 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012506 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012507 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012508 } else if (app.executingServices.size() > 0) {
12509 // An app that is currently executing a service callback also
12510 // counts as being in the foreground.
12511 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012512 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012513 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012514 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012515 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012516 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012517 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012518 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012519 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012520 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012521 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012522 // A very not-needed process. If this is lower in the lru list,
12523 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012524 adj = hiddenAdj;
12525 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012526 app.hidden = true;
12527 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012528 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012529 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012530
12531 // Examine all activities if not already foreground.
12532 if (!app.foregroundActivities && activitiesSize > 0) {
12533 for (int j = 0; j < activitiesSize; j++) {
12534 final ActivityRecord r = app.activities.get(j);
12535 if (r.visible) {
12536 // App has a visible activity; only upgrade adjustment.
12537 if (adj > VISIBLE_APP_ADJ) {
12538 adj = VISIBLE_APP_ADJ;
12539 app.adjType = "visible";
12540 }
12541 schedGroup = Process.THREAD_GROUP_DEFAULT;
12542 app.hidden = false;
12543 app.foregroundActivities = true;
12544 break;
12545 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12546 || r.state == ActivityState.STOPPING) {
12547 // Only upgrade adjustment.
12548 if (adj > PERCEPTIBLE_APP_ADJ) {
12549 adj = PERCEPTIBLE_APP_ADJ;
12550 app.adjType = "stopping";
12551 }
12552 app.foregroundActivities = true;
12553 }
12554 }
12555 }
12556
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012557 if (adj > PERCEPTIBLE_APP_ADJ) {
12558 if (app.foregroundServices) {
12559 // The user is aware of this app, so make it visible.
12560 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012561 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012562 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012563 } else if (app.forcingToForeground != null) {
12564 // The user is aware of this app, so make it visible.
12565 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012566 app.adjType = "force-foreground";
12567 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012568 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012569 }
12570 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012571
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012572 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12573 // We don't want to kill the current heavy-weight process.
12574 adj = HEAVY_WEIGHT_APP_ADJ;
12575 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12576 app.adjType = "heavy";
12577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012578
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012579 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12580 // This process is hosting what we currently consider to be the
12581 // home app, so we don't want to let it go into the background.
12582 adj = HOME_APP_ADJ;
12583 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12584 app.adjType = "home";
12585 }
12586
Joe Onorato8a9b2202010-02-26 18:56:32 -080012587 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012588
The Android Open Source Project4df24232009-03-05 14:34:35 -080012589 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012590 // there are applications dependent on our services or providers, but
12591 // this gives us a baseline and makes sure we don't get into an
12592 // infinite recursion.
12593 app.adjSeq = mAdjSeq;
12594 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012595
Christopher Tate6fa95972009-06-05 18:43:55 -070012596 if (mBackupTarget != null && app == mBackupTarget.app) {
12597 // If possible we want to avoid killing apps while they're being backed up
12598 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012599 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012600 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012601 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012602 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012603 }
12604 }
12605
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012606 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12607 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012608 final long now = SystemClock.uptimeMillis();
12609 // This process is more important if the top activity is
12610 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012611 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012612 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012613 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012614 if (s.startRequested) {
12615 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12616 // This service has seen some activity within
12617 // recent memory, so we will keep its process ahead
12618 // of the background processes.
12619 if (adj > SECONDARY_SERVER_ADJ) {
12620 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012621 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012622 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012623 }
12624 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012625 // If we have let the service slide into the background
12626 // state, still have some text describing what it is doing
12627 // even though the service no longer has an impact.
12628 if (adj > SECONDARY_SERVER_ADJ) {
12629 app.adjType = "started-bg-services";
12630 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012631 // Don't kill this process because it is doing work; it
12632 // has said it is doing work.
12633 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012634 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012635 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12636 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012637 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012638 = s.connections.values().iterator();
12639 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012640 ArrayList<ConnectionRecord> clist = kt.next();
12641 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12642 // XXX should compute this based on the max of
12643 // all connected clients.
12644 ConnectionRecord cr = clist.get(i);
12645 if (cr.binding.client == app) {
12646 // Binding to ourself is not interesting.
12647 continue;
12648 }
12649 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12650 ProcessRecord client = cr.binding.client;
12651 int myHiddenAdj = hiddenAdj;
12652 if (myHiddenAdj > client.hiddenAdj) {
12653 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12654 myHiddenAdj = client.hiddenAdj;
12655 } else {
12656 myHiddenAdj = VISIBLE_APP_ADJ;
12657 }
12658 }
12659 int clientAdj = computeOomAdjLocked(
12660 client, myHiddenAdj, TOP_APP, true);
12661 if (adj > clientAdj) {
12662 adj = clientAdj >= VISIBLE_APP_ADJ
12663 ? clientAdj : VISIBLE_APP_ADJ;
12664 if (!client.hidden) {
12665 app.hidden = false;
12666 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012667 if (client.keeping) {
12668 app.keeping = true;
12669 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012670 app.adjType = "service";
12671 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12672 .REASON_SERVICE_IN_USE;
12673 app.adjSource = cr.binding.client;
12674 app.adjTarget = s.name;
12675 }
12676 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12677 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12678 schedGroup = Process.THREAD_GROUP_DEFAULT;
12679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012680 }
12681 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012682 ActivityRecord a = cr.activity;
12683 //if (a != null) {
12684 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12685 //}
12686 if (a != null && adj > FOREGROUND_APP_ADJ &&
12687 (a.state == ActivityState.RESUMED
12688 || a.state == ActivityState.PAUSING)) {
12689 adj = FOREGROUND_APP_ADJ;
12690 schedGroup = Process.THREAD_GROUP_DEFAULT;
12691 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012692 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012693 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12694 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012695 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012696 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012698 }
12699 }
12700 }
12701 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012702
Dianne Hackborn287952c2010-09-22 22:34:31 -070012703 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012704 // would like to avoid killing it unless it would prevent the current
12705 // application from running. By default we put the process in
12706 // with the rest of the background processes; as we scan through
12707 // its services we may bump it up from there.
12708 if (adj > hiddenAdj) {
12709 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012710 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012711 app.adjType = "bg-services";
12712 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012713 }
12714
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012715 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12716 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012717 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012718 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12719 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012720 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012721 if (cpr.clients.size() != 0) {
12722 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12723 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12724 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012725 if (client == app) {
12726 // Being our own client is not interesting.
12727 continue;
12728 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012729 int myHiddenAdj = hiddenAdj;
12730 if (myHiddenAdj > client.hiddenAdj) {
12731 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12732 myHiddenAdj = client.hiddenAdj;
12733 } else {
12734 myHiddenAdj = FOREGROUND_APP_ADJ;
12735 }
12736 }
12737 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012738 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012739 if (adj > clientAdj) {
12740 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012741 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012742 if (!client.hidden) {
12743 app.hidden = false;
12744 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012745 if (client.keeping) {
12746 app.keeping = true;
12747 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012748 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012749 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12750 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012751 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012752 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012754 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12755 schedGroup = Process.THREAD_GROUP_DEFAULT;
12756 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012757 }
12758 }
12759 // If the provider has external (non-framework) process
12760 // dependencies, ensure that its adjustment is at least
12761 // FOREGROUND_APP_ADJ.
12762 if (cpr.externals != 0) {
12763 if (adj > FOREGROUND_APP_ADJ) {
12764 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012765 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012766 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012767 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012768 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012769 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012770 }
12771 }
12772 }
12773 }
12774
12775 app.curRawAdj = adj;
12776
Joe Onorato8a9b2202010-02-26 18:56:32 -080012777 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012778 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12779 if (adj > app.maxAdj) {
12780 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012781 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012782 schedGroup = Process.THREAD_GROUP_DEFAULT;
12783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012784 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012785 if (adj < HIDDEN_APP_MIN_ADJ) {
12786 app.keeping = true;
12787 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012788
12789 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012790 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012791
12792 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkeya4620792011-05-20 15:29:23 -070012793 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED,
12794 app.foregroundActivities ? 1 : 0, 0, app).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012795 }
12796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012797 return adj;
12798 }
12799
12800 /**
12801 * Ask a given process to GC right now.
12802 */
12803 final void performAppGcLocked(ProcessRecord app) {
12804 try {
12805 app.lastRequestedGc = SystemClock.uptimeMillis();
12806 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012807 if (app.reportLowMemory) {
12808 app.reportLowMemory = false;
12809 app.thread.scheduleLowMemory();
12810 } else {
12811 app.thread.processInBackground();
12812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012813 }
12814 } catch (Exception e) {
12815 // whatever.
12816 }
12817 }
12818
12819 /**
12820 * Returns true if things are idle enough to perform GCs.
12821 */
Josh Bartel7f208742010-02-25 11:01:44 -060012822 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012823 return mParallelBroadcasts.size() == 0
12824 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012825 && (mSleeping || (mMainStack.mResumedActivity != null &&
12826 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012827 }
12828
12829 /**
12830 * Perform GCs on all processes that are waiting for it, but only
12831 * if things are idle.
12832 */
12833 final void performAppGcsLocked() {
12834 final int N = mProcessesToGc.size();
12835 if (N <= 0) {
12836 return;
12837 }
Josh Bartel7f208742010-02-25 11:01:44 -060012838 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012839 while (mProcessesToGc.size() > 0) {
12840 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012841 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012842 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12843 <= SystemClock.uptimeMillis()) {
12844 // To avoid spamming the system, we will GC processes one
12845 // at a time, waiting a few seconds between each.
12846 performAppGcLocked(proc);
12847 scheduleAppGcsLocked();
12848 return;
12849 } else {
12850 // It hasn't been long enough since we last GCed this
12851 // process... put it in the list to wait for its time.
12852 addProcessToGcListLocked(proc);
12853 break;
12854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012855 }
12856 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012857
12858 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 }
12860 }
12861
12862 /**
12863 * If all looks good, perform GCs on all processes waiting for them.
12864 */
12865 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012866 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012867 performAppGcsLocked();
12868 return;
12869 }
12870 // Still not idle, wait some more.
12871 scheduleAppGcsLocked();
12872 }
12873
12874 /**
12875 * Schedule the execution of all pending app GCs.
12876 */
12877 final void scheduleAppGcsLocked() {
12878 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012879
12880 if (mProcessesToGc.size() > 0) {
12881 // Schedule a GC for the time to the next process.
12882 ProcessRecord proc = mProcessesToGc.get(0);
12883 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12884
12885 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12886 long now = SystemClock.uptimeMillis();
12887 if (when < (now+GC_TIMEOUT)) {
12888 when = now + GC_TIMEOUT;
12889 }
12890 mHandler.sendMessageAtTime(msg, when);
12891 }
12892 }
12893
12894 /**
12895 * Add a process to the array of processes waiting to be GCed. Keeps the
12896 * list in sorted order by the last GC time. The process can't already be
12897 * on the list.
12898 */
12899 final void addProcessToGcListLocked(ProcessRecord proc) {
12900 boolean added = false;
12901 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12902 if (mProcessesToGc.get(i).lastRequestedGc <
12903 proc.lastRequestedGc) {
12904 added = true;
12905 mProcessesToGc.add(i+1, proc);
12906 break;
12907 }
12908 }
12909 if (!added) {
12910 mProcessesToGc.add(0, proc);
12911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012912 }
12913
12914 /**
12915 * Set up to ask a process to GC itself. This will either do it
12916 * immediately, or put it on the list of processes to gc the next
12917 * time things are idle.
12918 */
12919 final void scheduleAppGcLocked(ProcessRecord app) {
12920 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012921 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012922 return;
12923 }
12924 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012925 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012926 scheduleAppGcsLocked();
12927 }
12928 }
12929
Dianne Hackborn287952c2010-09-22 22:34:31 -070012930 final void checkExcessivePowerUsageLocked(boolean doKills) {
12931 updateCpuStatsNow();
12932
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012933 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012934 boolean doWakeKills = doKills;
12935 boolean doCpuKills = doKills;
12936 if (mLastPowerCheckRealtime == 0) {
12937 doWakeKills = false;
12938 }
12939 if (mLastPowerCheckUptime == 0) {
12940 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012941 }
12942 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012943 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012944 }
12945 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012946 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12947 final long curUptime = SystemClock.uptimeMillis();
12948 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12949 mLastPowerCheckRealtime = curRealtime;
12950 mLastPowerCheckUptime = curUptime;
12951 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12952 doWakeKills = false;
12953 }
12954 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12955 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012956 }
12957 int i = mLruProcesses.size();
12958 while (i > 0) {
12959 i--;
12960 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012961 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012962 long wtime;
12963 synchronized (stats) {
12964 wtime = stats.getProcessWakeTime(app.info.uid,
12965 app.pid, curRealtime);
12966 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012967 long wtimeUsed = wtime - app.lastWakeTime;
12968 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12969 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012970 StringBuilder sb = new StringBuilder(128);
12971 sb.append("Wake for ");
12972 app.toShortString(sb);
12973 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012974 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012975 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012976 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012977 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012978 sb.append((wtimeUsed*100)/realtimeSince);
12979 sb.append("%)");
12980 Slog.i(TAG, sb.toString());
12981 sb.setLength(0);
12982 sb.append("CPU for ");
12983 app.toShortString(sb);
12984 sb.append(": over ");
12985 TimeUtils.formatDuration(uptimeSince, sb);
12986 sb.append(" used ");
12987 TimeUtils.formatDuration(cputimeUsed, sb);
12988 sb.append(" (");
12989 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012990 sb.append("%)");
12991 Slog.i(TAG, sb.toString());
12992 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012993 // If a process has held a wake lock for more
12994 // than 50% of the time during this period,
12995 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012996 if (doWakeKills && realtimeSince > 0
12997 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12998 synchronized (stats) {
12999 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13000 realtimeSince, wtimeUsed);
13001 }
13002 Slog.w(TAG, "Excessive wake lock in " + app.processName
13003 + " (pid " + app.pid + "): held " + wtimeUsed
13004 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013005 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13006 app.processName, app.setAdj, "excessive wake lock");
13007 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013008 } else if (doCpuKills && uptimeSince > 0
13009 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13010 synchronized (stats) {
13011 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13012 uptimeSince, cputimeUsed);
13013 }
13014 Slog.w(TAG, "Excessive CPU in " + app.processName
13015 + " (pid " + app.pid + "): used " + cputimeUsed
13016 + " during " + uptimeSince);
13017 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13018 app.processName, app.setAdj, "excessive cpu");
13019 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013020 } else {
13021 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013022 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013023 }
13024 }
13025 }
13026 }
13027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013028 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013029 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013030 app.hiddenAdj = hiddenAdj;
13031
13032 if (app.thread == null) {
13033 return true;
13034 }
13035
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013036 boolean success = true;
13037
Dianne Hackborn287952c2010-09-22 22:34:31 -070013038 final boolean wasKeeping = app.keeping;
13039
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013040 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013041
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013042 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013043 if (app.curRawAdj != app.setRawAdj) {
13044 if (app.curRawAdj > FOREGROUND_APP_ADJ
13045 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13046 // If this app is transitioning from foreground to
13047 // non-foreground, have it do a gc.
13048 scheduleAppGcLocked(app);
13049 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13050 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13051 // Likewise do a gc when an app is moving in to the
13052 // background (such as a service stopping).
13053 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013054 }
13055
13056 if (wasKeeping && !app.keeping) {
13057 // This app is no longer something we want to keep. Note
13058 // its current wake lock time to later know to kill it if
13059 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013060 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13061 synchronized (stats) {
13062 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13063 app.pid, SystemClock.elapsedRealtime());
13064 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013065 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013066 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013068 app.setRawAdj = app.curRawAdj;
13069 }
13070 if (adj != app.setAdj) {
13071 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013072 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013073 TAG, "Set app " + app.processName +
13074 " oom adj to " + adj);
13075 app.setAdj = adj;
13076 } else {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013077 success = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013078 }
13079 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013080 if (app.setSchedGroup != app.curSchedGroup) {
13081 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013082 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013083 "Setting process group of " + app.processName
13084 + " to " + app.curSchedGroup);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013085 if (app.waitingToKill != null &&
13086 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13087 Slog.i(TAG, "Killing " + app + ": " + app.waitingToKill);
13088 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13089 app.processName, app.setAdj, app.waitingToKill);
13090 Process.killProcessQuiet(app.pid);
13091 } else {
13092 if (true) {
13093 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013094 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013095 Process.setProcessGroup(app.pid, app.curSchedGroup);
13096 } catch (Exception e) {
13097 Slog.w(TAG, "Failed setting process group of " + app.pid
13098 + " to " + app.curSchedGroup);
13099 e.printStackTrace();
13100 } finally {
13101 Binder.restoreCallingIdentity(oldId);
13102 }
13103 }
13104 if (false) {
13105 if (app.thread != null) {
13106 try {
13107 app.thread.setSchedulingGroup(app.curSchedGroup);
13108 } catch (RemoteException e) {
13109 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013110 }
13111 }
13112 }
13113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013114 }
13115
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013116 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013117 }
13118
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013119 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013120 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013121 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013122 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013123 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013124 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013125 }
13126 }
13127 return resumedActivity;
13128 }
13129
13130 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013131 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013132 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13133 int curAdj = app.curAdj;
13134 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13135 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13136
13137 mAdjSeq++;
13138
13139 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13140 if (res) {
13141 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13142 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13143 if (nowHidden != wasHidden) {
13144 // Changed to/from hidden state, so apps after it in the LRU
13145 // list may also be changed.
13146 updateOomAdjLocked();
13147 }
13148 }
13149 return res;
13150 }
13151
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013152 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013153 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013154 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13156
13157 if (false) {
13158 RuntimeException e = new RuntimeException();
13159 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013160 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013161 }
13162
13163 mAdjSeq++;
13164
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013165 // Let's determine how many processes we have running vs.
13166 // how many slots we have for background processes; we may want
13167 // to put multiple processes in a slot of there are enough of
13168 // them.
13169 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
13170 int factor = (mLruProcesses.size()-4)/numSlots;
13171 if (factor < 1) factor = 1;
13172 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013173 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013175 // First try updating the OOM adjustment for each of the
13176 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013177 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013178 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13179 while (i > 0) {
13180 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013181 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013182 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013183 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013184 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013185 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013186 step++;
13187 if (step >= factor) {
13188 step = 0;
13189 curHiddenAdj++;
13190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013191 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013192 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070013193 if (!app.killedBackground) {
13194 numHidden++;
13195 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070013196 Slog.i(TAG, "No longer want " + app.processName
13197 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013198 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13199 app.processName, app.setAdj, "too many background");
13200 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070013201 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013202 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013203 }
13204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013205 } else {
13206 didOomAdj = false;
13207 }
13208 }
13209
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013210 // If we return false, we will fall back on killing processes to
13211 // have a fixed limit. Do this if a limit has been requested; else
13212 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013213 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13214 }
13215
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013216 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013217 synchronized (this) {
13218 int i;
13219
13220 // First remove any unused application processes whose package
13221 // has been removed.
13222 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13223 final ProcessRecord app = mRemovedProcesses.get(i);
13224 if (app.activities.size() == 0
13225 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013226 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013227 TAG, "Exiting empty application process "
13228 + app.processName + " ("
13229 + (app.thread != null ? app.thread.asBinder() : null)
13230 + ")\n");
13231 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013232 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13233 app.processName, app.setAdj, "empty");
13234 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013235 } else {
13236 try {
13237 app.thread.scheduleExit();
13238 } catch (Exception e) {
13239 // Ignore exceptions.
13240 }
13241 }
13242 cleanUpApplicationRecordLocked(app, false, -1);
13243 mRemovedProcesses.remove(i);
13244
13245 if (app.persistent) {
13246 if (app.persistent) {
13247 addAppLocked(app.info);
13248 }
13249 }
13250 }
13251 }
13252
13253 // Now try updating the OOM adjustment for each of the
13254 // application processes based on their current state.
13255 // If the setOomAdj() API is not supported, then go with our
13256 // back-up plan...
13257 if (!updateOomAdjLocked()) {
13258
13259 // Count how many processes are running services.
13260 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013261 for (i=mLruProcesses.size()-1; i>=0; i--) {
13262 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013263
13264 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013265 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013266 // Don't count processes holding services against our
13267 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013268 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013269 TAG, "Not trimming app " + app + " with services: "
13270 + app.services);
13271 numServiceProcs++;
13272 }
13273 }
13274
13275 int curMaxProcs = mProcessLimit;
13276 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13277 if (mAlwaysFinishActivities) {
13278 curMaxProcs = 1;
13279 }
13280 curMaxProcs += numServiceProcs;
13281
13282 // Quit as many processes as we can to get down to the desired
13283 // process count. First remove any processes that no longer
13284 // have activites running in them.
13285 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013286 i<mLruProcesses.size()
13287 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013288 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013289 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013290 // Quit an application only if it is not currently
13291 // running any activities.
13292 if (!app.persistent && app.activities.size() == 0
13293 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013294 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013295 TAG, "Exiting empty application process "
13296 + app.processName + " ("
13297 + (app.thread != null ? app.thread.asBinder() : null)
13298 + ")\n");
13299 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013300 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13301 app.processName, app.setAdj, "empty");
13302 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013303 } else {
13304 try {
13305 app.thread.scheduleExit();
13306 } catch (Exception e) {
13307 // Ignore exceptions.
13308 }
13309 }
13310 // todo: For now we assume the application is not buggy
13311 // or evil, and will quit as a result of our request.
13312 // Eventually we need to drive this off of the death
13313 // notification, and kill the process if it takes too long.
13314 cleanUpApplicationRecordLocked(app, false, i);
13315 i--;
13316 }
13317 }
13318
13319 // If we still have too many processes, now from the least
13320 // recently used process we start finishing activities.
Joe Onorato43a17652011-04-06 19:22:23 -070013321 if (false) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013322 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 " of " + curMaxProcs + " processes");
13324 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013325 i<mLruProcesses.size()
13326 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013327 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013328 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013329 // Quit the application only if we have a state saved for
13330 // all of its activities.
13331 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013332 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013333 int NUMA = app.activities.size();
13334 int j;
Joe Onorato43a17652011-04-06 19:22:23 -070013335 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013336 TAG, "Looking to quit " + app.processName);
13337 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013338 ActivityRecord r = app.activities.get(j);
Joe Onorato43a17652011-04-06 19:22:23 -070013339 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013340 TAG, " " + r.intent.getComponent().flattenToShortString()
13341 + ": frozen=" + r.haveState + ", visible=" + r.visible);
13342 canQuit = (r.haveState || !r.stateNotNeeded)
13343 && !r.visible && r.stopped;
13344 }
13345 if (canQuit) {
13346 // Finish all of the activities, and then the app itself.
13347 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013348 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013349 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013350 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013351 }
13352 r.resultTo = null;
13353 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080013354 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013355 + app.processName + " ("
13356 + (app.thread != null ? app.thread.asBinder() : null)
13357 + ")\n");
13358 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013359 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13360 app.processName, app.setAdj, "old background");
13361 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013362 } else {
13363 try {
13364 app.thread.scheduleExit();
13365 } catch (Exception e) {
13366 // Ignore exceptions.
13367 }
13368 }
13369 // todo: For now we assume the application is not buggy
13370 // or evil, and will quit as a result of our request.
13371 // Eventually we need to drive this off of the death
13372 // notification, and kill the process if it takes too long.
13373 cleanUpApplicationRecordLocked(app, false, i);
13374 i--;
13375 //dump();
13376 }
13377 }
13378
13379 }
13380
13381 int curMaxActivities = MAX_ACTIVITIES;
13382 if (mAlwaysFinishActivities) {
13383 curMaxActivities = 1;
13384 }
13385
13386 // Finally, if there are too many activities now running, try to
13387 // finish as many as we can to get back down to the limit.
13388 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013389 i<mMainStack.mLRUActivities.size()
13390 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013391 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013392 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013393 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013394
13395 // We can finish this one if we have its icicle saved and
13396 // it is not persistent.
13397 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013398 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013399 final int origSize = mMainStack.mLRUActivities.size();
13400 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013401
13402 // This will remove it from the LRU list, so keep
13403 // our index at the same value. Note that this check to
13404 // see if the size changes is just paranoia -- if
13405 // something unexpected happens, we don't want to end up
13406 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013407 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013408 i--;
13409 }
13410 }
13411 }
13412 }
13413 }
13414
13415 /** This method sends the specified signal to each of the persistent apps */
13416 public void signalPersistentProcesses(int sig) throws RemoteException {
13417 if (sig != Process.SIGNAL_USR1) {
13418 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13419 }
13420
13421 synchronized (this) {
13422 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13423 != PackageManager.PERMISSION_GRANTED) {
13424 throw new SecurityException("Requires permission "
13425 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13426 }
13427
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013428 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13429 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013430 if (r.thread != null && r.persistent) {
13431 Process.sendSignal(r.pid, sig);
13432 }
13433 }
13434 }
13435 }
13436
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013437 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013438 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013439
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013440 try {
13441 synchronized (this) {
13442 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13443 // its own permission.
13444 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13445 != PackageManager.PERMISSION_GRANTED) {
13446 throw new SecurityException("Requires permission "
13447 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013448 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013449
13450 if (start && fd == null) {
13451 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013452 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013453
13454 ProcessRecord proc = null;
13455 try {
13456 int pid = Integer.parseInt(process);
13457 synchronized (mPidsSelfLocked) {
13458 proc = mPidsSelfLocked.get(pid);
13459 }
13460 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013461 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013462
13463 if (proc == null) {
13464 HashMap<String, SparseArray<ProcessRecord>> all
13465 = mProcessNames.getMap();
13466 SparseArray<ProcessRecord> procs = all.get(process);
13467 if (procs != null && procs.size() > 0) {
13468 proc = procs.valueAt(0);
13469 }
13470 }
13471
13472 if (proc == null || proc.thread == null) {
13473 throw new IllegalArgumentException("Unknown process: " + process);
13474 }
13475
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013476 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13477 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013478 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13479 throw new SecurityException("Process not debuggable: " + proc);
13480 }
13481 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013482
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013483 proc.thread.profilerControl(start, path, fd);
13484 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013485 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013486 }
13487 } catch (RemoteException e) {
13488 throw new IllegalStateException("Process disappeared");
13489 } finally {
13490 if (fd != null) {
13491 try {
13492 fd.close();
13493 } catch (IOException e) {
13494 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013495 }
13496 }
13497 }
Andy McFadden824c5102010-07-09 16:26:57 -070013498
13499 public boolean dumpHeap(String process, boolean managed,
13500 String path, ParcelFileDescriptor fd) throws RemoteException {
13501
13502 try {
13503 synchronized (this) {
13504 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13505 // its own permission (same as profileControl).
13506 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13507 != PackageManager.PERMISSION_GRANTED) {
13508 throw new SecurityException("Requires permission "
13509 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13510 }
13511
13512 if (fd == null) {
13513 throw new IllegalArgumentException("null fd");
13514 }
13515
13516 ProcessRecord proc = null;
13517 try {
13518 int pid = Integer.parseInt(process);
13519 synchronized (mPidsSelfLocked) {
13520 proc = mPidsSelfLocked.get(pid);
13521 }
13522 } catch (NumberFormatException e) {
13523 }
13524
13525 if (proc == null) {
13526 HashMap<String, SparseArray<ProcessRecord>> all
13527 = mProcessNames.getMap();
13528 SparseArray<ProcessRecord> procs = all.get(process);
13529 if (procs != null && procs.size() > 0) {
13530 proc = procs.valueAt(0);
13531 }
13532 }
13533
13534 if (proc == null || proc.thread == null) {
13535 throw new IllegalArgumentException("Unknown process: " + process);
13536 }
13537
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013538 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13539 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013540 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13541 throw new SecurityException("Process not debuggable: " + proc);
13542 }
13543 }
13544
13545 proc.thread.dumpHeap(managed, path, fd);
13546 fd = null;
13547 return true;
13548 }
13549 } catch (RemoteException e) {
13550 throw new IllegalStateException("Process disappeared");
13551 } finally {
13552 if (fd != null) {
13553 try {
13554 fd.close();
13555 } catch (IOException e) {
13556 }
13557 }
13558 }
13559 }
13560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013561 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13562 public void monitor() {
13563 synchronized (this) { }
13564 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013565
13566 public void onCoreSettingsChange(Bundle settings) {
13567 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13568 ProcessRecord processRecord = mLruProcesses.get(i);
13569 try {
13570 if (processRecord.thread != null) {
13571 processRecord.thread.setCoreSettings(settings);
13572 }
13573 } catch (RemoteException re) {
13574 /* ignore */
13575 }
13576 }
13577 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013578
13579 // Multi-user methods
13580
13581 public boolean switchUser(int userid) {
13582 // TODO
13583 return true;
13584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013585}